Class: Aurita::GUI::Form

Inherits:
Element show all
Defined in:
lib/aurita-gui/form.rb,
lib/aurita-gui/form/hidden_field.rb

Overview

Usage examples:

form = Form.new(:method   => :put  # default: :post
                :action   => '/where/to/send/form/'
                :onsubmit => "alert('submitting');") { 
  [ 
    Input_Field.new(:name => :description, :label => 'Description'), 
    Select_Field.new(:name => :category, :label => 'Select category')
  ]
}
textarea = GUI::Textarea.new(:name => :comment, :label => 'Comment')
form.add(textarea)

In case you want to override the form action (default: /aurita/dispatch), use :action_url:

Form.new(:action_url => '/where/to/send/form')

or

Form.action_url = '/where/to/send/form'

Render modes

There are several ways to influence the rendering of a field. Available modes are:

* editable: Default mode, opposite of readonly mode. 
* disabled: Set the disabled="disabled" attribute. Element will 
            be rendered as input field, but can't be modified 
            by the user. 
* readonly: Unlike in disabled mode, element will not be rendered 
            as input field, but as a <div> containing the field's value. 
* required: Always render this field. If it is not included in the 
            form's field configuration, render it as hidden field. 
* hidden:   Render as hidden field.

Examples

form = Form.new(:name   => :the_form, 
                :id     => :the_form_id, 
                :action => :where_to_send)

You can either set all attributes in the constructor call …

text = Input_Field.new(:name => :description, 
                       :class => :the_css_class, 
                       :label => 'Enter description', 
                       :onfocus => "alert('input focussed');", 
                       :value => 'some text')

Or set them afterwards:

text.onblur = "alert('i lost focus :(');"

Default mode:

puts text.to_s

Disabled mode:

text.disable! 
puts text.to_s

Re-enable:

text.enable! 
puts text.to_s

Readonly:

text.readonly! 
puts text.to_s

Back to editable:

text.editable! 
puts text.to_s

Render to hidden field:

puts text.to_hidden_field.to_s

Set to hidden (will only influence handling when rendered by a form):

text.hidden = true

Add it to the form:

form.add(text)

Modifying form elements

Access it again, by name:

assert_equal(form[:description], text)

Or by using its index:

assert_equal(form[0], text)

This is useful!

form[:description].value = 'change value'

checkbox = Checkbox_Field.new(:name => :enable_me, 
                              :value => :foo, 
                              :label => 'Check me', 
                              :options => [ :foo, :bar ] )
form.add(checkbox)

Modifying a field element after adding it to the form also works, as the form instance only references its form elements:

checkbox.required = true

The all form instance this checkbox has been added to now recognize it as a required field.

form.fields = [ :description, :enable_me ]
form.delete_field(:enable_me)

And this is something i personally really like:

form[:description].required = true

Now, checkbox is not included in the form’s field configuration, but as it is a required field, it will be rendered as hidden field.

puts form.to_s

Instance Attribute Summary collapse

Attributes inherited from Element

#attrib, #parent, #tag, #type

Instance Method Summary collapse

Methods inherited from Element

#+, #clear_floating, #dom_id, #dom_id=, #empty?, #id, #id=, #length, #method_missing, #to_ary

Constructor Details

#initialize(params, &block) ⇒ Form

Returns a new instance of Form.



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/aurita-gui/form.rb', line 182

def initialize(params, &block)
  @action       = params[:action]
  @method       = params[:method]
  @fields       = params[:fields]
  @values       = params[:values]
  @method     ||= :post
  @fields     ||= []
  @elements     = []
  @element_map  = {}
  @values     ||= {}
  @title        = false
  @custom_fields = false
  if block_given? then
    yield.each { |e| add(e) }
  end
  params.delete(:fields)
  params.delete(:values)
  params[:tag]     = 'form'
  params[:content] = content()
  super(params)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Aurita::GUI::Element

Instance Attribute Details

#actionObject

Returns the value of attribute action.



180
181
182
# File 'lib/aurita-gui/form.rb', line 180

def action
  @action
end

#element_mapObject

Returns the value of attribute element_map.



180
181
182
# File 'lib/aurita-gui/form.rb', line 180

def element_map
  @element_map
end

#elementsObject

Returns the value of attribute elements.



180
181
182
# File 'lib/aurita-gui/form.rb', line 180

def elements
  @elements
end

#fieldsObject

Return array of field names currently available for rendering.



294
295
296
# File 'lib/aurita-gui/form.rb', line 294

def fields
  @fields
end

#methodObject

Returns the value of attribute method.



180
181
182
# File 'lib/aurita-gui/form.rb', line 180

def method
  @method
end

#targetObject

Returns the value of attribute target.



