Module: AttributeFu::AssociatedFormHelper
- Defined in:
- lib/attribute_fu/associated_form_helper.rb
Overview
Methods for building forms that contain fields for associated models.
Refer to the Conventions section in the README for the various expected defaults.
Instance Method Summary collapse
-
#add_associated_link(name, object, opts = {}) ⇒ Object
Creates a link that adds a new associated form to the page using Javascript.
-
#fields_for_associated(associated, *args, &block) ⇒ Object
Works similarly to fields_for, but used for building forms for associated objects.
-
#remove_link(name, *args) ⇒ Object
Creates a link for removing an associated element from the form, by removing its containing element from the DOM.
-
#render_associated_form(associated, opts = {}) ⇒ Object
Renders the form of an associated object, wrapping it in a fields_for_associated call.
Instance Method Details
#add_associated_link(name, object, opts = {}) ⇒ Object
Creates a link that adds a new associated form to the page using Javascript.
Must be called from within an associated form.
Must be provided with a new instance of the associated object.
e.g. f.add_associated_link 'Add Task', @project.tasks.build
An options hash can be specified to override the default behaviors.
Options are:
-
:partial- specify the name of the partial in which the form is located. -
:container- specify the DOM id of the container in which to insert the new element. -
:expression- specify a javascript expression with which to select the container to insert the new form in to (i.e. $(this).up(‘.tasks’)) -
:name- specify an alternate class name for the associated model (underscored)
Any additional options are forwarded to link_to_function. See its documentation for available options.
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/attribute_fu/associated_form_helper.rb', line 80 def add_associated_link(name, object, opts = {}) associated_name = extract_option_or_class_name(opts, :name, object) variable = "attribute_fu_#{associated_name}_count" opts.symbolize_keys! partial = opts.delete(:partial) || associated_name container = opts.delete(:expression) || "'#{opts.delete(:container) || associated_name.pluralize}'" form_builder = self # because the value of self changes in the block @template.link_to_function(name, opts) do |page| page << "if (typeof #{variable} == 'undefined') #{variable} = 0;" page << "new Insertion.Bottom(#{container}, new Template("+form_builder.render_associated_form(object, :fields_for => { :javascript => true }, :partial => partial).to_json+").evaluate({'number': --#{variable}}).gsub(/__number_/, #{variable}))" end end |
#fields_for_associated(associated, *args, &block) ⇒ Object
Works similarly to fields_for, but used for building forms for associated objects.
Automatically names fields to be compatible with the association_attributes= created by attribute_fu.
An options hash can be specified to override the default behaviors.
Options are: :javascript - Generate id placeholders for use with Prototype’s Template class (this is how attribute_fu’s add_associated_link works). :name - Specify the singular name of the association (in singular form), if it differs from the class name of the object.
Any other supplied parameters are passed along to fields_for.
Note: It is preferable to call render_associated_form, which will automatically wrap your form partial in a fields_for_associated call.
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/attribute_fu/associated_form_helper.rb', line 21 def fields_for_associated(associated, *args, &block) conf = args.last.is_a?(Hash) ? args.last : {} associated_name = extract_option_or_class_name(conf, :name, associated) name = associated_base_name associated_name unless associated.new_record? name << "[#{associated.new_record? ? 'new' : associated.id}]" else @new_objects ||= {} @new_objects[associated_name] ||= -1 # we want naming to start at 0 identifier = !conf.nil? && conf[:javascript] ? '#{number}' : @new_objects[associated_name]+=1 name << "[new][#{identifier}]" end @template.fields_for(name, *args.unshift(associated), &block) end |
#remove_link(name, *args) ⇒ Object
Creates a link for removing an associated element from the form, by removing its containing element from the DOM.
Must be called from within an associated form.
An options hash can be specified to override the default behaviors.
Options are:
-
:selector- The CSS selector with which to find the element to remove. -
:function- Additional javascript to be executed before the element is removed.
Any remaining options are passed along to link_to_function
51 52 53 54 55 56 57 58 59 60 |
# File 'lib/attribute_fu/associated_form_helper.rb', line 51 def remove_link(name, *args) = args. css_selector = .delete(:selector) || ".#{@object.class.name.split("::").last.underscore}" function = .delete(:function) || "" function << "$(this).up('#{css_selector}').remove()" @template.link_to_function(name, function, *args.push()) end |
#render_associated_form(associated, opts = {}) ⇒ Object
Renders the form of an associated object, wrapping it in a fields_for_associated call.
The associated argument can be either an object, or a collection of objects to be rendered.
An options hash can be specified to override the default behaviors.
Options are:
-
:new- specify a certain number of new elements to be added to the form. Useful for displaying a few blank elements at the bottom. -
:name- override the name of the association, both for the field names, and the name of the partial -
:partial- specify the name of the partial in which the form is located. -
:fields_for- specify additional options for the fields_for_associated call -
:locals- specify additional variables to be passed along to the partial -
:render- specify additional options to be passed along to the render :partial call
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/attribute_fu/associated_form_helper.rb', line 111 def render_associated_form(associated, opts = {}) associated = associated.is_a?(Array) ? associated : [associated] # preserve association proxy if this is one opts.symbolize_keys! (opts[:new] - associated.select(&:new_record?).length).times { associated.build } if opts[:new] unless associated.empty? name = extract_option_or_class_name(opts, :name, associated.first) partial = opts[:partial] || name local_assign_name = partial.split('/').last.split('.').first associated.map do |element| fields_for_associated(element, (opts[:fields_for] || {}).merge(:name => name)) do |f| @template.render({:partial => "#{partial}", :locals => {local_assign_name.to_sym => element, :f => f}.merge(opts[:locals] || {})}.merge(opts[:render] || {})) end end end end |