class Forme::Form

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

Using the form, input, tag, and inputs methods, one can return HTML form tag string (or fragments of an HTML form tag).

Attributes

form_tag_attributes[R]

The attributes used for the form tag for this 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.

to_s[R]

The contents of the form as a string. This should not be mutated by external code.

Public Class Methods

form(obj=nil, attr={}, opts={}, &block) click to toggle source

Create a Form instance and yield it to the block. Returns an HTML string for the form tag.

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.

   # File lib/forme/form.rb
76 def self.form(obj=nil, attr={}, opts={}, &block)
77   f, attr, block = form_args(obj, attr, opts, &block)
78   f.form(attr, &block)
79 end
form_args(obj, attr, opts) { |form| ... } click to toggle source

Parse the args given to form and return Form instance, form tag attributes, and block for form.

   # File lib/forme/form.rb
38 def self.form_args(obj, attr, opts, &block)
39   f = if obj.is_a?(Hash)
40     raise Error, "Can't provide 3 hash arguments to form" unless opts.empty?
41     opts = attr
42     attr = obj
43     new(opts)
44   else
45     new(obj, opts)
46   end
47 
48   ins = opts[:inputs]
49   button = opts[:button]
50   if ins || button
51     block = proc do |form|
52       form.inputs(ins, opts) if ins
53       yield form if block_given?
54       form.button(button) if button
55     end
56   end
57 
58   [f, attr, block]
59 end
new(obj=nil, opts={}) click to toggle source

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

Calls superclass method
   # File lib/forme/form.rb
28 def self.new(obj=nil, opts={})
29   if obj && obj.respond_to?(:forme_form_class) && !opts[:_forme_form_class_set]
30     obj.forme_form_class(self).new(obj, opts.merge(:_forme_form_class_set=>true))
31   else
32     super
33   end
34 end
new(obj=nil, opts={}) click to toggle source

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

    # File lib/forme/form.rb
 85 def initialize(obj=nil, opts={})
 86   @opts = opts.merge(obj.is_a?(Hash) ? obj : {:obj=>obj})
 87   @opts[:namespace] = Array(@opts[:namespace])
 88 
 89   if obj && obj.respond_to?(:forme_config)
 90     obj.forme_config(self)
 91   end
 92 
 93   config = CONFIGURATIONS[@opts[:config]||Forme.default_config]
 94   copy_inputs_wrapper_from_wrapper(@opts)
 95 
 96   TRANSFORMER_TYPES.each do |t|
 97     case @opts[t]
 98     when Symbol
 99       @opts[t] = Forme.transformer(t, @opts[t], @opts)
100     when nil
101       unless @opts.has_key?(t)
102         @opts[t] = Forme.transformer(t, config, @opts)
103       end
104     end
105   end
106 
107   @serializer = @opts[:serializer]
108   @input_defaults = @opts[:input_defaults] || {}
109   @to_s = String.new
110 end

Public Instance Methods

<<(tag) click to toggle source

Add the Input/Tag instance to the HTML buffer.

    # File lib/forme/form.rb
300 def <<(tag)
301   @to_s << tag.to_s
302 end
_input(*a) click to toggle source

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

    # File lib/forme/form.rb
181 def _input(*a)
182   Input.new(self, *a)
183 end
_tag(*a, &block) click to toggle source

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

    # File lib/forme/form.rb
256 def _tag(*a, &block)
257   Tag.new(self, *a, &block)
258 end
button(opts={}) click to toggle source

Creates a :submit Input with the given opts. Returns the generated HTML for the input.

    # File lib/forme/form.rb
294 def button(opts={})
295   opts = {:value=>opts} if opts.is_a?(String)
296   content_added{self << _input(:submit, opts)}
297 end
close() click to toggle source

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

    # File lib/forme/form.rb
250 def close
251   serializer.serialize_close(_tag(:form)) if serializer.respond_to?(:serialize_close)
252 end
each_obj(objs, namespace=nil) { |obj, i| ... } click to toggle source

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

    # File lib/forme/form.rb
306 def each_obj(objs, namespace=nil)
307   objs.each_with_index do |obj, i|
308     with_obj(obj, Array(namespace) + [i]) do
309       yield obj, i
310     end
311   end
312 end
form(attr={}) { |self| ... } click to toggle source

Create a form tag with the given attributes. Returns an HTML string for the generated form tag.

    # File lib/forme/form.rb
114 def form(attr={})
115   if obj && !attr[:method] && !attr['method'] && obj.respond_to?(:forme_default_request_method)
116     attr = Hash[attr]
117     attr['method'] = obj.forme_default_request_method
118   end
119   @form_tag_attributes = attr
120 
121   tag(:form, attr) do
122     before_form_yield
123     yield self if block_given?
124     after_form_yield
125   end
126 end
input(field, opts={}) click to toggle source

Creates an Input with the given field and opts associated with the receiver. Returns the HTML generated by the given input.

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.

    # File lib/forme/form.rb
146 def input(field, opts={})
147   content_added do
148     if opts.has_key?(:obj)
149       opts = opts.dup
150       obj = opts.delete(:obj)
151     else
152       obj = self.obj
153     end
154 
155     input = if obj
156       if obj.respond_to?(:forme_input)
157         obj.forme_input(self, field, opts.dup)
158       else
159         opts = opts.dup
160         opts[:key] = field unless opts.has_key?(:key)
161         type = opts.delete(:type) || :text
162         unless opts.has_key?(:value) || type == :file
163           opts[:value] = if obj.is_a?(Hash)
164             obj[field]
165           else
166             obj.send(field)
167           end
168         end
169         _input(type, opts)
170       end
171     else
172       _input(field, opts)
173     end
174 
175     self << input
176   end
177 end
inputs(inputs=[], opts={}) { || ... } click to toggle source

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.