180
181
182
# File 'lib/aurita-gui/form.rb', line 180

def target
  @target
end

Instance Method Details

#[](index) ⇒ Object

Access form element by index or name (by index if parameter is of type Numeric, by name otherwhise)



213
214
215
216
# File 'lib/aurita-gui/form.rb', line 213

def [](index)
  return @elements[index] if index.kind_of? Numeric
  return @element_map[index.to_s] 
end

#[]=(index, form_field) ⇒ Object

Assign / overwrite field element with index form_index.



219
220
221
222
# File 'lib/aurita-gui/form.rb', line 219

def []=(index, form_field)
  @elements[index] = form_field
  @content = false # Invalidate
end

#add(form_field_element) ⇒ Object

Add form field element to this form.



243
244
245
246
247
248
249
250
# File 'lib/aurita-gui/form.rb', line 243

def add(form_field_element)
  if !form_field_element.dom_id then
    form_field_element.dom_id = form_field_element.name.to_s.gsub('.','_')
  end
  @element_map[form_field_element.name.to_s] = form_field_element
  @elements << form_field_element
  @content = false # Invalidate
end

#add_hidden(params) ⇒ Object Also known as: add_hidden_fields



36
37
38
39
40
# File 'lib/aurita-gui/form/hidden_field.rb', line 36

def add_hidden(params)
  params.each_pair { |k,v| 
    add(Hidden_Field.new(:name => k, :value => v))
  }
end

#attributesObject

Returns field element map. An element map maps field names to elements of this form.



207
208
209
# File 'lib/aurita-gui/form.rb', line 207

def attributes
  @element_map
end

#contentObject

Return underlying HTML element instance (HTML.ul), without wrapping HTML.form element.



322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
# File 'lib/aurita-gui/form.rb', line 322

def content
  # TODO: Provide Fieldset instances
  @content = []
  if @title then
    @content << HTML.h1(:class => :form_title) { @title }
  end
  fields().each { |field|
    element = @element_map[field.to_s]
    if element then
       element = element.to_hidden_field() if element.hidden?
      if element.kind_of? Aurita::GUI::Hidden_Field then
        @content << element
      else
        @content << Form_Field_Wrapper.new(element)
      end
    end
  }
  # Render required field as hidden field if not 
  # included in form field config: 
  @elements.each { |element| 
    if !fields.include?(element.name.to_s) && element.required? then
      @content << element.to_hidden_field()
    end
  }
  @content = HTML.ul(:class => :form_fields) { @content }
  return @content
end

#delete(field_name) ⇒ Object

Delete form field with name field_name from this form.



226
227
228
# File 'lib/aurita-gui/form.rb', line 226

def delete(field_name)
  @element_map.delete(field_name.to_s)
end

#delete_field(field_name) ⇒ Object

Remove field with name=field_name from list of elements to be rendered in the form. The element will not be deleted from the form, so it can be enabled again using

form.fields << :field_name


312
313
314
315
316
317
318
# File 'lib/aurita-gui/form.rb', line 312

def delete_field(field_name)
  if field_name.kind_of? Numeric then
    @fields.delete_at(field_name)
  else
    @fields.delete(field_name.to_s)
  end
end

#each(&block) ⇒ Object

Iterate over form field elements. This would add a CSS class to all elements without a value:

form.each { |element| 
  element.class = 'missing' unless element.value
}


238
239
240
# File 'lib/aurita-gui/form.rb', line 238

def each(&block)
  @elements.each(&block)
end

#editable!Object

Set all form elements to editable mode.



369
370
371
372
373
# File 'lib/aurita-gui/form.rb', line 369

def editable! 
  elements.each { |e|
    e.editable! 
  }
end

#elementObject

Render this form to an HTML.form instance. Wraps result of #content.



352
353
354
# File 'lib/aurita-gui/form.rb', line 352

def element
  HTML.form(@attrib) { content() }
end

#readonly!Object

Set all form elements to readonly mode.



286
287
288
289
290
# File 'lib/aurita-gui/form.rb', line 286

def readonly!
  @elements.each { |e|
    e.readonly!
  }
end

#stringObject Also known as: to_s

Render this form to a string



357
358
359
# File 'lib/aurita-gui/form.rb', line 357

def string
  element().to_s
end

#values=(value_hash = {}) ⇒ Object Also known as: set_values

Set field values for this form. Expects hash mapping field names to values. Example:

form.values = { :name => 'Foo', :description => 'Bar', :date => '20081012' }


276
277
278
279
280
281
282
# File 'lib/aurita-gui/form.rb', line 276

def values=(value_hash={})
  @values = value_hash
  @values.each_pair { |field_name, value|
    element = @element_map[field_name.to_s]
    element.value = value if element
  }
end