module ActionView::Helpers::FormHelper
def _object_for_form_builder(object) # :nodoc:
def _object_for_form_builder(object) # :nodoc: object.is_a?(Array) ? object.last : object end
def apply_form_for_options!(object, options) # :nodoc:
def apply_form_for_options!(object, options) # :nodoc: object = convert_to_model(object) as = options[:as] namespace = options[:namespace] action = object.respond_to?(:persisted?) && object.persisted? ? :edit : :new options[:html] ||= {} options[:html].reverse_merge!( class: as ? "#{action}_#{as}" : dom_class(object, action), id: (as ? [namespace, action, as] : [namespace, dom_id(object, action)]).compact.join("_").presence, ) end
def check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0")
# =>
check_box("eula", "accepted", { class: 'eula_check' }, "yes", "no")
#
# =>
check_box("puppy", "gooddog", {}, "yes", "no")
# Let's say that @puppy.gooddog is "no":
#
# =>
check_box("post", "validated")
# Let's say that @post.validated? is 1:
==== Examples
hashes instead of arrays.
In that case it is preferable to either use +check_box_tag+ or to use
get an extra ghost item with only that attribute, assigned to "0".
the elements of the array. For each item with a checked check box you
because parameter name repetition is precisely what Rails seeks to distinguish
<% end %>
...
<%= form.check_box :paid %>
<%= fields_for "project[invoice_attributes][]", invoice, index: nil do |form| %>
within an array-like parameter, as in
Unfortunately that workaround does not work when the check box goes
key in the query string, that works for ordinary forms.
form, and parameters extraction gets the last occurrence of any repeated
says key/value pairs have to be sent in the same order they appear in the
the check box is unchecked), or both fields. Since the HTML specification
This way, the client either sends only the hidden field (representing
attributes mimic an unchecked check box.
every check box. The hidden field has the same name and its
To prevent this the helper generates an auxiliary hidden field before
wouldn't update the flag.
@invoice.update(params[:invoice])
any mass-assignment idiom like
invoice the user unchecks its check box, no +paid+ parameter is sent. So,
if an +Invoice+ model has a +paid+ flag, and in the form that edits a paid
thus web browsers do not send them. Unfortunately this introduces a gotcha:
The HTML specification says unchecked check boxes are not successful, and
==== Gotcha
* :include_hidden - If set to false, the auxiliary hidden field described below will not be generated.
* :checked - +true+ or +false+ forces the state of the checkbox to be checked or not.
* Any standard HTML attributes for the tag can be passed in, for example +:class+.
==== Options
while the default +unchecked_value+ is set to 0 which is convenient for boolean values.
Additional options on the input tag can be passed as a hash with +options+. The +checked_value+ defaults to 1
It's intended that +method+ returns an integer and if that integer is above zero, then the checkbox is checked.
assigned to the template (identified by +object+). This object must be an instance object (@object) and not a local object.
Returns a checkbox tag tailored for accessing a specified attribute (identified by +method+) on an object
def check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0") Tags::CheckBox.new(object_name, method, self, checked_value, unchecked_value, options).render end
def color_field(object_name, method, options = {})
color_field("car", "color")
Returns a text_field of type "color".
def color_field(object_name, method, options = {}) Tags::ColorField.new(object_name, method, self, options).render end
def date_field(object_name, method, options = {})
# =>
date_field("user", "born_on", min: "2014-05-20")
values for "min" and "max."
Alternatively, you can pass a String formatted as an ISO8601 date as the
# =>
date_field("user", "born_on", min: Date.today)
instances of Date or Time to the options hash.
You can create values for the "min" and "max" attributes by passing
# =>
date_field("user", "born_on", value: "1984-05-12")
@user.born_on = Date.new(1984, 1, 27)
by passing the "value" option explicitly, e.g.
of DateTime and ActiveSupport::TimeWithZone. You can still override that
on the object's value, which makes it behave as expected for instances
The default value is generated by trying to call +strftime+ with "%Y-%m-%d"
# =>
date_field("user", "born_on")
Returns a text_field of type "date".
def date_field(object_name, method, options = {}) Tags::DateField.new(object_name, method, self, options).render end
def datetime_field(object_name, method, options = {})
# =>
datetime_field("user", "born_on", min: "2014-05-20T00:00:00")
the values for "min" and "max."
Alternatively, you can pass a String formatted as an ISO8601 datetime as
# =>
datetime_field("user", "born_on", min: Date.today)
instances of Date or Time to the options hash.
You can create values for the "min" and "max" attributes by passing
# =>
datetime_field("user", "born_on")
@user.born_on = Date.new(1984, 1, 12)
of DateTime and ActiveSupport::TimeWithZone.
on the object's value, which makes it behave as expected for instances
The default value is generated by trying to call +strftime+ with "%Y-%m-%dT%T"
# =>
datetime_field("user", "born_on")
Returns a text_field of type "datetime-local".
def datetime_field(object_name, method, options = {}) Tags::DatetimeLocalField.new(object_name, method, self, options).render end
def default_form_builder_class
def default_form_builder_class builder = default_form_builder || ActionView::Base.default_form_builder builder.respond_to?(:constantize) ? builder.constantize : builder end
def email_field(object_name, method, options = {})
# =>
email_field("user", "address")
Returns a text_field of type "email".
def email_field(object_name, method, options = {}) Tags::EmailField.new(object_name, method, self, options).render end
def fields(scope = nil, model: nil, **options, &block)
to work with an object as a base, like
Same goes for the methods in FormOptionsHelper and DateHelper designed
<% end %>
<%= check_box_tag "comment[all_caps]", "1", @comment.commenter.hulk_mode? %>
<%= text_area :commenter, :biography %>
<%= fields.text_field :body %>
<%= fields model: @comment do |fields| %>
from FormTagHelper:
match the stand-alone FormHelper methods and methods
While +form_with+ uses a FormBuilder object it's possible to mix and
=== Mixing with other form helpers
either the passed scope or the scope inferred from the :model.
or model is yielded, so any generated field names are prefixed with
Much like +form_with+ a FormBuilder instance associated with the scope
<% end %>
<% end %>
<%= fields.text_field :body %>
<%= form.fields :comment do |fields| %>
<%= form.text_field :title %>
<%= form_with model: @post do |form| %>
# Using +fields+ with +form_with+:
# =>
<% end %>
<%= fields.text_field :body %>
<%= fields model: Comment.new(body: "full bodied") do |fields| %>
# Using a model infers the scope and assigns field values:
# =>
<% end %>
<%= fields.text_field :body %>
<%= fields :comment do |fields| %>
# Using a scope prefixes the input field names:
except it doesn't output the form tags.
Like +form_with+ does with :scope or :model,
Scopes input fields with either an explicit scope or model.
def fields(scope = nil, model: nil, **options, &block) options = { allow_method_names_outside_object: true, skip_default_ids: !form_with_generates_ids }.merge!(options) if model model = _object_for_form_builder(model) scope ||= model_name_from_record_or_class(model).param_key end builder = instantiate_builder(scope, model, options) capture(builder, &block) end
def fields_for(record_name, record_object = nil, options = {}, &block)
can pass include_id: false to prevent fields_for from
There are circumstances where this hidden field is not needed and you
to store the ID of the record if it responds to persisted?.
Note that fields_for will automatically generate a hidden field
<% end %>
...
<% end %>
...
Project #<%= project_fields.index %>
<%= person_form.fields_for :projects do |project_fields| %>
...
<%= form_for @person do |person_form| %>
is available in the FormBuilder object.
object into the array. For this purpose, the index method
When a collection is used you might want to know the index of each
<% end %>
...
<% end %>
Delete: <%= project_fields.check_box :_destroy %>
<%= person_form.fields_for :projects do |project_fields| %>
...
<%= form_for @person do |person_form| %>
(e.g. 1, '1', true, or 'true'):
parameter with a value that evaluates to +true+
attributes hash by adding a form element for the _destroy
This will allow you to specify which models to destroy in the
end
accepts_nested_attributes_for :projects, allow_destroy: true
has_many :projects
class Person < ActiveRecord::Base
option for +accepts_nested_attributes_for+:
form, you have to enable it first using the :allow_destroy
If you want to destroy any of the associated models through the
<% end %>
...
<% end %>
Name: <%= project_fields.text_field :name %>
<%= person_form.fields_for :projects, @active_projects do |project_fields| %>
...
<%= form_for @person do |person_form| %>
Or a collection to be used:
<% end %>
...
<% end %>
<% end %>
<% end %>
Name: <%= project_fields.text_field :name %>
<%= person_form.fields_for :projects, project do |project_fields| %>
<% if project.active? %>
<% @person.projects.each do |project| %>
...
<%= form_for @person do |person_form| %>
It's also possible to specify the instance to be used:
<% end %>
...
<% end %>
<% end %>
Name: <%= project_fields.text_field :name %>
<% if project_fields.object.active? %>
<%= person_form.fields_for :projects do |project_fields| %>
...
<%= form_for @person do |person_form| %>
collection:
the nested fields_for call will be repeated for each instance in the
This model can now be used with a nested fields_for. The block given to
end
accepts_nested_attributes_for :projects
has_many :projects
class Person < ActiveRecord::Base
+accepts_nested_attributes_for+ to define the writer method for you:
When projects is already an association on Person you can use
collection, and the correct indices to be set in the form markup.
required for fields_for to correctly identify :projects as a
Note that the projects_attributes= writer method is in fact
end
end
# Process the attributes hash
def projects_attributes=(attributes)
end
[@project1, @project2]
def projects
class Person
projects_attributes= writer method:
from the projects reader method and responds to the
Consider a Person class which returns an _array_ of Project instances
==== One-to-many
<% end %>
...
<% end %>
Delete: <%= address_fields.check_box :_destroy %>
...
<%= person_form.fields_for :address do |address_fields| %>
...
<%= form_for @person do |person_form| %>
model (e.g. 1, '1', true, or 'true'):
with a value that evaluates to +true+, you will destroy the associated
Now, when you use a form element with the _destroy parameter,
end
accepts_nested_attributes_for :address, allow_destroy: true
has_one :address
class Person < ActiveRecord::Base
+accepts_nested_attributes_for+:
to enable it first using the :allow_destroy option for
If you want to destroy the associated model through the form, you have
end
accepts_nested_attributes_for :address
has_one :address
class Person < ActiveRecord::Base
+accepts_nested_attributes_for+ to define the writer method for you:
When address is already an association on a Person you can use
<% end %>
...
<% end %>
Zip code: <%= address_fields.text_field :zip_code %>
Street : <%= address_fields.text_field :street %>
<%= person_form.fields_for :address do |address_fields| %>
...
<%= form_for @person do |person_form| %>
This model can now be used with a nested fields_for, like so:
end
end
# Process the attributes hash
def address_attributes=(attributes)
end
@address
def address
class Person
address_attributes= writer method:
address reader method and responds to the
Consider a Person class which returns a _single_ Address from the
==== One-to-one
or an _array_ of objects.
depends on whether the normal reader method returns a _single_ object
Whether a one-to-one or one-to-many style form builder will be yielded
address_attributes=.
writer for the association :address is called
defining a method with the proper name. For example: the attribute
with +accepts_nested_attributes_for+ in a model definition or by
association. The most common way of defining these writers is either
Nested attribute writers are normal setter methods named after an
the attributes of a parent object and its associations in one go.
for that attribute. This allows you to create forms that set or change
writer for a certain attribute, fields_for will yield a new scope
When the object belonging to the current scope has a nested attribute
=== Nested Attributes Examples
FormOptionsHelper#collection_select and DateHelper#datetime_select.
DateHelper that are designed to work with an object as base, like
Note: This also works for the methods in FormOptionsHelper and
of class +Permission+, the field will still be named permission[admin].
_class_ of the model object, e.g. if @person.permission, is
and +fields_for+ will derive the required name of the field from the
<% end %>
Admin?: <%= permission_fields.check_box :admin %>
<%= fields_for @person.permission do |permission_fields| %>
name has been omitted) -
argument isn't a string or symbol +fields_for+ will realize that the
Alternatively, you can pass just the model object itself (if the first
field will reflect the value of that variable's attribute @permission.admin.
instance variable @permission, the initial state of the input
...in which case, if :permission also happens to be the name of an
<% end %>
Admin?: <%= permission_fields.check_box :admin %>
<%= fields_for :permission do |permission_fields| %>
object to +fields_for+ -
Often this can be simplified by passing just the name of the model
reflect the value of @person.permission.admin.
+admin+, the initial state of the checkbox when first displayed will
If @person.permission is an existing record with an attribute
value will appear in the controller as params[:permission][:admin].
tag with the +name+ attribute permission[admin], and the submitted
In this case, the checkbox field will be represented by an HTML +input+
<% end %>
<%= person_form.submit %>
<% end %>
Admin? : <%= permission_fields.check_box :admin %>
<%= fields_for :permission, @person.permission do |permission_fields| %>
Last name : <%= person_form.text_field :last_name %>
First name: <%= person_form.text_field :first_name %>
<%= form_for @person do |person_form| %>
object itself can be passed to the method separately -
both an object name (represented by either a symbol or string) and the
displayed. In order for both of these features to be specified independently,
default values are shown when the form the fields appear in is first
values appear within the +params+ hash in the controller) and what
a model object in two ways - how they are named (hence how submitted
generate fields associated with the model object. Fields may reflect
and within the block allows methods to be called on the builder to
a FormBuilder object associated with a particular model object to a block,
its method signature is slightly different. Like +form_for+, it yields
Although the usage and purpose of +fields_for+ is similar to +form_for+'s,
for specifying additional model objects in the same form.
doesn't create the form tags themselves. This makes fields_for suitable
Creates a scope around a specific model object like form_for, but
def fields_for(record_name, record_object = nil, options = {}, &block) options = { model: record_object, allow_method_names_outside_object: false, skip_default_ids: false }.merge!(options) fields(record_name, **options, &block) end
def file_field(object_name, method, options = {})
file_field(:attachment, :file, class: 'file_input')
# =>
file_field(:post, :image, accept: 'image/png,image/gif,image/jpeg')
# =>
file_field(:post, :attached, accept: 'text/html')
# =>
file_field(:post, :image, multiple: true)
# =>
file_field(:user, :avatar)
==== Examples
* :accept - If set to one or multiple mime-types, the user will be suggested a filter when choosing a file. You still need to set up model validations.
* :include_hidden - When multiple: true and include_hidden: true, the field will be prefixed with an field with an empty value to support submitting an empty collection of files.
* :multiple - If set to true, *in most updated browsers* the user will be allowed to select multiple files.
* :disabled - If set to true, the user will not be able to use this input.
* Creates standard HTML attributes for the tag.
==== Options
Using this method inside a +form_for+ block will set the enclosing form's encoding to multipart/form-data.
shown.
hash with +options+. These options will be tagged onto the HTML as an HTML element attribute as in the example
assigned to the template (identified by +object+). Additional options on the input tag can be passed as a
Returns a file upload input tag tailored for accessing a specified attribute (identified by +method+) on an object
def file_field(object_name, method, options = {}) options = { include_hidden: multiple_file_field_include_hidden }.merge!(options) Tags::FileField.new(object_name, method, self, convert_direct_upload_option_to_url(options.dup)).render end
def form_for(record, options = {}, &block)
...
<%= form_for @invoice, url: external_url, authenticity_token: false do |f| %>
If you don't want to an authenticity token field be rendered at all just pass false:
<% end %>
...
<%= form_for @invoice, url: external_url, authenticity_token: 'external_token' do |f| %>
To set an authenticity token you need to pass an :authenticity_token parameter
without it, for example when you submit data to a payment gateway number and types of fields could be limited.
When you build forms to external resources sometimes you need to set an authenticity token or just render a form
=== Form to external resources
FormTagHelper#form_tag.
If you don't need to attach a form to a model instance, then check out
end
form_for(record_or_name_or_array, *(args << options.merge(builder: LabellingFormBuilder)), &block)
options = args.extract_options!
def labelled_form_for(record_or_name_or_array, *args, &block)
could do something like the following:
In many cases you will want to wrap the above in another helper, so you
of a nested fields_for call, unless it's explicitly set.
The custom FormBuilder class is automatically merged with the options
labelling_form.
variable referencing the form builder is called
The rendered template is people/_labelling_form and the local
<%= render f %>
In this case, if you use this:
<% end %>
<%= f.submit %>
<%= f.check_box :admin %>
<%= f.text_area :biography %>
<%= f.text_field :last_name %>
<%= f.text_field :first_name %>
<%= form_for @person, url: { action: "create" }, builder: LabellingFormBuilder do |f| %>
automatically add labels to form inputs.
custom builder. For example, let's say you made a helper to
FormBuilder and override or define some more helpers, then use your
You can also build forms using a customized FormBuilder class. Subclass
=== Customized form builders
<% end %>
<% end %>
...
<%= f.fields_for(:comments, include_id: false) do |cf| %>
<%= form_for(@post) do |f| %>
Example:
thus there is no primary key for comments.
In the following example the Post model has many Comments stored within it in a NoSQL database,
to disable the hidden id.
Some ORM systems do not use IDs on nested models so in this case you want to be able
This is used to maintain the correlation between the form data and its associated model.
The form_for method automatically includes the model id as a hidden field in the form.
=== Removing hidden model id's
...
...
def form_for(record, options = {}, &block) raise ArgumentError, "Missing block" unless block_given? case record when String, Symbol model = nil object_name = record else model = convert_to_model(record) object = _object_for_form_builder(record) raise ArgumentError, "First argument in form cannot contain nil or be empty" unless object object_name = options[:as] || model_name_from_record_or_class(object).param_key apply_form_for_options!(object, options) end remote = options.delete(:remote) if remote && !embed_authenticity_token_in_remote_forms && options[:authenticity_token].blank? options[:authenticity_token] = false end options[:model] = model options[:scope] = object_name options[:local] = !remote options[:skip_default_ids] = false options[:allow_method_names_outside_object] = options.fetch(:allow_method_names_outside_object, false) form_with(**options, &block) end
def form_with(model: nil, scope: nil, url: nil, format: nil, **options, &block)
form_with(**options.merge(builder: LabellingFormBuilder), &block)
def labelled_form_with(**options, &block)
could do something like the following:
In many cases you will want to wrap the above in another helper, so you
of a nested +fields+ call, unless it's explicitly set.
The custom FormBuilder class is automatically merged with the options
labelling_form.
variable referencing the form builder is called
The rendered template is people/_labelling_form and the local
<%= render form %>
In this case, if you use:
<% end %>
<%= form.submit %>
<%= form.check_box :admin %>
<%= form.text_area :biography %>
<%= form.text_field :last_name %>
<%= form.text_field :first_name %>
<%= form_with model: @person, url: { action: "create" }, builder: LabellingFormBuilder do |form| %>
automatically add labels to form inputs.
custom builder. For example, let's say you made a helper to
FormBuilder and override or define some more helpers, then use your
You can also build forms using a customized FormBuilder class. Subclass
=== Customized form builders
<% end %>
<% end %>
...
<%= form.fields(:comments, skip_id: true) do |fields| %>
<%= form_with(model: @post) do |form| %>
thus there is no primary key for comments.
In the following example the Post model has many Comments stored within it in a NoSQL database,
to disable the hidden id.
Some ORM systems do not use IDs on nested models so in this case you want to be able
This is used to maintain the correlation between the form data and its associated model.
The +form_with+ method automatically includes the model id as a hidden field in the form.
=== Removing hidden model id's
...
def form_with(model: nil, scope: nil, url: nil, format: nil, **options, &block) options = { allow_method_names_outside_object: true, skip_default_ids: !form_with_generates_ids }.merge!(options) if model if url != false url ||= polymorphic_path(model, format: format) end model = _object_for_form_builder(model) scope ||= model_name_from_record_or_class(model).param_key end if block_given? builder = instantiate_builder(scope, model, options) output = capture(builder, &block) options[:multipart] ||= builder.multipart? html_options = html_options_for_form_with(url, model, **options) form_tag_with_body(html_options, output) else html_options = html_options_for_form_with(url, model, **options) form_tag_html(html_options) end end
def hidden_field(object_name, method, options = {})
hidden_field(:user, :token)
# =>
hidden_field(:post, :tag_list)
# =>
hidden_field(:signup, :pass_confirm)
==== Examples
shown.
hash with +options+. These options will be tagged onto the HTML as an HTML element attribute as in the example
assigned to the template (identified by +object+). Additional options on the input tag can be passed as a
Returns a hidden input tag tailored for accessing a specified attribute (identified by +method+) on an object
def hidden_field(object_name, method, options = {}) Tags::HiddenField.new(object_name, method, self, options).render end
def html_options_for_form_with(url_for_options = nil, model = nil, html: {}, local: !form_with_generates_remote_forms,
def html_options_for_form_with(url_for_options = nil, model = nil, html: {}, local: !form_with_generates_remote_forms, skip_enforcing_utf8: nil, **options) html_options = options.slice(:id, :class, :multipart, :method, :data, :authenticity_token).merge!(html) html_options[:remote] = html.delete(:remote) || !local html_options[:method] ||= :patch if model.respond_to?(:persisted?) && model.persisted? if skip_enforcing_utf8.nil? if options.key?(:enforce_utf8) html_options[:enforce_utf8] = options[:enforce_utf8] end else html_options[:enforce_utf8] = !skip_enforcing_utf8 end html_options_for_form(url_for_options.nil? ? {} : url_for_options, html_options) end
def instantiate_builder(record_name, record_object, options)
def instantiate_builder(record_name, record_object, options) case record_name when String, Symbol object = record_object object_name = record_name else object = record_name object_name = model_name_from_record_or_class(object).param_key if object end builder = options[:builder] || default_form_builder_class builder.new(object_name, object, self, options) end
def label(object_name, method, content_or_options = nil, options = nil, &block)
end
raw('Accept Terms.')
label(:post, :terms) do
# =>
end
content_tag(:span, builder.translation, class: "cost_label")
label(:post, :cost) do |builder|
# =>
end
content_tag(:span, translation, class: "cost_label")
label(:post, :cost) do |translation|
# =>
label(:post, :privacy, "Public Post", value: "public")
# =>
label(:post, :title, "A short title", class: "title_label")
# =>
label(:post, :title, "A short title")
# =>
label(:post, :cost)
cost: "Total cost"
post:
attributes:
activerecord:
(if you are using ActiveRecord):
Localization can also be based purely on the translation of the attribute-name
# =>
label(:post, :body)
Which then will result in
body: "Write your entire text here"
post:
label:
helpers:
For example you can define the following in your locale (e.g. en.yml)
You can localize your labels based on model and attribute names.
# =>
label(:post, :title)
==== Examples
target labels for radio_button tags (where the value is used in the ID of the input tag).
onto the HTML as an HTML element attribute as in the example shown, except for the :value option, which is designed to
Additional options on the label tag can be passed as a hash with +options+. These options will be tagged
is found in the current I18n locale (through helpers.label.
assigned to the template (identified by +object+). The text of label will default to the attribute name unless a translation
Returns a label tag tailored for labelling an input field for a specified attribute (identified by +method+) on an object
def label(object_name, method, content_or_options = nil, options = nil, &block) Tags::Label.new(object_name, method, self, content_or_options, options).render(&block) end
def month_field(object_name, method, options = {})
# =>
month_field("user", "born_on")
@user.born_on = Date.new(1984, 1, 27)
of DateTime and ActiveSupport::TimeWithZone.
on the object's value, which makes it behave as expected for instances
The default value is generated by trying to call +strftime+ with "%Y-%m"
# =>
month_field("user", "born_on")
Returns a text_field of type "month".
def month_field(object_name, method, options = {}) Tags::MonthField.new(object_name, method, self, options).render end
def number_field(object_name, method, options = {})
==== Options
Returns an input tag of type "number".
def number_field(object_name, method, options = {}) Tags::NumberField.new(object_name, method, self, options).render end
def password_field(object_name, method, options = {})
password_field(:account, :pin, size: 20, class: 'form_input')
# =>
password_field(:user, :password, onchange: "if ($('#user_password').val().length > 30) { alert('Your password needs to be shorter!'); }")
# =>
password_field(:account, :secret, class: "form_input", value: @account.secret)
# =>
password_field(:login, :pass, size: 20)
==== Examples
shown. For security reasons this field is blank by default; pass in a value via +options+ if this is not desired.
hash with +options+. These options will be tagged onto the HTML as an HTML element attribute as in the example
assigned to the template (identified by +object+). Additional options on the input tag can be passed as a
Returns an input tag of the "password" type tailored for accessing a specified attribute (identified by +method+) on an object
def password_field(object_name, method, options = {}) Tags::PasswordField.new(object_name, method, self, options).render end
def radio_button(object_name, method, tag_value, options = {})
# =>
radio_button("user", "receive_newsletter", "no")
radio_button("user", "receive_newsletter", "yes")
# Let's say that @user.receive_newsletter returns "no":
#
# =>
radio_button("post", "category", "java")
radio_button("post", "category", "rails")
# Let's say that @post.category returns "rails":
+options+ hash. You may pass HTML options there as well.
To force the radio button to be checked pass checked: true in the
radio button will be checked.
assigned to the template (identified by +object+). If the current value of +method+ is +tag_value+ the
Returns a radio button tag for accessing a specified attribute (identified by +method+) on an object
def radio_button(object_name, method, tag_value, options = {}) Tags::RadioButton.new(object_name, method, self, tag_value, options).render end
def range_field(object_name, method, options = {})
==== Options
Returns an input tag of type "range".
def range_field(object_name, method, options = {}) Tags::RangeField.new(object_name, method, self, options).render end
def search_field(object_name, method, options = {})
search_field(:user, :name, autosave: true, onsearch: true)
# =>
search_field(:user, :name, autosave: false, onsearch: true)
# =>
search_field(:user, :name, onsearch: true)
# =>
search_field(:user, :name, autosave: true)
# Assume request.host returns "www.example.com"
# =>
search_field(:user, :name, results: 3)
# =>
search_field(:user, :name, autosave: false)
# =>
search_field(:user, :name)
some browsers.
assigned to the template (identified by +object_name+). Inputs of type "search" may be styled differently by
Returns an input of type "search" for accessing a specified attribute (identified by +method+) on an object
def search_field(object_name, method, options = {}) Tags::SearchField.new(object_name, method, self, options).render end
def telephone_field(object_name, method, options = {})
# =>
telephone_field("user", "phone")
Returns a text_field of type "tel".
def telephone_field(object_name, method, options = {}) Tags::TelField.new(object_name, method, self, options).render end
def text_area(object_name, method, options = {})
# #{@entry.body}
# =>
# #{@application.notes}
# =>
# #{@comment.text}
# =>
# #{@post.body}
# =>
def text_area(object_name, method, options = {}) Tags::TextArea.new(object_name, method, self, options).render end
def text_field(object_name, method, options = {})
text_field(:snippet, :code, size: 20, class: 'code_input')
# =>
text_field(:session, :user, onchange: "if ($('#session_user').val() === 'admin') { alert('Your login cannot be admin!'); }")
# =>
text_field(:post, :title, maxlength: 30, class: "title_input")
# =>
text_field(:post, :title, class: "create_input")
# =>
text_field(:post, :title, size: 20)
==== Examples
shown.
hash with +options+. These options will be tagged onto the HTML as an HTML element attribute as in the example
assigned to the template (identified by +object+). Additional options on the input tag can be passed as a
Returns an input tag of the "text" type tailored for accessing a specified attribute (identified by +method+) on an object
def text_field(object_name, method, options = {}) Tags::TextField.new(object_name, method, self, options).render end
def time_field(object_name, method, options = {})
time_field("task", "started_at", value: Time.now, include_seconds: false)
if you exclude seconds in the timestamp format.
and minute by passing include_seconds: false. Some browsers will render a simpler UI
By default, provided times will be formatted including seconds. You can render just the hour
# =>
time_field("task", "started_at", min: "01:00:00")
values for "min" and "max."
Alternatively, you can pass a String formatted as an ISO8601 time as the
# =>
time_field("task", "started_at", min: Time.now)
instances of Date or Time to the options hash.
You can create values for the "min" and "max" attributes by passing
# =>
time_field("task", "started_at")
==== Examples
Supports the same options as FormTagHelper#time_field_tag.
==== Options
It is also possible to override this by passing the "value" option.
formatted by trying to call +strftime+ with "%H:%M" on the object's value.
on the object's value. If you pass include_seconds: false, it will be
The default value is generated by trying to call +strftime+ with "%T.%L"
Returns a text_field of type "time".
def time_field(object_name, method, options = {}) Tags::TimeField.new(object_name, method, self, options).render end
def url_field(object_name, method, options = {})
# =>
url_field("user", "homepage")
Returns a text_field of type "url".
def url_field(object_name, method, options = {}) Tags::UrlField.new(object_name, method, self, options).render end
def week_field(object_name, method, options = {})
# =>
week_field("user", "born_on")
@user.born_on = Date.new(1984, 5, 12)
of DateTime and ActiveSupport::TimeWithZone.
on the object's value, which makes it behave as expected for instances
The default value is generated by trying to call +strftime+ with "%Y-W%W"
# =>
week_field("user", "born_on")
Returns a text_field of type "week".
def week_field(object_name, method, options = {}) Tags::WeekField.new(object_name, method, self, options).render end