This module extends all Forme::Form
instances that use a Sequel::Model
instance as the form’s obj
.
Public Instance methods
If the form has the :formactions option and the button has the formaction option or attribute, append the action and method for this button to the formactions. This is used by the Roda
forme_route_csrf and forme_set plugins so that formaction can work as expected.
# File lib/sequel/plugins/forme.rb 25 def button(opts={}) 26 if opts.is_a?(Hash) && (formactions = self.opts[:formactions]) && 27 (formaction = opts[:formaction] || ((attr = opts[:attr]) && (attr[:formaction] || attr['formaction']))) 28 formmethod = opts[:formmethod] || 29 ((attr = opts[:attr]) && (attr[:formmethod] || attr['formmethod'])) || 30 ((attr = form_tag_attributes) && (attr[:method] || attr['method'])) 31 formactions << [formaction, formmethod] 32 end 33 super 34 end
Use the post method by default for Sequel
forms, unless overridden with the :method attribute.
# File lib/sequel/plugins/forme.rb 38 def form(attr={}, &block) 39 attr[:class] = ::Forme.merge_classes(attr[:class], "forme", obj.forme_namespace) 40 super(attr, &block) 41 end
Call humanize on a string version of the argument if String#humanize exists. Otherwise, do some monkeying with the string manually.
# File lib/sequel/plugins/forme.rb 46 def humanize(s) 47 s = s.to_s 48 s.respond_to?(:humanize) ? s.humanize : s.gsub(/_id$/, "").gsub(/_/, " ").capitalize 49 end
Handle nested association usage. The association
should be a name of the association for the form’s obj
. Inside the block, calls to the input
and inputs
methods for the receiver treat the associated object as the recevier’s obj
, using name and id attributes that work with the Sequel
nested_attributes
plugin. Returns the HTML generated by the subform.
The following options are currently supported:
:inputs |
Automatically call |
:inputs_opts |
When using the :grid option, this allows you to specify options to pass to the table InputsWrapper. |
:legend |
Overrides the default :legend used (which is based on the association name). You can also use a proc as the value, which will called with each associated object (and the position in the associated object already for *_to_many associations), and should return the legend string to use for that object. |
:grid |
Sets up a table with one row per associated object, and one column per field. |
:labels |
When using the :grid option, override the labels that would be created via the :inputs option. If you are not providing an :inputs option or are using a block with additional inputs, you should specify this option. |
:skip_primary_key |
Skip adding a hidden primary key field for existing objects. |
# File lib/sequel/plugins/forme.rb 77 def subform(association, opts={}, &block) 78 content_added do 79 nested_obj = opts.has_key?(:obj) ? opts[:obj] : obj.send(association) 80 ref = obj.class.association_reflection(association) 81 multiple = ref.returns_array? 82 grid = opts[:grid] 83 ns = "#{association}_attributes" 84 85 send(multiple ? :each_obj : :with_obj, nested_obj, ns) do |no, i| 86 input(ref.associated_class.primary_key, :type=>:hidden, :label=>nil, :wrapper=>nil) unless no.new? || opts[:skip_primary_key] 87 end 88 89 contents = proc do 90 send(multiple ? :each_obj : :with_obj, nested_obj, ns) do |no, i| 91 options = opts.dup 92 if grid 93 options.delete(:legend) 94 else 95 if options.has_key?(:legend) 96 if options[:legend].respond_to?(:call) 97 options[:legend] = multiple ? options[:legend].call(no, i) : options[:legend].call(no) 98 end 99 else 100 if multiple 101 options[:legend] = humanize("#{obj.model.send(:singularize, association)} ##{i+1}") 102 else 103 options[:legend] = humanize(association) 104 end 105 end 106 end 107 options[:subform] = true 108 109 inputs(options[:inputs]||[], options, &block) 110 end 111 end 112 113 if grid 114 labels = opts.fetch(:labels){opts[:inputs].map{|l,| humanize(l)} if opts[:inputs]} 115 legend = opts.fetch(:legend){humanize(association)} 116 inputs_opts = opts[:inputs_opts] || {} 117 inputs(inputs_opts.merge(:inputs_wrapper=>:table, :nested_inputs_wrapper=>:tr, :wrapper=>:td, :labeler=>nil, :labels=>labels, :legend=>legend), &contents) 118 else 119 contents.call 120 end 121 end 122 end