Class | Formtastic::SemanticFormBuilder |
In: |
lib/formtastic.rb
|
Parent: | ActionView::Helpers::FormBuilder |
RESERVED_COLUMNS | = | [:created_at, :updated_at, :created_on, :updated_on, :lock_version, :version] |
INLINE_ERROR_TYPES | = | [:sentence, :list, :first] |
inline_errors_for | -> | errors_on |
template | [RW] |
Creates a submit input tag with the value "Save [model name]" (for existing records) or "Create [model name]" (for new records) by default:
<%= form.commit_button %> => <input name="commit" type="submit" value="Save Post" />
The value of the button text can be overridden:
<%= form.commit_button "Go" %> => <input name="commit" type="submit" value="Go" class="{create|update|submit}" /> <%= form.commit_button :label => "Go" %> => <input name="commit" type="submit" value="Go" class="{create|update|submit}" />
And you can pass html atributes down to the input, with or without the button text:
<%= form.commit_button :button_html => { :class => "pretty" } %> => <input name="commit" type="submit" value="Save Post" class="pretty {create|update|submit}" />
Returns a suitable form input for the given method, using the database column information and other factors (like the method name) to figure out what you probably want.
Options:
Input Types:
Most inputs map directly to one of ActiveRecord‘s column types by default (eg string_input), but there are a few special cases and some simplification (:integer, :float and :decimal columns all map to a single numeric_input, for example).
Example:
<% semantic_form_for @employee do |form| %> <% form.inputs do -%> <%= form.input :name, :label => "Full Name" %> <%= form.input :manager, :as => :radio %> <%= form.input :secret, :as => :password, :input_html => { :value => "xxxx" } %> <%= form.input :hired_at, :as => :date, :label => "Date Hired" %> <%= form.input :phone, :required => false, :hint => "Eg: +1 555 1234" %> <%= form.input :email %> <%= form.input :website, :as => :url, :hint => "You may wish to omit the http://" %> <% end %> <% end %>
Creates an input fieldset and ol tag wrapping for use around a set of inputs. It can be called either with a block (in which you can do the usual Rails form stuff, HTML, ERB, etc), or with a list of fields. These two examples are functionally equivalent:
# With a block: <% semantic_form_for @post do |form| %> <% form.inputs do %> <%= form.input :title %> <%= form.input :body %> <% end %> <% end %> # With a list of fields: <% semantic_form_for @post do |form| %> <%= form.inputs :title, :body %> <% end %> # Output: <form ...> <fieldset class="inputs"> <ol> <li class="string">...</li> <li class="text">...</li> </ol> </fieldset> </form>
When called without a block or a field list, an input is rendered for each column in the model‘s database table, just like Rails’ scaffolding. You‘ll obviously want more control than this in a production application, but it‘s a great way to get started, then come back later to customise the form with a field list or a block of inputs. Example:
<% semantic_form_for @post do |form| %> <%= form.inputs %> <% end %> With a few arguments: <% semantic_form_for @post do |form| %> <%= form.inputs "Post details", :title, :body %> <% end %>
All options (with the exception of :name/:title) are passed down to the fieldset as HTML attributes (id, class, style, etc). If provided, the :name/:title option is passed into a legend tag inside the fieldset.
# With a block: <% semantic_form_for @post do |form| %> <% form.inputs :name => "Create a new post", :style => "border:1px;" do %> ... <% end %> <% end %> # With a list (the options must come after the field list): <% semantic_form_for @post do |form| %> <%= form.inputs :title, :body, :name => "Create a new post", :style => "border:1px;" %> <% end %> # ...or the equivalent: <% semantic_form_for @post do |form| %> <%= form.inputs "Create a new post", :title, :body, :style => "border:1px;" %> <% end %>
Instead of hard-coding fieldsets & legends into your form to logically group related fields, use inputs:
<% semantic_form_for @post do |f| %> <% f.inputs do %> <%= f.input :title %> <%= f.input :body %> <% end %> <% f.inputs :name => "Advanced", :id => "advanced" do %> <%= f.input :created_at %> <%= f.input :user_id, :label => "Author" %> <% end %> <% f.inputs "Extra" do %> <%= f.input :update_at %> <% end %> <% end %> # Output: <form ...> <fieldset class="inputs"> <ol> <li class="string">...</li> <li class="text">...</li> </ol> </fieldset> <fieldset class="inputs" id="advanced"> <legend><span>Advanced</span></legend> <ol> <li class="datetime">...</li> <li class="select">...</li> </ol> </fieldset> <fieldset class="inputs"> <legend><span>Extra</span></legend> <ol> <li class="datetime">...</li> </ol> </fieldset> </form>
As in Rails, you can use semantic_fields_for to nest attributes:
<% semantic_form_for @post do |form| %> <%= form.inputs :title, :body %> <% form.semantic_fields_for :author, @bob do |author_form| %> <% author_form.inputs do %> <%= author_form.input :first_name, :required => false %> <%= author_form.input :last_name %> <% end %> <% end %> <% end %>
But this does not look formtastic! This is equivalent:
<% semantic_form_for @post do |form| %> <%= form.inputs :title, :body %> <% form.inputs :for => [ :author, @bob ] do |author_form| %> <%= author_form.input :first_name, :required => false %> <%= author_form.input :last_name %> <% end %> <% end %>
And if you don‘t need to give options to your input call, you could do it in just one line:
<% semantic_form_for @post do |form| %> <%= form.inputs :title, :body %> <%= form.inputs :first_name, :last_name, :for => @bob %> <% end %>
Just remember that calling inputs generates a new fieldset to wrap your inputs. If you have two separate models, but, semantically, on the page they are part of the same fieldset, you should use semantic_fields_for instead (just as you would do with Rails’ form builder).
Generates the label for the input. It also accepts the same arguments as Rails label method. It has three options that are not supported by Rails label method:
is false, a blank string is returned.
to call f.label :authors but it should match :author_ids.
f.label :title # like in rails, except that it searches the label on I18n API too f.label :title, "Your post title" f.label :title, :label => "Your post title" # Added for formtastic API f.label :title, :required => true # Returns <label>Title<abbr title="required">*</abbr></label>
Generates error messages for given method names and for base. You can pass a hash with html options that will be added to ul tag
f.semantic_errors # This will show only errors on base f.semantic_errors :state # This will show errors on base and state f.semantic_errors :state, :class => "awesome" # errors will be rendered in ul.awesome
A thin wrapper around fields_for to set :builder => Formtastic::SemanticFormBuilder for nesting forms:
# Example: <% semantic_form_for @post do |post| %> <% post.semantic_fields_for :author do |author| %> <% author.inputs :name %> <% end %> <% end %> # Output: <form ...> <fieldset class="inputs"> <ol> <li class="string"><input type='text' name='post[author][name]' id='post_author_name' /></li> </ol> </fieldset> </form>
Outputs a fieldset containing a legend for the label text, and an ordered list (ol) of list items, one for each possible choice in the belongs_to association. Each li contains a label and a check_box input.
This is an alternative for has many and has and belongs to many associations.
Example:
f.input :author, :as => :check_boxes
Output:
<fieldset> <legend class="label"><label>Authors</label></legend> <ol> <li> <input type="hidden" name="book[author_id][1]" value=""> <label for="book_author_id_1"><input id="book_author_id_1" name="book[author_id][1]" type="checkbox" value="1" /> Justin French</label> </li> <li> <input type="hidden" name="book[author_id][2]" value=""> <label for="book_author_id_2"><input id="book_author_id_2" name="book[owner_id][2]" type="checkbox" value="2" /> Kate French</label> </li> </ol> </fieldset>
Notice that the value of the checkbox is the same as the id and the hidden field has empty value. You can override the hidden field value using the unchecked_value option.
You can customize the options available in the set by passing in a collection (Array) of ActiveRecord objects through the :collection option. If not provided, the choices are found by inferring the parent‘s class name from the method name and simply calling all on it (Author.all in the example above).
Examples:
f.input :author, :as => :check_boxes, :collection => @authors f.input :author, :as => :check_boxes, :collection => Author.all f.input :author, :as => :check_boxes, :collection => [@justin, @kate]
The :label_method option allows you to customize the label for each checkbox two ways:
Examples:
f.input :author, :as => :check_boxes, :label_method => :full_name f.input :author, :as => :check_boxes, :label_method => :login f.input :author, :as => :check_boxes, :label_method => :full_name_with_post_count f.input :author, :as => :check_boxes, :label_method => Proc.new { |a| "#{a.name} (#{pluralize("post", a.posts.count)})" }
The :value_method option provides the same customization of the value attribute of each checkbox input tag.
Examples:
f.input :author, :as => :check_boxes, :value_method => :full_name f.input :author, :as => :check_boxes, :value_method => :login f.input :author, :as => :check_boxes, :value_method => Proc.new { |a| "author_#{a.login}" }
Formtastic works around a bug in rails handling of check box collections by not generating the hidden fields for state checking of the checkboxes The :hidden_fields option provides a way to re-enable these hidden inputs by setting it to true.
f.input :authors, :as => :check_boxes, :hidden_fields => false f.input :authors, :as => :check_boxes, :hidden_fields => true
Finally, you can set :value_as_class => true if you want the li wrapper around each checkbox / label combination to contain a class with the value of the radio button (useful for applying specific CSS or Javascript to a particular checkbox).
Outputs a country select input, wrapping around a regular country_select helper. Rails doesn‘t come with a country_select helper by default any more, so you‘ll need to install the "official" plugin, or, if you wish, any other country_select plugin that behaves in the same way.
The Rails plugin iso-3166-country-select plugin can be found "here":github.com/rails/iso-3166-country-select.
By default, Formtastic includes a handfull of english-speaking countries as "priority counties", which you can change to suit your market and user base (see README for more info on config).
Examples:
f.input :location, :as => :country # use Formtastic::SemanticFormBuilder.priority_countries array for the priority countries f.input :location, :as => :country, :priority_countries => /Australia/ # set your own
Outputs a fieldset with a legend for the method label, and a ordered list (ol) of list items (li), one for each fragment for the date (year, month, day). Each li contains a label (eg "Year") and a select box. Overwriting the label is possible by adding the :labels option. :labels should be a hash with the field (e.g. day) as key and the label text as value. See date_or_datetime_input for a more detailed output example.
Some of Rails’ options for select_date are supported, but not everything yet, see documentation of date_or_datetime_input() for more information.
Helper method used by :as => (:date|:datetime|:time). Generates a fieldset containing a legend (for what would normally be considered the label), and an ordered list of list items for year, month, day, hour, etc, each containing a label and a select. Example:
<fieldset>
<legend>Created At</legend> <ol> <li> <label for="user_created_at_1i">Year</label> <select id="user_created_at_1i" name="user[created_at(1i)]"> <option value="2003">2003</option> ... <option value="2013">2013</option> </select> </li> <li> <label for="user_created_at_2i">Month</label> <select id="user_created_at_2i" name="user[created_at(2i)]"> <option value="1">January</option> ... <option value="12">December</option> </select> </li> <li> <label for="user_created_at_3i">Day</label> <select id="user_created_at_3i" name="user[created_at(3i)]"> <option value="1">1</option> ... <option value="31">31</option> </select> </li> </ol>
</fieldset>
This is an absolute abomination, but so is the official Rails select_date().
Options:
* @:order => [:month, :day, :year]@ * @:include_seconds@ => true@ * @:discard_(year|month|day|hour|minute) => true@ * @:include_blank => true@ * @:labels => {}@
Outputs a fieldset with a legend for the method label, and a ordered list (ol) of list items (li), one for each fragment for the date (year, month, day, hour, min, sec). Each li contains a label (eg "Year") and a select box. Overwriting the label is possible by adding the :labels option. :labels should be a hash with the field (e.g. day) as key and the label text as value. See date_or_datetime_input for a more detailed output example.
Some of Rails’ options for select_date are supported, but not everything yet, see documentation of date_or_datetime_input() for more information.
Detects the label and value methods from a collection using methods set in collection_label_methods and collection_value_methods. For some ruby core classes sensible defaults have been defined. It will use and delete the options :label_method and :value_methods when present.
Used by check_boxes input. The selected values will be set by retrieving the value through the association.
If the collection is not a hash or an array of strings, fixnums or symbols, we use value_method to retrieve an array with the values
Outputs a hidden field inside the wrapper, which should be hidden with CSS. Additionals options can be given using :input_hml. Should :input_html not be specified every option except for formtastic options will be sent straight to hidden input element.
Generates an input for the given method using the type supplied with :as.
Outputs a label and standard Rails password field inside the wrapper.
Outputs a fieldset containing a legend for the label text, and an ordered list (ol) of list items, one for each possible choice in the belongs_to association. Each li contains a label and a radio input.
Example:
f.input :author, :as => :radio
Output:
<fieldset> <legend><span>Author</span></legend> <ol> <li> <label for="book_author_id_1"><input id="book_author_id_1" name="book[author_id]" type="radio" value="1" /> Justin French</label> </li> <li> <label for="book_author_id_2"><input id="book_author_id_2" name="book[owner_id]" type="radio" value="2" /> Kate French</label> </li> </ol> </fieldset>
You can customize the choices available in the radio button set by passing in a collection (an Array or Hash) through the :collection option. If not provided, the choices are found by reflecting on the association (Author.all in the example above).
Examples:
f.input :author, :as => :radio, :collection => @authors f.input :author, :as => :radio, :collection => Author.all f.input :author, :as => :radio, :collection => [@justin, @kate] f.input :author, :collection => ["Justin", "Kate", "Amelia", "Gus", "Meg"]
The :label_method option allows you to customize the label for each radio button two ways:
Examples:
f.input :author, :as => :radio, :label_method => :full_name f.input :author, :as => :radio, :label_method => :login f.input :author, :as => :radio, :label_method => :full_name_with_post_count f.input :author, :as => :radio, :label_method => Proc.new { |a| "#{a.name} (#{pluralize("post", a.posts.count)})" }
The :value_method option provides the same customization of the value attribute of each option tag.
Examples:
f.input :author, :as => :radio, :value_method => :full_name f.input :author, :as => :radio, :value_method => :login f.input :author, :as => :radio, :value_method => Proc.new { |a| "author_#{a.login}" }
Finally, you can set :value_as_class => true if you want the li wrapper around each radio button / label combination to contain a class with the value of the radio button (useful for applying specific CSS or Javascript to a particular radio button).
Outputs a label and a select box containing options from the parent (belongs_to, has_many, has_and_belongs_to_many) association. If an association is has_many or has_and_belongs_to_many the select box will be set as multi-select and size = 5
Example (belongs_to):
f.input :author <label for="book_author_id">Author</label> <select id="book_author_id" name="book[author_id]"> <option value=""></option> <option value="1">Justin French</option> <option value="2">Jane Doe</option> </select>
Example (has_many):
f.input :chapters <label for="book_chapter_ids">Chapters</label> <select id="book_chapter_ids" name="book[chapter_ids]"> <option value=""></option> <option value="1">Chapter 1</option> <option value="2">Chapter 2</option> </select>
Example (has_and_belongs_to_many):
f.input :authors <label for="book_author_ids">Authors</label> <select id="book_author_ids" name="book[author_ids]"> <option value=""></option> <option value="1">Justin French</option> <option value="2">Jane Doe</option> </select>
You can customize the options available in the select by passing in a collection. A collection can be given as an Array, a Hash or as a String (containing pre-rendered HTML options). If not provided, the choices are found by inferring the parent‘s class name from the method name and simply calling all on it (VehicleOwner.all in the example above).
Examples:
f.input :author, :collection => @authors f.input :author, :collection => Author.all f.input :author, :collection => [@justin, @kate] f.input :author, :collection => {@justin.name => @justin.id, @kate.name => @kate.id} f.input :author, :collection => ["Justin", "Kate", "Amelia", "Gus", "Meg"] f.input :author, :collection => grouped_options_for_select(["North America",[["United States","US"],["Canada","CA"]]])
The :label_method option allows you to customize the text label inside each option tag two ways:
Examples:
f.input :author, :label_method => :full_name f.input :author, :label_method => :login f.input :author, :label_method => :full_name_with_post_count f.input :author, :label_method => Proc.new { |a| "#{a.name} (#{pluralize("post", a.posts.count)})" }
The :value_method option provides the same customization of the value attribute of each option tag.
Examples:
f.input :author, :value_method => :full_name f.input :author, :value_method => :login f.input :author, :value_method => Proc.new { |a| "author_#{a.login}" }
You can pass html_options to the select tag using :input_html => {}
Examples:
f.input :authors, :input_html => {:size => 20, :multiple => true}
By default, all select inputs will have a blank option at the top of the list. You can add a prompt with the :prompt option, or disable the blank option with :include_blank => false.
You can group the options in optgroup elements by passing the :group_by option (Note: only tested for belongs_to relations)
Examples:
f.input :author, :group_by => :continent
All the other options should work as expected. If you want to call a custom method on the group item. You can include the option:group_label_method Examples:
f.input :author, :group_by => :continents, :group_label_method => :something_different
Outputs a fieldset with a legend for the method label, and a ordered list (ol) of list items (li), one for each fragment for the time (hour, minute, second). Each li contains a label (eg "Hour") and a select box. Overwriting the label is possible by adding the :labels option. :labels should be a hash with the field (e.g. day) as key and the label text as value. See date_or_datetime_input for a more detailed output example.
Some of Rails’ options for select_time are supported, but not everything yet, see documentation of date_or_datetime_input() for more information.
Outputs a timezone select input as Rails’ time_zone_select helper. You can give priority zones as option.
Examples:
f.input :time_zone, :as => :time_zone, :priority_zones => /Australia/
Returns the active validations for the given method or an empty Array if no validations are found for the method.
By default, the if/unless options of the validations are evaluated and only the validations that should be run for the current object state are returned. Pass :all to the last parameter to return :all validations regardless of if/unless options.
Requires the ValidationReflection plugin to be present or an ActiveModel. Returns an epmty Array if neither is the case.