Module Mack::ViewHelpers::FormHelpers
In: lib/mack/view_helpers/date_time_helpers.rb
lib/mack/view_helpers/form_helpers.rb

A useful collection of helpers for forms.

Methods

Constants

MONTHS = [["January", 1], ["February", 2], ["March", 3], ["April", 4], ["May", 5], ["June", 6], ["July", 7], ["August", 8], ["September", 9], ["October", 10], ["November", 11], ["December", 12]] unless defined?(MONTHS)
DAYS = []
HOURS = []
MINUTES = []

Public Instance methods

Examples:

  @user = User.new(:accepted_tos => true)
  <%= check_box :user, :accepted_tos %> # => <input checked="checked" id="user_accepted_tos" name="user[accepted_tos]" type="checkbox" />
  <%= check_box :i_dont_exist %> # => <input id="i_dont_exist" name="i_dont_exist" type="checkbox" />

[Source]

     # File lib/mack/view_helpers/form_helpers.rb, line 112
112:       def check_box(name, *args)
113:         build_form_element(name, {:type => :checkbox}, *args) do |var, fe, options|
114:           if options[:value]
115:             options.merge!(:checked => "checked")
116:           end
117:           options.delete(:value)
118:         end
119:       end

Used just like date_time_select, but it has hours, minutes, and seconds turned off. See date_time_select for more options.

  @user = User.new
  <%= :user.date_select :birth_date %>
  @some_time = Time.new
  <%= :date_select :some_time, :label => true %>

[Source]

     # File lib/mack/view_helpers/date_time_helpers.rb, line 99
 99:       def date_select(name, *args)
100:         fe = FormElement.new(*args)
101:         date_time_select(name, fe.calling_method, {:hours => false, :minutes => false, :seconds => false}.merge(fe.options))
102:       end

This will create a series of select boxes that compromise a time object. By default boxes will be created for day/month/year hour:minute. You can optionally turn on or off any of these boxes, including seconds by setting them to true/false. For example:

  <%= date_time_select :some_time, :days => false %>

will not produce a select box for days, and so on…

You can pass in an array of arrays to represent the options for any of the boxes like such:

  <%= date_time_select :some_time, :day_options => [[1,"one"], [2,"two"]] %>

Will produce a day select box with only two options. Alternatively you can pass in an array of values and the options will be done for you. Like such:

  <%= date_time_select :some_time, :day_values => 1..60 %>

Will produce a day select box with 60 options whose values and keys will be the same.

The separators for dates and times can be set with the date_separator and time_separator options. By default they are:

  :date_separator => '/'
  :time_separator => ':'

[Source]

    # File lib/mack/view_helpers/date_time_helpers.rb, line 43
43:       def date_time_select(name, *args)
44:         var = instance_variable_get("@#{name}")
45:         fe = FormElement.new(*args)
46:         
47:         time = var if var.is_a?(Time) || var.is_a?(Date)
48:         time = var.nil? ? Time.now : (var.send(fe.calling_method) || Time.now) if time.nil?
49:         
50:         years = []
51:         (time.year - 5).upto(time.year + 5) { |y| years << [y, y]}
52:         
53:         options = {:years => true, :months => true, :days => true, :hours => true, :minutes => true, :seconds => false, :year_options => years, :month_options => MONTHS, :day_options => DAYS, :hour_options => HOURS, :minute_options => MINUTES, :second_options => MINUTES, :date_separator => '/', :time_separator => ':', :date_order => [:month, :day, :year], :time_order => [:hour, :minute, :second], :date_time_order => [:date, :time]}.merge(fe.options)
54:         
55:         [:year, :month, :day, :hour, :minute, :second].each do |v|
56:           if options["#{v}_values".to_sym]
57:             options["#{v}_options".to_sym] = []
58:             options["#{v}_values".to_sym].each {|i| options["#{v}_options".to_sym] << [i, i]}
59:           end
60:         end
61:         
62:         fe.options - [:years, :months, :days, :hours, :minutes, :seconds, :year_options, :month_options, :day_options, :hour_options, :minute_options, :second_options, :year_values, :month_values, :day_values, :hour_values, :minute_values, :second_values, :date_order, :time_order, :date_time_order]
63:         
64:         label = label_parameter_tag(name, (fe.calling_method == :to_s ? name : "#{name}_#{fe.calling_method}"), var, fe)
65: 
66:         
67:         date_boxes = []
68:         options[:date_order].collect! { |s| s.to_sym }
69:         date_boxes[options[:date_order].index(:month)] = dt_select(:month, name, fe, time.month, options[:month_options]) if options[:months]
70:         date_boxes[options[:date_order].index(:day)] = dt_select(:day, name, fe, time.day, options[:day_options]) if options[:days]
71:         date_boxes[options[:date_order].index(:year)] = dt_select(:year, name, fe, time.year, options[:year_options]) if options[:years]
72:         date_boxes.compact!
73:         
74:         time_boxes = []
75:         options[:time_order].collect! { |s| s.to_sym }
76:         time_boxes[options[:time_order].index(:hour)] = dt_select(:hour, name, fe, time.hour, options[:hour_options]) if options[:hours]
77:         time_boxes[options[:time_order].index(:minute)] = dt_select(:minute, name, fe, time.min, options[:minute_options]) if options[:minutes]
78:         time_boxes[options[:time_order].index(:second)] = dt_select(:second, name, fe, time.sec, options[:second_options]) if options[:seconds]
79:         time_boxes.compact!
80:         
81:         elts = []
82:         elts[options[:date_time_order].index(:date)] = date_boxes.join(options[:date_separator])
83:         unless elts.empty?
84:           elts[options[:date_time_order].index(:time)] = time_boxes.join(options[:time_separator])
85:         end
86:         elts.compact!
87:         
88:         boxes = elts.join(" ").strip
89:         return label + boxes
90:       end

