Class: Forme::Form
- Inherits:
-
Object
- Object
- Forme::Form
- Defined in:
- lib/forme.rb
Overview
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
.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#error_handler ⇒ Object
readonly
The
error_handler
determines how to to mark tags as containing errors. -
#formatter ⇒ Object
readonly
The
formatter
determines how the Inputs created are transformed intoTag
objects. -
#hidden_tags ⇒ Object
readonly
The hidden tags to automatically add to the form.
-
#input_defaults ⇒ Object
readonly
Set the default options for inputs by type.
-
#inputs_wrapper ⇒ Object
readonly
The
inputs_wrapper
determines how calls toinputs
are wrapped. -
#labeler ⇒ Object
readonly
The
labeler
determines how to label tags. -
#obj ⇒ Object
readonly
The object related to the receiver, if any.
-
#opts ⇒ Object
readonly
A hash of options for the receiver.
-
#serializer ⇒ Object
readonly
The
serializer
determines howTag
objects are transformed into strings. -
#wrapper ⇒ Object
readonly
The
wrapper
determines how (potentially labeled) tags are wrapped.
Class Method Summary collapse
-
.form(obj = nil, attr = {}, opts = {}, &block) ⇒ Object
Create a
Form
instance and yield it to the block, injecting the opening form tag before yielding and the closing form tag after yielding.
Instance Method Summary collapse
-
#<<(tag) ⇒ Object
Add the
Input
/Tag
instance given to the currently open tag. -
#_input(*a) ⇒ Object
Create a new
Input
associated with the receiver with the given arguments, doing no other processing. -
#_inputs(inputs = [], opts = {}) ⇒ Object
Internals of #inputs, should be used internally by the library, where #inputs is designed for external use.
-
#_tag(*a, &block) ⇒ Object
Create a
Tag
associated to the receiver with the given arguments and block, doing no other processing. -
#button(opts = {}) ⇒ Object
Creates a :submit
Input
with the given opts, adding it to the list of children for the currently open tag. -
#close ⇒ Object
Returns a string representing the closing of the form tag, for serializers that support closing tags.
-
#emit(tag) ⇒ Object
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.
-
#form(attr = {}, &block) ⇒ Object
Create a form tag with the given attributes.
-
#format(input) ⇒ Object
Formats the
input
using theformatter
. -
#initialize(obj = nil, opts = {}) ⇒ Form
constructor
Creates a
Form
object. -
#input(field, opts = {}) ⇒ Object
Creates an
Input
with the givenfield
andopts
associated with the receiver, and add it to the list of children to the currently open tag. -
#inputs(*a, &block) ⇒ Object
Creates a tag using the
inputs_wrapper
(a fieldset by default), calls input on each element ofinputs
, and yields to if given a block. -
#open(attr) ⇒ Object
Returns a string representing the opening of the form tag for serializers that support opening tags.
-
#serialize(tag) ⇒ Object
Serializes the
tag
using theserializer
. -
#tag(*a, &block) ⇒ Object
Creates a
Tag
associated to the receiver with the given arguments. - #tag_(*a, &block) ⇒ Object
-
#transform(type, trans_name, *args, &block) ⇒ Object
If there is a related transformer, call it with the given
args
andblock
. -
#transformer(type, trans) ⇒ Object
Get the related transformer for the given transformer type.
Constructor Details
#initialize(obj = nil, opts = {}) ⇒ Form
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, see
opts
attribute for details on available options.
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/forme.rb', line 238 def initialize(obj=nil, opts={}) if obj.is_a?(Hash) @opts = obj.merge(opts) @obj = @opts.delete(:obj) else @obj = obj @opts = opts end if @obj && @obj.respond_to?(:forme_config) @obj.forme_config(self) end config = CONFIGURATIONS[@opts[:config]||Forme.default_config] TRANSFORMER_TYPES.each{|k| instance_variable_set(:"@#{k}", transformer(k, @opts.fetch(k, config[k])))} @input_defaults = @opts[:input_defaults] || {} @hidden_tags = @opts[:hidden_tags] @nesting = [] end |
Instance Attribute Details
#error_handler ⇒ Object (readonly)
The error_handler
determines how to to mark tags as containing errors. Must respond to call
or be a registered symbol.
163 164 165 |
# File 'lib/forme.rb', line 163 def error_handler @error_handler end |
#formatter ⇒ Object (readonly)
The formatter
determines how the Inputs created are transformed into Tag
objects. Must respond to call
or be a registered symbol.
159 160 161 |
# File 'lib/forme.rb', line 159 def formatter @formatter end |
#hidden_tags ⇒ Object (readonly)
The hidden tags to automatically add to the form. If set, this should be an array, where elements are one of the following types:
- String, Array, Forme::Tag
-
Added directly as a child of the form tag.
- Hash
-
Adds a hidden tag for each entry, with keys as the name of the hidden tag and values as the value of the hidden tag.
- Proc
-
Will be called with the form tag object, and should return an instance of one of the handled types (or nil to not add a tag).
192 193 194 |
# File 'lib/forme.rb', line 192 def @hidden_tags end |
#input_defaults ⇒ Object (readonly)
Set the default options for inputs by type. This should be a hash with input type string keys and values that are hashes of input options.
175 176 177 |
# File 'lib/forme.rb', line 175 def input_defaults @input_defaults end |
#inputs_wrapper ⇒ Object (readonly)
The inputs_wrapper
determines how calls to inputs
are wrapped. Must respond to call
or be a registered symbol.
179 180 181 |
# File 'lib/forme.rb', line 179 def inputs_wrapper @inputs_wrapper end |
#labeler ⇒ Object (readonly)
The labeler
determines how to label tags. Must respond to call
or be a registered symbol.
167 168 169 |
# File 'lib/forme.rb', line 167 def labeler @labeler end |
#obj ⇒ Object (readonly)
The object related to the receiver, 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.
142 143 144 |
# File 'lib/forme.rb', line 142 def obj @obj end |
#opts ⇒ Object (readonly)
A hash of options for the receiver. Currently, the following are recognized by default:
- :obj
-
Sets the
obj
attribute - :error_handler
-
Sets the
error_handler
for the form - :formatter
-
Sets the
formatter
for the form - :hidden_tags
-
Sets the hidden tags to automatically add to this form.
- :input_defaults
-
Sets the default options for each input type
- :inputs_wrapper
-
Sets the
inputs_wrapper
for the form - :labeler
-
Sets the
labeler
for the form - :wrapper
-
Sets the
wrapper
for the form - :serializer
-
Sets the
serializer
for the form
155 156 157 |
# File 'lib/forme.rb', line 155 def opts @opts end |
#serializer ⇒ Object (readonly)
The serializer
determines how Tag
objects are transformed into strings. Must respond to call
or be a registered symbol.
183 184 185 |
# File 'lib/forme.rb', line 183 def serializer @serializer end |
#wrapper ⇒ Object (readonly)
The wrapper
determines how (potentially labeled) tags are wrapped. Must respond to call
or be a registered symbol.
171 172 173 |
# File 'lib/forme.rb', line 171 def wrapper @wrapper end |
Class Method Details
.form(obj = nil, attr = {}, opts = {}, &block) ⇒ Object
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 anobj
, 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
‘sobj
, 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 isForm
’s options.
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/forme.rb', line 210 def self.form(obj=nil, attr={}, opts={}, &block) f = if obj.is_a?(Hash) raise Error, "Can't provide 3 hash arguments to form" unless opts.empty? opts = attr attr = obj new(opts) else new(obj, opts) end ins = opts[:inputs] = opts[:button] if ins || block = Proc.new do |form| form._inputs(ins, opts) if ins yield form if block_given? form.emit(form.()) if end end f.form(attr, &block) end |
Instance Method Details
#<<(tag) ⇒ Object
Add the Input
/Tag
instance given to the currently open tag.
437 438 439 440 441 |
# File 'lib/forme.rb', line 437 def <<(tag) if n = @nesting.last n << tag end end |
#_input(*a) ⇒ Object
Create a new Input
associated with the receiver with the given arguments, doing no other processing.
360 361 362 |
# File 'lib/forme.rb', line 360 def _input(*a) Input.new(self, *a) end |
#_inputs(inputs = [], opts = {}) ⇒ Object
Internals of #inputs, should be used internally by the library, where #inputs is designed for external use.
381 382 383 384 385 386 387 388 389 390 391 392 |
# File 'lib/forme.rb', line 381 def _inputs(inputs=[], opts={}) if inputs.is_a?(Hash) opts = inputs.merge(opts) inputs = [] end transform(:inputs_wrapper, opts, self, opts) do inputs.each do |i| emit(input(*i)) end yield if block_given? end end |
#_tag(*a, &block) ⇒ Object
Create a Tag
associated to the receiver with the given arguments and block, doing no other processing.
408 409 410 |
# File 'lib/forme.rb', line 408 def _tag(*a, &block) tag = Tag.new(self, *a, &block) end |
#button(opts = {}) ⇒ Object
Creates a :submit Input
with the given opts, adding it to the list of children for the currently open tag.
429 430 431 432 433 434 |
# File 'lib/forme.rb', line 429 def (opts={}) opts = {:value=>opts} if opts.is_a?(String) input = _input(:submit, opts) self << input input end |
#close ⇒ Object
Returns a string representing the closing of the form tag, for serializers that support closing tags.
402 403 404 |
# File 'lib/forme.rb', line 402 def close serializer.serialize_close(_tag(:form)) if serializer.respond_to?(:serialize_close) end |
#emit(tag) ⇒ Object
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.
317 318 |
# File 'lib/forme.rb', line 317 def emit(tag) end |
#form(attr = {}, &block) ⇒ Object
Create a form tag with the given attributes.
305 306 307 |
# File 'lib/forme.rb', line 305 def form(attr={}, &block) tag(:form, attr, method(:hidden_form_tags), &block) end |
#format(input) ⇒ Object
Formats the input
using the formatter
.
310 311 312 |
# File 'lib/forme.rb', line 310 def format(input) transform(:formatter, input.opts, input) end |
#input(field, opts = {}) ⇒ Object
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
.
333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 |
# File 'lib/forme.rb', line 333 def input(field, opts={}) if opts.has_key?(:obj) opts = opts.dup obj = opts.delete(:obj) else obj = self.obj end input = if obj if obj.respond_to?(:forme_input) obj.forme_input(self, field, opts.dup) else opts = opts.dup opts[:name] = field unless opts.has_key?(:name) opts[:id] = field unless opts.has_key?(:id) opts[:value] = obj.send(field) unless opts.has_key?(:value) _input(:text, opts) end else _input(field, opts) end use_serializer(input) if input.is_a?(Array) self << input input end |
#inputs(*a, &block) ⇒ Object
Creates a tag using the inputs_wrapper
(a fieldset by default), calls input on each element of inputs
, and yields to if given a block. You can use array arguments if you want inputs to be created with specific options:
inputs([:field1, :field2])
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.
375 376 377 |
# File 'lib/forme.rb', line 375 def inputs(*a, &block) _inputs(*a, &block) end |
#open(attr) ⇒ Object
Returns a string representing the opening of the form tag for serializers that support opening tags.
396 397 398 |
# File 'lib/forme.rb', line 396 def open(attr) serializer.serialize_open(_tag(:form, attr)) if serializer.respond_to?(:serialize_open) end |
#serialize(tag) ⇒ Object
Serializes the tag
using the serializer
.
444 445 446 |
# File 'lib/forme.rb', line 444 def serialize(tag) serializer.call(tag) end |
#tag(*a, &block) ⇒ Object
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.
416 417 418 419 420 421 |
# File 'lib/forme.rb', line 416 def tag(*a, &block) tag = _tag(*a) self << tag nest(tag, &block) if block tag end |
#tag_(*a, &block) ⇒ Object
423 424 425 |
# File 'lib/forme.rb', line 423 def tag_(*a, &block) tag(*a, &block) end |
#transform(type, trans_name, *args, &block) ⇒ Object
If there is a related transformer, call it with the given args
and block
. Otherwise, attempt to return the initial input without modifying it.
258 259 260 261 262 263 264 265 266 267 268 269 270 271 |
# File 'lib/forme.rb', line 258 def transform(type, trans_name, *args, &block) if trans = transformer(type, trans_name) trans.call(*args, &block) else case type when :inputs_wrapper yield when :labeler, :error_handler, :wrapper args.first else raise Error, "No matching #{type}: #{trans_name.inspect}" end end end |
#transformer(type, trans) ⇒ Object
Get the related transformer for the given transformer type. Output depends on the type of trans
:
Symbol
-
Assume a request for a registered transformer, so look it up in the
TRANSFORRMERS
hash. Hash
-
If
type
is also a key intrans
, return the related value fromtrans
, unless the related value isnil
, in which case, returnnil
. Iftype
is not a key intrans
, use the default transformer for the receiver. nil
-
Assume the default transformer for this receiver.
- otherwise
-
return
trans
directly if it responds tocall
, and raise anError
if not.
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 |
# File 'lib/forme.rb', line 281 def transformer(type, trans) case trans when Symbol TRANSFORMERS[type][trans] || raise(Error, "invalid #{type}: #{trans.inspect} (valid #{type}s: #{TRANSFORMERS[type].keys.map{|k| k.inspect}.join(', ')})") when Hash if trans.has_key?(type) if v = trans[type] transformer(type, v) end else transformer(type, nil) end when nil send(type) else if trans.respond_to?(:call) trans else raise Error, "#{type} #{trans.inspect} must respond to #call" end end end |