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).
Methods
Public Class
Public Instance
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 |
to_s | [R] |
The contents of the form as a string. This should not be mutated by external code. |
Public Class methods
Create a Form
instance and yield it to the block. Returns an HTML string for the form tag.
Argument Handling:
No args |
Creates a |
1 hash arg |
Treated as opening form tag attributes, creating a |
1 non-hash arg |
Treated as the |
2 hash args |
First hash is opening attributes, second hash is |
1 non-hash arg, 1-2 hash args |
First argument is |
# 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
# 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
Use appropriate Form
subclass for object based on the current class, if the object responds to forme_form_class
.
# 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
Creates a Form
object. Arguments:
obj |
Sets the obj for the form. If a hash, is merged with the |
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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