Class: RPH::FormAssistant::FormBuilder
- Inherits:
-
ActionView::Helpers::FormBuilder
- Object
- ActionView::Helpers::FormBuilder
- RPH::FormAssistant::FormBuilder
- Defined in:
- lib/form_assistant/form_builder.rb
Overview
FormAssistant::FormBuilder
* provides several convenient helpers (see helpers.rb) and
an infrastructure to easily add your own
* method_missing hook to wrap content "on the fly"
* optional: automatically attach labels to field helpers
* optional: format fields using partials (extremely extensible)
Usage:
<% form_for @project, :builder => RPH::FormAssistant::FormBuilder do |form| %>
// fancy form stuff
<% end %>
- or -
<% form_assistant_for @project do |form| %>
// fancy form stuff
<% end %>
- or -
# in config/intializers/form_assistant.rb
ActionView::Base.default_form_builder = RPH::FormAssistant::FormBuilder
Class Attribute Summary collapse
-
.ignore_errors ⇒ Object
Returns the value of attribute ignore_errors.
-
.ignore_labels ⇒ Object
Returns the value of attribute ignore_labels.
-
.ignore_templates ⇒ Object
Returns the value of attribute ignore_templates.
-
.template_root(full_path = false) ⇒ Object
sets the root directory where templates will be searched note: the template root should be nested within the configured view path (which defaults to app/views).
Instance Attribute Summary collapse
-
#fallback_template ⇒ Object
used if no other template is available.
Class Method Summary collapse
Instance Method Summary collapse
- #column_type(field) ⇒ Object
-
#fields_for_with_form_assistant(record_or_name_or_array, *args, &proc) ⇒ Object
since #fields_for() doesn’t inherit the builder from form_for, we need to provide a means to set the builder automatically (works with nesting, too).
- #input(field, *args) ⇒ Object
- #inputs(*args) ⇒ Object
-
#partial(name, options = {}) ⇒ Object
Renders a partial, passing the form object as a local variable named ‘form’ <%= form.partial ‘shared/new’, :locals => { :whatever => @whatever } %>.
- #widget(*args, &block) ⇒ Object
- #without_assistance(options = {}, &block) ⇒ Object
Class Attribute Details
.ignore_errors ⇒ Object
Returns the value of attribute ignore_errors.
45 46 47 |
# File 'lib/form_assistant/form_builder.rb', line 45 def ignore_errors @ignore_errors end |
.ignore_labels ⇒ Object
Returns the value of attribute ignore_labels.
44 45 46 |
# File 'lib/form_assistant/form_builder.rb', line 44 def ignore_labels @ignore_labels end |
.ignore_templates ⇒ Object
Returns the value of attribute ignore_templates.
43 44 45 |
# File 'lib/form_assistant/form_builder.rb', line 43 def ignore_templates @ignore_templates end |
.template_root(full_path = false) ⇒ Object
sets the root directory where templates will be searched note: the template root should be nested within the configured view path (which defaults to app/views)
71 72 73 |
# File 'lib/form_assistant/form_builder.rb', line 71 def template_root @template_root end |
Instance Attribute Details
#fallback_template ⇒ Object
used if no other template is available
36 37 38 |
# File 'lib/form_assistant/form_builder.rb', line 36 def fallback_template @fallback_template end |
Class Method Details
.assist(helper_name) ⇒ Object
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'lib/form_assistant/form_builder.rb', line 204 def self.assist(helper_name) define_method(helper_name) do |field, *args| = (helper_name == 'check_box' ? args.shift : args.) || {} = (field, ) = (helper_name, ) extra_locals = .delete(:locals) || {} # build out the label element (if desired) label = [:label] === false ? nil : self.label(field, .delete(:text), ) # grab the tip, if any tip = .delete(:tip) # is the field required? required = !!.delete(:required) # ensure that we don't have any custom options pass through = .except(:label, :template, :tip, :required) # call the original render for the element super_args = helper_name == 'check_box' ? args.unshift() : args.push() element = super(field, *super_args) return element if [:template] === false # return the helper with an optional label if templates are not to be used return render_element(element, field, helper_name, , [:label] === false) if self.class.ignore_templates # render the partial template from the desired template root render_partial_for(element, field, label, tip, [:template], helper_name, required, extra_locals, args) end end |
.view_path ⇒ Object
60 61 62 63 64 65 66 |
# File 'lib/form_assistant/form_builder.rb', line 60 def view_path if Rails.configuration.respond_to?(:view_path) return Rails.configuration.view_path else return Rails.configuration.paths['app/views'].first end end |
Instance Method Details
#column_type(field) ⇒ Object
313 314 315 |
# File 'lib/form_assistant/form_builder.rb', line 313 def column_type(field) object.class.columns_hash[field.to_s].type rescue :string end |
#fields_for_with_form_assistant(record_or_name_or_array, *args, &proc) ⇒ Object
since #fields_for() doesn’t inherit the builder from form_for, we need to provide a means to set the builder automatically (works with nesting, too)
Usage: simply call #fields_for() on the builder object
<% form_assistant_for @project do |form| %>
<%= form.text_field :title %>
<% form.fields_for :tasks do |task_fields| %>
<%= task_fields.text_field :name %>
<% end %>
<% end %>
328 329 330 331 332 |
# File 'lib/form_assistant/form_builder.rb', line 328 def fields_for_with_form_assistant(record_or_name_or_array, *args, &proc) = args. # hand control over to the original #fields_for() fields_for_without_form_assistant(record_or_name_or_array, *(args << .merge!(:builder => self.class)), &proc) end |
#input(field, *args) ⇒ Object
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 |
# File 'lib/form_assistant/form_builder.rb', line 290 def input(field, *args) helper_name = case column_type(field) when :string field.to_s.include?('password') ? :password_field : :text_field when :text ; :text_area when :integer, :float, :decimal ; :text_field when :date ; :date_select when :datetime, :timestamp ; :datetime_select when :time ; :time_select when :boolean ; :check_box else ; :text_field end send(helper_name, field, *args) end |
#inputs(*args) ⇒ Object
306 307 308 309 310 311 |
# File 'lib/form_assistant/form_builder.rb', line 306 def inputs(*args) = args. args.flatten.map do |field| input(field, .dup) end.join('') end |
#partial(name, options = {}) ⇒ Object
Renders a partial, passing the form object as a local variable named ‘form’ <%= form.partial ‘shared/new’, :locals => { :whatever => @whatever } %>
284 285 286 287 288 |
# File 'lib/form_assistant/form_builder.rb', line 284 def partial(name, ={}) ([:locals] ||= {}).update :form => self .update :partial => name @template.render end |
#widget(*args, &block) ⇒ Object
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 |
# File 'lib/form_assistant/form_builder.rb', line 257 def (*args, &block) = args. fields = args.shift || nil field = Array === fields ? fields.first : fields = (field, ) = (self.fallback_template, ) label = [:label] === false ? nil : self.label(field, .delete(:text), ) tip = .delete(:tip) locals = .delete(:locals) required = !!.delete(:required) if block_given? element = without_assistance do @template.capture(&block) end else element = nil end partial = render_partial_for(element, fields, label, tip, [:template], 'widget', required, locals, args) RPH::FormAssistant::Rules.binding_required? ? @template.concat(partial, block.binding) : @template.concat(partial) end |
#without_assistance(options = {}, &block) ⇒ Object
243 244 245 246 247 248 249 250 251 252 253 254 255 |
# File 'lib/form_assistant/form_builder.rb', line 243 def without_assistance(={}, &block) # TODO - allow options to only turn off templates and/or labels ignore_labels, ignore_templates = self.class.ignore_labels, self.class.ignore_templates begin self.class.ignore_labels, self.class.ignore_templates = true, true result = yield ensure self.class.ignore_labels, self.class.ignore_templates = ignore_labels, ignore_templates end result end |