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. -
#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. -
#_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(inputs = [], opts = {}) ⇒ 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. -
#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.
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
# File 'lib/forme.rb', line 222 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])))} @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.
160 161 162 |
# File 'lib/forme.rb', line 160 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.
156 157 158 |
# File 'lib/forme.rb', line 156 def formatter @formatter end |
#inputs_wrapper ⇒ Object (readonly)
The inputs_wrapper
determines how calls to inputs
are wrapped. Must respond to call
or be a registered symbol.
172 173 174 |
# File 'lib/forme.rb', line 172 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.
164 165 166 |
# File 'lib/forme.rb', line 164 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.
141 142 143 |
# File 'lib/forme.rb', line 141 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 - :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
152 153 154 |
# File 'lib/forme.rb', line 152 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.
176 177 178 |
# File 'lib/forme.rb', line 176 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.
168 169 170 |
# File 'lib/forme.rb', line 168 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.
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/forme.rb', line 194 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.
409 410 411 412 413 |
# File 'lib/forme.rb', line 409 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.
342 343 344 |
# File 'lib/forme.rb', line 342 def _input(*a) Input.new(self, *a) end |
#_tag(*a, &block) ⇒ Object
Create a Tag
associated to the receiver with the given arguments and block, doing no other processing.
384 385 386 |
# File 'lib/forme.rb', line 384 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.
401 402 403 404 405 406 |
# File 'lib/forme.rb', line 401 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.
378 379 380 |
# File 'lib/forme.rb', line 378 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.
299 300 |
# File 'lib/forme.rb', line 299 def emit(tag) end |
#form(attr = {}, &block) ⇒ Object
Create a form tag with the given attributes.
287 288 289 |
# File 'lib/forme.rb', line 287 def form(attr={}, &block) tag(:form, attr, &block) end |
#format(input) ⇒ Object
Formats the input
using the formatter
.
292 293 294 |
# File 'lib/forme.rb', line 292 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
.
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 |
# File 'lib/forme.rb', line 315 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(inputs = [], opts = {}) ⇒ 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.
357 358 359 360 361 362 363 364 365 366 367 368 |
# File 'lib/forme.rb', line 357 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 |
#open(attr) ⇒ Object
Returns a string representing the opening of the form tag for serializers that support opening tags.
372 373 374 |
# File 'lib/forme.rb', line 372 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
.
416 417 418 |
# File 'lib/forme.rb', line 416 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.
392 393 394 395 396 397 |
# File 'lib/forme.rb', line 392 def tag(*a, &block) tag = _tag(*a) self << tag nest(tag, &block) if block tag 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.
240 241 242 243 244 245 246 247 248 249 250 251 252 253 |
# File 'lib/forme.rb', line 240 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.
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
# File 'lib/forme.rb', line 263 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 |