class Forme::Form

  1. lib/forme/form.rb
Superclass: Object

The Form class is the main entry point to the library.

Using the form, input, tag, and inputs methods, one can easily build an abstract syntax tree of Tag and Input instances, which can be serialized to a string using to_s.

Attributes

hidden_tags [R]

The hidden tags to automatically add to the form.

input_defaults [R]

Set the default options for inputs by type. This should be a hash with input type keys and values that are hashes of input options.

opts [R]

A hash of options for the form.

serializer [R]

The serializer determines how Tag objects are transformed into strings. Must respond to call or be a registered symbol.

Public Class methods

form (obj=nil, attr={}, opts={}, &block)

Create a Form instance and yield it to the block, injecting the opening form tag before yielding and the closing form tag after yielding.

Argument Handling:

No args

Creates a Form object with no options and not associated to an obj, and with no attributes in the opening tag.

1 hash arg

Treated as opening form tag attributes, creating a Form object with no options.

1 non-hash arg

Treated as the Form's obj, with empty options and no attributes in the opening tag.

2 hash args

First hash is opening attributes, second hash is Form options.

1 non-hash arg, 1-2 hash args

First argument is Form's obj, second is opening attributes, third if provided is Form's options.

[show source]
   # File lib/forme/form.rb
49 def self.form(obj=nil, attr={}, opts={}, &block)
50   f = if obj.is_a?(Hash)
51     raise Error, "Can't provide 3 hash arguments to form" unless opts.empty?
52     opts = attr
53     attr = obj
54     new(opts)
55   else
56     new(obj, opts)
57   end
58 
59   ins = opts[:inputs]
60   button = opts[:button]
61   if ins || button
62     block = proc do |form|
63       form._inputs(ins, opts) if ins
64       yield form if block_given?
65       form.emit(form.button(button)) if button
66     end
67   end
68 
69   f.form(attr, &block)
70 end
new (obj=nil, opts={})

Use appropriate Form subclass for object based on the current class, if the object responds to forme_form_class.

[show source]
   # File lib/forme/form.rb
25 def self.new(obj=nil, opts={})
26   if obj && obj.respond_to?(:forme_form_class) && !opts[:_forme_form_class_set]
27     obj.forme_form_class(self).new(obj, opts.merge(:_forme_form_class_set=>true))
28   else
29     super
30   end
31 end
new (obj=nil, opts={})

Creates a Form object. Arguments:

obj

Sets the obj for the form. If a hash, is merged with the opts argument to set the opts.

opts

A hash of options for the form

[show source]
    # File lib/forme/form.rb
 76 def initialize(obj=nil, opts={})
 77   @opts = opts.merge(obj.is_a?(Hash) ? obj : {:obj=>obj})
 78   @opts[:namespace] = Array(@opts[:namespace])
 79 
 80   if obj && obj.respond_to?(:forme_config)
 81     obj.forme_config(self)
 82   end
 83 
 84   config = CONFIGURATIONS[@opts[:config]||Forme.default_config]
 85   copy_inputs_wrapper_from_wrapper(@opts)
 86 
 87   TRANSFORMER_TYPES.each do |t|
 88     case @opts[t]
 89     when Symbol
 90       @opts[t] = Forme.transformer(t, @opts[t], @opts)
 91     when nil
 92       unless @opts.has_key?(t)
 93         @opts[t] = Forme.transformer(t, config, @opts)
 94       end
 95     end
 96   end
 97 
 98   @serializer = @opts[:serializer]
 99   @input_defaults = @opts[:input_defaults] || {}
100   @hidden_tags = @opts[:hidden_tags]
101   @nesting = []
102 end

Public Instance methods

<< (tag)

Add the Input/Tag instance given to the currently open tag.

[show source]
    # File lib/forme/form.rb
283 def <<(tag)
284   if n = @nesting.last
285     n << tag
286   end
287 end
_input (*a)

Create a new Input associated with the receiver with the given arguments, doing no other processing.

[show source]
    # File lib/forme/form.rb
163 def _input(*a)
164   Input.new(self, *a)
165 end
_tag (*a, &block)

Create a Tag associated to the receiver with the given arguments and block, doing no other processing.

[show source]
    # File lib/forme/form.rb
240 def _tag(*a, &block)
241   Tag.new(self, *a, &block)
242 end
button (opts={})

Creates a :submit Input with the given opts, adding it to the list of children for the currently open tag.

[show source]
    # File lib/forme/form.rb
275 def button(opts={})
276   opts = {:value=>opts} if opts.is_a?(String)
277   input = _input(:submit, opts)
278   self << input
279   input
280 end
close ()

Returns a string representing the closing of the form tag, for serializers that support closing tags.

[show source]
    # File lib/forme/form.rb
234 def close
235   serializer.serialize_close(_tag(:form)) if serializer.respond_to?(:serialize_close)
236 end
each_obj (objs, namespace=nil)

Calls the block for each object in objs, using with_obj with the given namespace and an index namespace (starting at 0).

[show source]
    # File lib/forme/form.rb
291 def each_obj(objs, namespace=nil)
292   objs.each_with_index do |obj, i|
293     with_obj(obj, Array(namespace) + [i]) do
294       yield obj, i
295     end
296   end
297 end
emit (tag)

