Module: Mack::ViewHelpers::FormHelpers
- Defined in:
- lib/mack/view_helpers/form_helpers.rb,
lib/mack/view_helpers/date_time_helpers.rb
Overview
A useful collection of helpers for forms.
Defined Under Namespace
Classes: FormElement
Constant Summary collapse
- 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]]
- DAYS =
[]
- HOURS =
[]
- MINUTES =
[]
Instance Method Summary collapse
-
#check_box(name, *args) ⇒ Object
Examples: @user = User.new(:accepted_tos => true) <%= check_box :user, :accepted_tos %> # => <input checked=“checked” id=“user_accepted_tos” name=“user” type=“checkbox” /> <%= check_box :i_dont_exist %> # => <input id=“i_dont_exist” name=“i_dont_exist” type=“checkbox” />.
-
#date_select(name, *args) ⇒ Object
Used just like date_time_select, but it has hours, minutes, and seconds turned off.
-
#date_time_select(name, *args) ⇒ Object
This will create a series of select boxes that compromise a time object.
-
#delete_button(url, value = "Delete", form_options = {}, button_options = {}) ⇒ Object
Generates a button with a form around it and will set the request method to delete.
-
#file_field(name, *args) ⇒ Object
Examples: @user = User.new(:bio_file => “~/bio.doc”) <%= file_field :user, :bio_file %> # => <input id=“user_bio_field” name=“user” type=“file” value=“~/bio.doc” /> <%= file_field :i_dont_exist %> # => <input id=“i_dont_exist” name=“i_dont_exist” type=“file” value=“” />.
-
#form(action, options = {}) {|form_builder| ... } ⇒ Object
Examples: <% form(users_create_url) do -%> # form stuff here…
-
#form_authenticity_field ⇒ Object
Get the secret token to be added in an HTML form.
-
#hidden_field(name, *args) ⇒ Object
Examples: @user = User.new(:email => “[email protected]”) <%= hidden_field :user, :email %> # => <input id=“user_email” name=“user” type=“hidden” value=“[email protected]” /> <%= hidden_field :i_dont_exist %> # => <input id=“i_dont_exist” name=“i_dont_exist” type=“hidden” />.
-
#image_submit(src, options = {}) ⇒ Object
Examples: <%= image_submit “logo.png” %> # => <input src=“/images/logo.png” type=“image” />.
-
#label_tag(name, *args) ⇒ Object
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>.
-
#password_field(name, *args) ⇒ Object
Examples: @user = User.new(:email => “[email protected]”) <%= password_field :user, :email %> # => <input id=“user_email” name=“user” type=“password” value=“[email protected]” /> <%= password_field :i_dont_exist %> # => <input id=“i_dont_exist” name=“i_dont_exist” type=“password” />.
-
#radio_button(name, *args) ⇒ Object
Examples: @user = User.new(:level => 1) <%= radio_button :user, :level %> # => <input checked=“checked” id=“user_level” name=“user” type=“radio” value=“1” /> <%= radio_button :user, :level, :value => 2 %> # => <input id=“user_level” name=“user” type=“radio” value=“2” /> <%= radio_button :i_dont_exist %> # => <input id=“i_dont_exist” name=“i_dont_exist” type=“radio” value=“” />.
-
#select_tag(name, *args) ⇒ Object
Examples: @user = User.new(:level => 1) <%= select_tag :user, :level, :options => [[“one”, 1], [“two”, 2]] %> # => <select id=“user_level” name=“user”><option value=“1” selected>one</option><option value=“2” >two</option></select> <%= select_tag :user :level, :options => => 1, :two => 2 %> # => <select id=“user_level” name=“user”><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>.
-
#submit_button(value = "Submit", options = {}, *original_args) ⇒ Object
Examples: <%= submit_button %> # => <input type=“submit” value=“Submit” /> <%= submit_button “Login” %> # => <input type=“submit” value=“Login” /> You can disable the button after clicking it.
-
#text_area(name, *args) ⇒ Object
Examples: @user = User.new(:bio => “my bio here”) <%= text_area :user, :bio %> # => <textarea id=“user_bio” name=“user”>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>.
-
#text_field(name, *args) ⇒ Object
Examples: @user = User.new(:email => “[email protected]”) <%= text_field :user, :email %> # => <input id=“user_email” name=“user” type=“text” value=“[email protected]” /> <%= text_field :i_dont_exist %> # => <input id=“i_dont_exist” name=“i_dont_exist” type=“text” />.
Instance Method Details
#check_box(name, *args) ⇒ Object
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" />
112 113 114 115 116 117 118 119 |
# File 'lib/mack/view_helpers/form_helpers.rb', line 112 def check_box(name, *args) build_form_element(name, {:type => :checkbox}, *args) do |var, fe, | if [:value] .merge!(:checked => "checked") end .delete(:value) end end |
#date_select(name, *args) ⇒ Object
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 %>
99 100 101 102 |
# File 'lib/mack/view_helpers/date_time_helpers.rb', line 99 def date_select(name, *args) fe = FormElement.new(*args) date_time_select(name, fe.calling_method, {:hours => false, :minutes => false, :seconds => false}.merge(fe.)) end |
#date_time_select(name, *args) ⇒ Object
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 => ':'
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/mack/view_helpers/date_time_helpers.rb', line 43 def date_time_select(name, *args) var = instance_variable_get("@#{name}") fe = FormElement.new(*args) time = var if var.is_a?(Time) || var.is_a?(Date) time = var.nil? ? Time.now : (var.send(fe.calling_method) || Time.now) if time.nil? years = [] (time.year - 5).upto(time.year + 5) { |y| years << [y, y]} = {: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.) [:year, :month, :day, :hour, :minute, :second].each do |v| if ["#{v}_values".to_sym] ["#{v}_options".to_sym] = [] ["#{v}_values".to_sym].each {|i| ["#{v}_options".to_sym] << [i, i]} end end fe. - [: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] label = label_parameter_tag(name, (fe.calling_method == :to_s ? name : "#{name}_#{fe.calling_method}"), var, fe) date_boxes = [] [:date_order].collect! { |s| s.to_sym } date_boxes[[:date_order].index(:month)] = dt_select(:month, name, fe, time.month, [:month_options]) if [:months] date_boxes[[:date_order].index(:day)] = dt_select(:day, name, fe, time.day, [:day_options]) if [:days] date_boxes[[:date_order].index(:year)] = dt_select(:year, name, fe, time.year, [:year_options]) if [:years] date_boxes.compact! time_boxes = [] [:time_order].collect! { |s| s.to_sym } time_boxes[[:time_order].index(:hour)] = dt_select(:hour, name, fe, time.hour, [:hour_options]) if [:hours] time_boxes[[:time_order].index(:minute)] = dt_select(:minute, name, fe, time.min, [:minute_options]) if [:minutes] time_boxes[[:time_order].index(:second)] = dt_select(:second, name, fe, time.sec, [:second_options]) if [:seconds] time_boxes.compact! elts = [] elts[[:date_time_order].index(:date)] = date_boxes.join([:date_separator]) unless elts.empty? elts[[:date_time_order].index(:time)] = time_boxes.join([:time_separator]) end elts.compact! boxes = elts.join(" ").strip return label + boxes end |
#delete_button(url, value = "Delete", form_options = {}, button_options = {}) ⇒ Object
Generates a button with a form around it and will set the request method to delete.
55 56 57 58 59 60 |
# File 'lib/mack/view_helpers/form_helpers.rb', line 55 def (url, value = "Delete", = {}, = {}) t = "\n" << hidden_field(:_method, :value => :delete) t << "\n" << (value, ) t << "\n" content_tag(:form, {:action => url, :method => :post}.merge(), t) end |
#file_field(name, *args) ⇒ Object
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="" />
125 126 127 |
# File 'lib/mack/view_helpers/form_helpers.rb', line 125 def file_field(name, *args) build_form_element(name, {:type => :file}, *args) end |
#form(action, options = {}) {|form_builder| ... } ⇒ Object
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 -%>
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/mack/view_helpers/form_helpers.rb', line 31 def form(action, = {}, &block) = {:method => :post, :action => action}.merge() form_builder = .delete(:builder) || configatron.mack.default_form_builder.camelcase.constantize.new(Thread.current[:view_template]) if [:id] = {:class => [:id]}.merge() end if [:multipart] = {:enctype => "multipart/form-data"}.merge() .delete(:multipart) end meth = nil unless [:method] == :get || [:method] == :post meth = "<input name=\"_method\" type=\"hidden\" value=\"#{[:method]}\" />\n" [:method] = :post end concat("<form#{()}>\n", block.binding) concat(meth, block.binding) unless meth.blank? concat(form_authenticity_field, block.binding) unless configatron.mack.disable_forgery_detector yield form_builder concat("\n</form>", block.binding) # content_tag(:form, options, &block) end |
#form_authenticity_field ⇒ Object
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.
14 15 16 |
# File 'lib/mack/view_helpers/form_helpers.rb', line 14 def form_authenticity_field str = %{<input type="hidden" name="__authenticity_token" value="#{Mack::Utils::AuthenticityTokenDispenser.instance.dispense_token(request.session.id)}" />\n} end |
#hidden_field(name, *args) ⇒ Object
Examples:
@user = User.new(:email => "[email protected]")
<%= hidden_field :user, :email %> # => <input id="user_email" name="user[email]" type="hidden" value="[email protected]" />
<%= hidden_field :i_dont_exist %> # => <input id="i_dont_exist" name="i_dont_exist" type="hidden" />
133 134 135 |
# File 'lib/mack/view_helpers/form_helpers.rb', line 133 def hidden_field(name, *args) build_form_element(name, {:type => :hidden}, *args) end |
#image_submit(src, options = {}) ⇒ Object
Examples:
<%= image_submit "logo.png" %> # => <input src="/images/logo.png" type="image" />
139 140 141 |
# File 'lib/mack/view_helpers/form_helpers.rb', line 139 def image_submit(src, = {}) non_content_tag(:input, {:type => :image, :src => "/images/#{src}"}.merge()) end |
#label_tag(name, *args) ⇒ Object
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>
249 250 251 252 253 254 255 256 257 258 259 260 |
# File 'lib/mack/view_helpers/form_helpers.rb', line 249 def label_tag(name, *args) fe = FormElement.new(*args) unless fe.[:for] fe.[:for] = (fe.calling_method == :to_s ? name.to_s : "#{name}_#{fe.calling_method}") end unless fe.[:value] fe.[:value] = (fe.calling_method == :to_s ? name.to_s.humanize : fe.calling_method.to_s.humanize) end content = fe.[:value] fe..delete(:value) content_tag(:label, fe., content) end |
#password_field(name, *args) ⇒ Object
Examples:
@user = User.new(:email => "[email protected]")
<%= password_field :user, :email %> # => <input id="user_email" name="user[email]" type="password" value="[email protected]" />
<%= password_field :i_dont_exist %> # => <input id="i_dont_exist" name="i_dont_exist" type="password" />
223 224 225 |
# File 'lib/mack/view_helpers/form_helpers.rb', line 223 def password_field(name, *args) build_form_element(name, {:type => :password}, *args) end |
#radio_button(name, *args) ⇒ Object
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="" />
232 233 234 235 236 237 238 239 240 241 242 |
# File 'lib/mack/view_helpers/form_helpers.rb', line 232 def (name, *args) build_form_element(name, {:type => :radio, :value => ""}, *args) do |var, fe, | if fe.[:value] if fe.[:value] == [:value] .merge!(:checked => "checked") end elsif [:value] .merge!(:checked => "checked") end end end |
#select_tag(name, *args) ⇒ Object
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>
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/mack/view_helpers/form_helpers.rb', line 148 def select_tag(name, *args) var = instance_variable_get("@#{name}") fe = FormElement.new(*args) = {:name => name, :id => name} unless fe.calling_method == :to_s .merge!(:name => "#{name}[#{fe.calling_method}]", :id => "#{name}_#{fe.calling_method}") end content = "" opts = fe.[:options] unless opts.nil? sopts = opts if opts.is_a?(Array) elsif opts.is_a?(Hash) sopts = [] opts.sort.each do |k,v| sopts << [k, v] end else raise ArgumentError.new(":options must be either an Array of Arrays or a Hash!") end sel_value = var.send(fe.calling_method) if var sel_value = fe.[:selected] if fe.[:selected] sopts.each do |kv| selected = kv[1].to_s == sel_value.to_s ? "selected" : "" content << %{\n<option value="#{kv[1]}" #{selected}>#{kv[0]}</option>} end fe..delete(:selected) fe..delete(:options) end return label_parameter_tag(name, [:id], var, fe) + content_tag(:select, .merge(fe.), content) end |
#submit_button(value = "Submit", options = {}, *original_args) ⇒ Object
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;"
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/mack/view_helpers/form_helpers.rb', line 80 def (value = "Submit", = {}, *original_args) if [:confirm] onclick = "if (confirm('#{.delete(:confirm)}')) {submit();}; return false;" onclick << ";#{.delete(:onclick)}" if .has_key?(:onclick) [:onclick] = onclick end # processing the disable with option, which will be embebed in the onclick parameter. if disable_with = .delete(:disable_with) disable_with = "this.innerHTML='#{disable_with}'" # Making sure that we keep the content of the onclick option, should it exist. disable_with << ";#{.delete(:onclick)}" if .has_key?(:onclick) # Setting the onlick option. [:onclick] = [ "this.setAttribute('originalValue', this.innerHTML)", "this.disabled=true", disable_with, "result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit())", "if (result == false) { this.innerHTML = this.getAttribute('originalValue'); this.disabled = false }", "return result;", ].join(";") end # non_content_tag(:input, {:type => :submit, :value => value}.merge(options)) content_tag(:button, {:type => :submit}.merge(), value) end |
#text_area(name, *args) ⇒ Object
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>
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/mack/view_helpers/form_helpers.rb', line 188 def text_area(name, *args) var = instance_variable_get("@#{name}") fe = FormElement.new(*args) = {:name => name, :id => name, :cols => 60, :rows => 20} if var.nil? value = fe.[:value] fe..delete(:value) return label_parameter_tag(name, [:id], var, fe) + content_tag(:textarea, .merge(fe.), value) else unless fe.calling_method == :to_s .merge!(:name => "#{name}[#{fe.calling_method}]", :id => "#{name}_#{fe.calling_method}") end [:value] = var.send(fe.calling_method) yield var, fe, if block_given? content = [:value] .delete(:value) return label_parameter_tag(name, [:id], var, fe) + content_tag(:textarea, .merge(fe.), content) end end |
#text_field(name, *args) ⇒ Object
Examples:
@user = User.new(:email => "[email protected]")
<%= text_field :user, :email %> # => <input id="user_email" name="user[email]" type="text" value="[email protected]" />
<%= text_field :i_dont_exist %> # => <input id="i_dont_exist" name="i_dont_exist" type="text" />
215 216 217 |
# File 'lib/mack/view_helpers/form_helpers.rb', line 215 def text_field(name, *args) build_form_element(name, {:type => :text}, *args) end |