Generates a button with a form around it and will set the request method to delete.

[Source]

    # File lib/mack/view_helpers/form_helpers.rb, line 55
55:       def delete_button(url, value = "Delete", form_options = {}, button_options = {})
56:         t = "\n" << hidden_field(:_method, :value => :delete)
57:         t << "\n" << submit_button(value, button_options)
58:         t << "\n"
59:         content_tag(:form, {:action => url, :method => :post}.merge(form_options), t)
60:       end

Examples:

  @user = User.new(:bio_file => "~/bio.doc")
  <%= file_field :user, :bio_file %> # => <input id="user_bio_field" name="user[bio_field]" type="file" value="~/bio.doc" />
  <%= file_field :i_dont_exist %> # => <input id="i_dont_exist" name="i_dont_exist" type="file" value="" />

[Source]

     # File lib/mack/view_helpers/form_helpers.rb, line 125
125:       def file_field(name, *args)
126:         build_form_element(name, {:type => :file}, *args)
127:       end

Examples:

  <% form(users_create_url) do -%>
    # form stuff here...
  <% end -%>

  <% form(users_update_url, :method => :put) do -%>
    # form stuff here...
  <% end -%>

  <% form(photos_create_url, :multipart => true) do -%>
    # form stuff here...
  <% end -%>

[Source]

    # File lib/mack/view_helpers/form_helpers.rb, line 31
31:       def form(action, options = {}, &block)
32:         options = {:method => :post, :action => action}.merge(options)
33:         form_builder = options.delete(:builder) || configatron.mack.default_form_builder.camelcase.constantize.new(Thread.current[:view_template])
34:         if options[:id]
35:           options = {:class => options[:id]}.merge(options)
36:         end
37:         if options[:multipart]
38:           options = {:enctype => "multipart/form-data"}.merge(options)
39:           options.delete(:multipart)
40:         end
41:         meth = nil
42:         unless options[:method] == :get || options[:method] == :post
43:           meth = "<input name=\"_method\" type=\"hidden\" value=\"#{options[:method]}\" />\n"
44:           options[:method] = :post
45:         end
46:         concat("<form#{build_options(options)}>\n", block.binding)
47:         concat(meth, block.binding) unless meth.blank?
48:         concat(form_authenticity_field, block.binding) unless configatron.mack.disable_forgery_detector
49:         yield form_builder
50:         concat("\n</form>", block.binding)
51:         # content_tag(:form, options, &block)
52:       end

Get the secret token to be added in an HTML form. This is to ensure that your form is valid.

Only call this method if you generate the form manually. If you use the form() method to generate your form, then the authenticity token is already included in your form.

[Source]

    # File lib/mack/view_helpers/form_helpers.rb, line 14
14:       def form_authenticity_field
15:         str = %{<input type="hidden" name="__authenticity_token" value="#{Mack::Utils::AuthenticityTokenDispenser.instance.dispense_token(request.session.id)}" />\n}
16:       end

Examples:

  @user = User.new(:email => "mark@mackframework.com")
  <%= hidden_field :user, :email %> # => <input id="user_email" name="user[email]" type="hidden" value="mark@mackframework.com" />
  <%= hidden_field :i_dont_exist %> # => <input id="i_dont_exist" name="i_dont_exist" type="hidden" />

[Source]

     # File lib/mack/view_helpers/form_helpers.rb, line 133
133:       def hidden_field(name, *args)
134:         build_form_element(name, {:type => :hidden}, *args)
135:       end

Examples:

  <%= image_submit "logo.png" %> # => <input src="/images/logo.png" type="image" />

