module Iowa
module FormElements
class Form < Tag
def defaultBindings
@bindings["action"] = LiteralAssociation.new(@name)
end
def handleRequest(context)
if(context.actionID == context.elementID)
context.setAction(@bindings["action"])
context[:formActive] = true
context.element_attributes = @attributes
end
super(context)
context[:formActive] = false
end
def handleResponse(context)
context.response << openTag("method", "post",
"action", context.actionURL)
super(context)
context.response << closeTag
end
end
class Input < Tag
def initialize(name, bindings, attributes)
type = attributes["type"]
case type
when "submit"
extend Submit
when "image"
extend Image
when "checkbox"
extend Checkbox
when "radio"
extend Radiobox
else
extend Text
end
super(name, bindings, attributes)
end
end
module Submit
def defaultBindings
@bindings["action"] = LiteralAssociation.new(@name)
@attributes["value"] ||= @name
end
def handleRequest(context)
if context.request.params.has_key?(context.elementID)
context.setAction(@bindings["action"])
context.element_attributes = @attributes
end
end
def handleResponse(context)
value = context.getBinding(@bindings["value"])
attrs = Hash["type", "submit", "name", context.elementID]
attrs["value"] = value if value
context.response << openTag(attrs)
end
end
module Image
def defaultBindings
@bindings["action"] = LiteralAssociation.new(@name)
end
def handleRequest(context)
if context.request.params.has_key?(context.elementID)
context.setAction(@bindings["action"])
context.element_attributes = @attributes
end
end
def handleResponse(context)
value = context.getBinding(@bindings["value"])
attrs = Hash["type", "image", "name", context.elementID]
context.response << openTag(attrs)
end
end
module Text
def defaultBindings
@bindings["value"] = PathAssociation.new(@name)
end
def handleRequest(context)
val = context.request.params[context.elementID]
if val
context.setBinding(@bindings["value"], val)
end
end
def handleResponse(context)
value = context.getBinding(@bindings["value"])
type = @attributes["type"]
context.response << openTag("type", type,
"name", context.elementID,
"value", value)
end
end
module Checkbox
def defaultBindings
@bindings["value"] = PathAssociation.new(@name)
end
def handleRequest(context)
if context[:formActive]
val = context.request.params[context.elementID]? true : false
context.setBinding(@bindings["value"], val)
end
end
def handleResponse(context)
val = context.getBinding(@bindings["value"])
attrs = {"type", "checkbox",
"name", context.elementID,
"value", "checked"}
attrs["checked"] = nil if val
context.response << openTag(attrs)
end
end
module Radiobox
def defaultBindings
@bindings["value"] = PathAssociation.new(@name)
end
def handleRequest(context)
if context[:formActive]
val = context.request.params[context.elementID]
context.setBinding(@bindings["value"], val) if val
end
end
def handleResponse(context)
val = context.getBinding(@bindings["value"])
attrs = {'type', 'radio'}
if @attributes['name'] !~ /^\d+(\.\d+)*$/
if context.radio_box_id.has_key? @name
attrs['name'] = context.radio_box_id[@name]
else
context.radio_box_id[@name] = context.elementID
attrs['name'] = context.elementID
end
else
attrs['name'] = @name
end
if @attributes['value'].to_s == val.to_s
attrs['checked'] = nil
@attributes.delete('checked')
elsif val
@attributes.delete('checked')
end
context.response << openTag(attrs)
end
end
class Textarea < Tag
def defaultBindings
@bindings["value"] = PathAssociation.new(@name)
end
def handleRequest(context)
val = context.request.params[context.elementID]
if val
context.setBinding(@bindings["value"], val)
end
end
def handleResponse(context)
value = context.getBinding(@bindings["value"])
context.response << openTag("name", context.elementID)
context.response << value
context.response << closeTag
end
end
class Select < Repeat
# If the multiple option is used in the select statement, then multiple
# values can be returned. If they are, then the 'item' variable will
# be set to an array, with each selection as an element in the array.
def handleRequest(context)
index = context.request.params[context.elementID]
handleRequestOrResponse(:handleRequest, context)
if index
list = context.getBinding(@bindings["list"])
if index.index(0)
c = []
index.split(0.chr).each do |i|
c.push list[i.to_i]
end
context.setBinding(@bindings["item"], c)
else
context.setBinding(@bindings["item"], list[index.to_i])
end
end
end
def handleResponse(context)
context.response << openTag("name", context.elementID)
handleRequestOrResponse(:handleResponse, context)
context.response << closeTag
end
# If the item is an array, then there are multiple entries within the
# select box that are selected.
def handleRequestOrResponse(method, context)
list = context.getBinding(@bindings["list"])
item = context.getBinding(@bindings["item"])
if item.class.to_s == 'Array'
h = {}
item.each do |i|
h[list.index(i)] = true
end
context[:selectItem] = h
else
context[:selectItem] = list.index(item)
end
context[:selectIndex] = 0
super(method, context)
context.setBindingNow(@bindings["item"], item)
end
end
class Option < Tag
def defaultBindings
@bindings["item"] = PathAssociation.new(@name)
end
def handleResponse(context)
attrs = {"value", context[:selectIndex]}
if context[:selectItem].class.to_s == 'Hash'
if context[:selectItem].has_key? context[:selectIndex]
attrs["selected"] = nil
end
elsif context[:selectIndex] == context[:selectItem]
attrs["selected"] = nil
end
context.response << openTag(attrs)
context.response << context.getBinding(@bindings["item"])
context[:selectIndex] += 1
end
end
end
end