Empty method designed to ease integration with other libraries where Forme is used in template code and some output implicitly created by Forme needs to be injected into the template output.

[show source]
    # File lib/forme/form.rb
115 def emit(tag)
116 end
form (attr={}, &block)

Create a form tag with the given attributes.

[show source]
    # File lib/forme/form.rb
105 def form(attr={}, &block)
106   if obj && !attr[:method] && !attr['method'] && obj.respond_to?(:forme_default_request_method)
107     attr = attr.merge('method'=>obj.forme_default_request_method)
108   end
109   tag(:form, attr, method(:hidden_form_tags), &block)
110 end
input (field, opts={})

Creates an Input with the given field and opts associated with the receiver, and add it to the list of children to the currently open tag.

If the form is associated with an obj, or the :obj key exists in the opts argument, treats the field as a call to the obj. If obj responds to forme_input, that method is called with the field and a copy of opts. Otherwise, the field is used as a method call on the obj and a text input is created with the result.

If no obj is associated with the receiver, field represents an input type (e.g. :text, :textarea, :select), and an input is created directly with the field and opts.

[show source]
    # File lib/forme/form.rb
131 def input(field, opts={})
132   if opts.has_key?(:obj)
133     opts = opts.dup
134     obj = opts.delete(:obj)
135   else
136     obj = self.obj
137   end
138   input = if obj
139     if obj.respond_to?(:forme_input)
140       obj.forme_input(self, field, opts.dup)
141     else
142       opts = opts.dup
143       opts[:key] = field unless opts.has_key?(:key)
144       type = opts.delete(:type) || :text
145       unless opts.has_key?(:value) || type == :file
146         opts[:value] = if obj.is_a?(Hash)
147           obj[field]
148         else
149           obj.send(field)
150         end
151       end
152       _input(type, opts)
153     end
154   else
155     _input(field, opts)
156   end
157   self << input
158   input
159 end
inputs (inputs=[], opts={}, &block)

Creates a tag using the inputs_wrapper (a fieldset by default), calls input on each element of inputs, and yields if given a block. You can use array arguments if you want inputs to be created with specific options:

f.inputs([:field1, :field2])
f.inputs([[:field1, {:name=>'foo'}], :field2])

The given opts are passed to the inputs_wrapper, and the default inputs_wrapper supports a :legend option that is used to set the legend for the fieldset.

opts can also include transformer options itself (e.g. :wrapper), which override the form's current transformer options for the duration of the block. The exception is the :inputs_wrapper transformer option, which affects the wrapper to use for this inputs call. You can use the :nested_inputs_wrapper option to set the default :inputs_wrapper option for the duration of the block.

This can also be called with a single hash argument to just use an options hash:

f.inputs(:legend=>'Foo') do
  # ...
end

or even without any arguments:

f.inputs do
  # ...
end
[show source]
    # File lib/forme/form.rb
196 def inputs(inputs=[], opts={}, &block)
197   _inputs(inputs, opts, &block)
198 end
namespaces ()

The namespaces if any for the receiver's inputs. This can be used to automatically setup namespaced class and id attributes.

[show source]
    # File lib/forme/form.rb
253 def namespaces
254   @opts[:namespace]
255 end
obj ()

The object associated with this form, if any. If the Form has an associated obj, then calls to input are assumed to be accessing fields of the object instead to directly representing input types.

[show source]
    # File lib/forme/form.rb
247 def obj
248   @opts[:obj]
249 end
open (attr)

Returns a string representing the opening of the form tag for serializers that support opening tags.

[show source]
    # File lib/forme/form.rb
228 def open(attr)
229   serializer.serialize_open(_tag(:form, attr)) if serializer.respond_to?(:serialize_open)
230 end
raw (s)

Return a new string that will not be html escaped by the default serializer.

[show source]
    # File lib/forme/form.rb
300 def raw(s)
301   Forme.raw(s)
302 end
raw_output (s)

Marks the string as containing already escaped output. Returns string given by default, but subclasses for specific web frameworks can handle automatic html escaping by overriding this.

[show source]
    # File lib/forme/form.rb
307 def raw_output(s)
308   s
309 end
tag (*a, &block)

Creates a Tag associated to the receiver with the given arguments. Add the tag to the the list of children for the currently open tag. If a block is given, make this tag the currently open tag while inside the block.

[show source]
    # File lib/forme/form.rb
261 def tag(*a, &block)
262   tag = _tag(*a)
263   self << tag
264   nest(tag, &block) if block
265   tag
266 end
with_obj (obj, namespace=nil)

Temporarily override the given object and namespace for the form. Any given namespaces are appended to the form's current namespace.

[show source]
    # File lib/forme/form.rb
313 def with_obj(obj, namespace=nil)
314   with_opts(:obj=>obj, :namespace=>@opts[:namespace]+Array(namespace)) do
315     yield obj
316   end
317 end
with_opts (opts)

Temporarily override the opts for the form for the duration of the block. This merges the given opts with the form's current opts, restoring the previous opts before returning.

[show source]
    # File lib/forme/form.rb
322 def with_opts(opts)
323   orig_opts = @opts
324   @opts = orig_opts.merge(opts)
325   copy_inputs_wrapper_from_wrapper(opts, @opts)
326   yield
327 ensure
328   @opts = orig_opts if orig_opts
329 end