[Source]

     # File lib/mack/view_helpers/form_helpers.rb, line 139
139:       def image_submit(src, options = {})
140:         non_content_tag(:input, {:type => :image, :src => "/images/#{src}"}.merge(options))
141:       end

Examples:

  @user = User.new
  <%= label_tag :user, :email %> # => <label for="user_email">Email</label>
  <%= label_tag :i_dont_exist %> # => <label for="i_dont_exist">I don't exist</label>
  <%= label_tag :i_dont_exist, :value => "Hello" %> # => <label for="i_dont_exist">Hello</label>

[Source]

     # File lib/mack/view_helpers/form_helpers.rb, line 249
249:       def label_tag(name, *args)
250:         fe = FormElement.new(*args)
251:         unless fe.options[:for]
252:           fe.options[:for] = (fe.calling_method == :to_s ? name.to_s : "#{name}_#{fe.calling_method}")
253:         end
254:         unless fe.options[:value]
255:           fe.options[:value] = (fe.calling_method == :to_s ? name.to_s.humanize : fe.calling_method.to_s.humanize)
256:         end
257:         content = fe.options[:value]
258:         fe.options.delete(:value)
259:         content_tag(:label, fe.options, content)
260:       end

Examples:

  @user = User.new(:email => "mark@mackframework.com")
  <%= password_field :user, :email %> # => <input id="user_email" name="user[email]" type="password" value="mark@mackframework.com" />
  <%= password_field :i_dont_exist %> # => <input id="i_dont_exist" name="i_dont_exist" type="password" />

[Source]

     # File lib/mack/view_helpers/form_helpers.rb, line 223
223:       def password_field(name, *args)
224:         build_form_element(name, {:type => :password}, *args)
225:       end

Examples:

  @user = User.new(:level => 1)
  <%= radio_button :user, :level %> # => <input checked="checked" id="user_level" name="user[level]" type="radio" value="1" />
  <%= radio_button :user, :level, :value => 2 %> # => <input id="user_level" name="user[level]" type="radio" value="2" />
  <%= radio_button :i_dont_exist %> # => <input id="i_dont_exist" name="i_dont_exist" type="radio" value="" />

[Source]

     # File lib/mack/view_helpers/form_helpers.rb, line 232
232:       def radio_button(name, *args)
233:         build_form_element(name, {:type => :radio, :value => ""}, *args) do |var, fe, options|
234:           if fe.options[:value]
235:             if fe.options[:value] == options[:value]
236:               options.merge!(:checked => "checked")
237:             end
238:           elsif options[:value]
239:             options.merge!(:checked => "checked")
240:           end
241:         end
242:       end

Examples:

  @user = User.new(:level => 1)
  <%= select_tag :user, :level, :options => [["one", 1], ["two", 2]] %> # => <select id="user_level" name="user[level]"><option value="1" selected>one</option><option value="2" >two</option></select>
  <%= select_tag :user :level, :options => {:one => 1, :two => 2} %> # => <select id="user_level" name="user[level]"><option value="1" selected>one</option><option value="2" >two</option></select>
  <%= select_tag :i_dont_exist :options => [["one", 1], ["two", 2]], :selected => 1 %> # => <select id="i_dont_exist" name="i_dont_exist"><option value="1" selected>one</option><option value="2" >two</option></select>

[Source]

     # File lib/mack/view_helpers/form_helpers.rb, line 148
