| Module | AttributeFu::AssociatedFormHelper |
| In: |
lib/attribute_fu/associated_form_helper.rb
|
Methods for building forms that contain fields for associated models.
Refer to the Conventions section in the README for the various expected defaults.
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:
# File lib/attribute_fu/associated_form_helper.rb, line 76
76: def add_associated_link(name, object, opts = {})
77: associated_name = object.class.name.underscore
78: variable = "attribute_fu_#{associated_name}_count"
79:
80: opts.symbolize_keys!
81: partial = opts[:partial] || associated_name
82: container = opts[:container] || associated_name.pluralize
83:
84: form_builder = self # because the value of self changes in the block
85:
86: @template.link_to_function name do |page|
87: page << "if (typeof #{variable} == 'undefined') #{variable} = 0;"
88: page << "new Insertion.Bottom('#{container}', new Template("+form_builder.render_associated_form(object, :fields_for => { :javascript => true }, :partial => partial).to_json+").evaluate({'number': --#{variable}}))"
89: end
90: end
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.
# File lib/attribute_fu/associated_form_helper.rb, line 21
21: def fields_for_associated(associated, *args, &block)
22: conf = args.last.is_a?(Hash) ? args.last : {}
23: associated_name = (conf.delete(:name) || associated.class.name.underscore).to_s
24: name = associated_base_name associated_name
25:
26: unless associated.new_record?
27: name << "[#{associated.new_record? ? 'new' : associated.id}]"
28: else
29: @new_objects ||= {}
30: @new_objects[associated_name] ||= -1 # we want naming to start at 0
31: identifier = !conf.nil? && conf[:javascript] ? '#{number}' : @new_objects[associated_name]+=1
32:
33: name << "[new][#{identifier}]"
34: end
35:
36: @template.fields_for(name, *args.unshift(associated), &block)
37: end
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:
Any remaining options are passed along to link_to_function
# File lib/attribute_fu/associated_form_helper.rb, line 51
51: def remove_link(name, *args)
52: options = args.extract_options!
53:
54: css_selector = options.delete(:selector) || ".#{@object.class.name.underscore}"
55: function = options.delete(:function) || ""
56:
57: function << "$(this).up("#{css_selector}").remove()"
58:
59: @template.link_to_function(name, function, *args.push(options))
60: end
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:
# File lib/attribute_fu/associated_form_helper.rb, line 107
107: def render_associated_form(associated, opts = {})
108: associated = associated.is_a?(Array) ? associated : [associated] # preserve association proxy if this is one
109:
110: opts.symbolize_keys!
111: (opts[:new] - associated.select(&:new_record?).length).times { associated.build } if opts[:new]
112:
113: unless associated.empty?
114: name = (opts[:name] || associated.first.class.name.underscore).to_s
115: partial = opts[:partial] || name
116: local_assign_name = partial.split('/').last.split('.').first
117:
118: associated.map do |element|
119: fields_for_associated(element, (opts[:fields_for] || {}).merge(:name => name)) do |f|
120: @template.render({:partial => "#{partial}", :locals => {local_assign_name.to_sym => element, :f => f}.merge(opts[:locals] || {})}.merge(opts[:render] || {}))
121: end
122: end
123: end
124: end