Returns the HTML generated by the inputs added to the form.

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
    # File lib/forme/form.rb
216 def inputs(inputs=[], opts={})
217   content_added do
218     if inputs.is_a?(Hash)
219       opts = inputs.merge(opts)
220       inputs = []
221     end
222 
223     form_opts = {}
224     form_opts[:inputs_wrapper] = opts[:nested_inputs_wrapper] if opts[:nested_inputs_wrapper]
225     TRANSFORMER_TYPES.each do |t|
226       if opts.has_key?(t) && t != :inputs_wrapper
227         form_opts[t] = opts[t]
228       end
229     end
230 
231     Forme.transform(:inputs_wrapper, opts, @opts, self, opts) do
232       with_opts(form_opts) do
233         inputs.each do |i|
234           input(*i)
235         end
236         yield if block_given?
237       end
238     end
239   end
240 end
namespaces() click to toggle source

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

    # File lib/forme/form.rb
269 def namespaces
270   @opts[:namespace]
271 end
obj() click to toggle source

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.

    # File lib/forme/form.rb
263 def obj
264   @opts[:obj]
265 end
open(attr) click to toggle source

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

    # File lib/forme/form.rb
244 def open(attr)
245   serializer.serialize_open(_tag(:form, attr)) if serializer.respond_to?(:serialize_open)
246 end
post?() click to toggle source

Whether the method for this form is POST. Only callable after calling form.

    # File lib/forme/form.rb
130 def post?
131   (form_tag_attributes[:method] || form_tag_attributes['method']).to_s.upcase == 'POST'
132 end
raw(s) click to toggle source

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

    # File lib/forme/form.rb
315 def raw(s)
316   Forme.raw(s)
317 end
tag(*a) { |self| ... } click to toggle source

Creates a Tag associated to the receiver with the given arguments. If a block is given, yield to the block inside the generated tag. Returns the HTML added to the form by the addition of this tag.

    # File lib/forme/form.rb
276 def tag(*a, &block)
277   content_added do
278     tag = _tag(*a)
279     if block
280       self << serialize_open(tag)
281       if children = tag.children
282         children.each{|child| self << child}
283       end
284       yield self
285       self << serialize_close(tag)
286     else
287       self << tag
288     end
289   end
290 end
with_obj(obj, namespace=nil) { |obj| ... } click to toggle source

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

    # File lib/forme/form.rb
321 def with_obj(obj, namespace=nil)
322   with_opts(:obj=>obj, :namespace=>@opts[:namespace]+Array(namespace)) do
323     yield obj
324   end
325 end
with_opts(opts) { || ... } click to toggle source

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.

    # File lib/forme/form.rb
330 def with_opts(opts)
331   orig_opts = @opts
332   @opts = orig_opts.merge(opts)
333   copy_inputs_wrapper_from_wrapper(opts, @opts)
334   yield
335 ensure
336   # :nocov:
337   @opts = orig_opts if orig_opts
338   # :nocov:
339 end

Private Instance Methods

after_form_yield() click to toggle source

Call after hooks if defined.

    # File lib/forme/form.rb
379 def after_form_yield
380   # after hook is for external use
381   opts[:after].call(self) if opts[:after]
382 
383   # _after hook is only for internal use
384   opts[:_after].call(self) if opts[:_after]
385 end
before_form_yield() click to toggle source

Call before hooks if defined.

    # File lib/forme/form.rb
369 def before_form_yield
370   # _before_post and _before hooks are only for internal use
371   opts[:_before_post].call(self) if opts[:_before_post] && post?
372   opts[:_before].call(self) if opts[:_before]
373 
374   # before hook is for external use
375   opts[:before].call(self) if opts[:before]
376 end
content_added() { || ... } click to toggle source

Return the HTML content added by the block.

    # File lib/forme/form.rb
352 def content_added
353   offset = @to_s.length
354   yield
355   @to_s[offset, @to_s.length]
356 end
copy_inputs_wrapper_from_wrapper(input_opts, output_opts=input_opts) click to toggle source

Copy the :wrapper option to :inputs_wrapper in output_opts if only :wrapper is present in input_opts and the :wrapper option value is a shared wrapper.

    # File lib/forme/form.rb
345 def copy_inputs_wrapper_from_wrapper(input_opts, output_opts=input_opts)
346   if input_opts[:wrapper] && !input_opts[:inputs_wrapper] && SHARED_WRAPPERS.include?(input_opts[:wrapper])
347     output_opts[:inputs_wrapper] = output_opts[:wrapper]
348   end
349 end
serialize_close(tag) click to toggle source

Return a serialized closing tag for the given tag.

    # File lib/forme/form.rb
364 def serialize_close(tag)
365   serializer.serialize_close(tag) if serializer.respond_to?(:serialize_close)
366 end
serialize_open(tag) click to toggle source

Return a serialized opening tag for the given tag.

    # File lib/forme/form.rb
359 def serialize_open(tag)
360   serializer.serialize_open(tag) if serializer.respond_to?(:serialize_open)
361 end