148:       def select_tag(name, *args)
149:         var = instance_variable_get("@#{name}")
150:         fe = FormElement.new(*args)
151:         options = {:name => name, :id => name}
152:         unless fe.calling_method == :to_s
153:           options.merge!(:name => "#{name}[#{fe.calling_method}]", :id => "#{name}_#{fe.calling_method}")
154:         end
155: 
156:         content = ""
157: 
158:         opts = fe.options[:options]
159:         unless opts.nil?
160:           sopts = opts
161:           if opts.is_a?(Array)
162:           elsif opts.is_a?(Hash)
163:             sopts = []
164:             opts.sort.each do |k,v|
165:               sopts << [k, v]
166:             end
167:           else
168:             raise ArgumentError.new(":options must be either an Array of Arrays or a Hash!")
169:           end
170:           sel_value = var.send(fe.calling_method) if var
171:           sel_value = fe.options[:selected] if fe.options[:selected]
172:           sopts.each do |kv|
173:             selected = kv[1].to_s == sel_value.to_s ? "selected" : ""
174:             content << %{\n<option value="#{kv[1]}" #{selected}>#{kv[0]}</option>}
175:           end
176:           fe.options.delete(:selected)
177:           fe.options.delete(:options)
178:         end
179:         
180:         return label_parameter_tag(name, options[:id], var, fe) + content_tag(:select, options.merge(fe.options), content)
181:       end

Examples:

  <%= submit_button %> # => <input type="submit" value="Submit" />
  <%= submit_button "Login" %> # => <input type="submit" value="Login" />
  You can disable the button after clicking it. In essence, this will work as follows:
  <%= submit_button "Login", :disable_with => "Please wait..." %>
   # => <input type="submit" value="Login" onclick="this.disabled=true;this.value='Please wait...';this.form.submit();" />
 Even though :disable_with will work on the onclick parameter, you can add your own onclick behaviour to the mix, as follows:
 <%= submit_button "Login", :disable_with => "Please wait...", :onclick => "alert('test')" %>
   # => <input type="submit" value="Login" onclick="this.disabled=true;this.value='Please wait...';alert('test');this.form.submit();" />

Please note that if the form.submit() returns false the button‘s value will be restored to its initial value. This behaviour is acheived through the injection of a couple bits of JS into the onlick existing parameter. These bits are injected after the disabled value, and all existing onclick behaviour that you define in the :onlick option. The included JS bits are as follows:

  "result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit())",
  "if (result == false) { this.value = this.getAttribute('originalValue'); this.disabled = false }",
  "return result;"

[Source]

     # File lib/mack/view_helpers/form_helpers.rb, line 80
 80:       def submit_button(value = "Submit", options = {}, *original_args)
 81:         if options[:confirm]
 82:           onclick = "if (confirm('#{options.delete(:confirm)}')) {submit();}; return false;"
 83:           onclick << ";#{options.delete(:onclick)}" if options.has_key?(:onclick)
 84:           options[:onclick] = onclick
 85:         end
 86:         # processing the disable with option, which will be embebed in the onclick parameter.
 87:         if disable_with = options.delete(:disable_with)
 88:           disable_with = "this.innerHTML='#{disable_with}'"
 89:           
 90:           # Making sure that we keep the content of the onclick option, should it exist.
 91:           disable_with << ";#{options.delete(:onclick)}" if options.has_key?(:onclick)
 92:           
 93:           # Setting the onlick option.
 94:           options[:onclick] = [
 95:             "this.setAttribute('originalValue', this.innerHTML)",
 96:             "this.disabled=true",
 97:             disable_with,
 98:             "result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit())",
 99:             "if (result == false) { this.innerHTML = this.getAttribute('originalValue'); this.disabled = false }",
100:             "return result;",
101:           ].join(";")
102:         end
103:         
104:         # non_content_tag(:input, {:type => :submit, :value => value}.merge(options))
105:         content_tag(:button, {:type => :submit}.merge(options), value)
106:       end

Examples:

  @user = User.new(:bio => "my bio here")
  <%= text_area :user, :bio %> # => <textarea id="user_bio" name="user[bio]">my bio here</textarea>
  <%= text_area :i_dont_exist %> # => <textarea id="i_dont_exist" name="i_dont_exist"></textarea>
  <%= text_area :i_dont_exist :value => "hi there" %> # => <textarea id="i_dont_exist" name="i_dont_exist">hi there</textarea>

[Source]

     # File lib/mack/view_helpers/form_helpers.rb, line 188
188:       def text_area(name, *args)
189:         var = instance_variable_get("@#{name}")
190:         fe = FormElement.new(*args)
191:         options = {:name => name, :id => name, :cols => 60, :rows => 20}
192:         if var.nil?
193:           value = fe.options[:value]
194:           fe.options.delete(:value)
195:           return label_parameter_tag(name, options[:id], var, fe) + content_tag(:textarea, options.merge(fe.options), value)
196:         else
197:           unless fe.calling_method == :to_s
198:             options.merge!(:name => "#{name}[#{fe.calling_method}]", :id => "#{name}_#{fe.calling_method}")
199:           end
200:           options[:value] = var.send(fe.calling_method)
201:           
202:           yield var, fe, options if block_given?
203:           
204:           content = options[:value]
205:           options.delete(:value)
206:           
207:           return label_parameter_tag(name, options[:id], var, fe) + content_tag(:textarea, options.merge(fe.options), content)
208:         end
209:       end

Examples:

  @user = User.new(:email => "mark@mackframework.com")
  <%= text_field :user, :email %> # => <input id="user_email" name="user[email]" type="text" value="mark@mackframework.com" />
  <%= text_field :i_dont_exist %> # => <input id="i_dont_exist" name="i_dont_exist" type="text" />

[Source]

     # File lib/mack/view_helpers/form_helpers.rb, line 215
215:       def text_field(name, *args)
216:         build_form_element(name, {:type => :text}, *args)
217:       end

[Validate]