Class: Formtastic::Inputs::RadioInput

Inherits:
Object
  • Object
show all
Includes:
Base, Base::Choices, Base::Collections
Defined in:
lib/formtastic/inputs/radio_input.rb

Overview

TODO:

:disabled like CheckBoxes?

A radio input is used to render a series of radio inputs. This is an alternative input choice for belongs_to associations like a Post belonging to a Section or an Author, or any case where the user needs to make a single selection from a pre-defined collectioon of choices.

Within the standard <li> wrapper, the output is a <fieldset> with a <legend> to represent the "label" for the input, and an <ol> containing <li>s for each choice in the association. Each <li> choice has a <label> containing an <input type="radio"> and the label text to describe each choice.

Radio inputs can be considered as an alternative where a (non-multi) select input is used, especially in cases where there are only a few choices, however they are not used by default for any type of association or model attribute. You can choose to use a radio input instead of a select with :as => :radio.

Like a select input, the flexibility of the :collection option (see examples) makes the :radio input viable as an alternative for many other input types. For example, instead of...

  • a :string input (where you want to force the user to choose from a few specific strings rather than entering anything)
  • a :boolean checkbox input (where the user could choose yes or no, rather than checking a box)
  • a :date_select, :time_select or :datetime_select input (where the user could choose from a small set of pre-determined dates)
  • a :number input (where the user could choose from a small set of pre-defined numbers)
  • a :time_zone input (where you want to provide your own small set of choices instead of relying on Rails)
  • a :country input (where you want to provide a small set of choices, no need for a plugin really)

For radio inputs that map to associations on the object model, Formtastic will automatically load in a collection of objects on the association as options to choose from. This might be an Author.all on a Post form with an input for a belongs_to :user association, or a Section.all for a Post form with an input for a belongs_to :section association. You can override or customise this collection through the :collection option (see examples).

For radio inputs that map to ActiveRecord enum attributes, Formtastic will automatically load in your enum options to be used as the radio button choices. This can be overridden with the :collection option, or augmented with I18n translations. See examples below.

The way on which Formtastic renders the value attribute and label for each choice in the :collection is customisable (see examples below). When not provided, we fall back to a list of methods to try on each object such as :to_label, :name and :to_s, which are defined in the configurations collection_label_methods and collection_value_methods.

Examples:

Basic belongs_to example with full form context


<%= semantic_form_for @post do |f| %>
  <%= f.inputs do %>
    <%= f.input :author, :as => :radio %>
  <% end %>
<% end %>

<form...>
  <fieldset>
    <ol>
      <li class='radio'>
        <fieldset>
          <legend class="label"><label>Categories</label></legend>
          <ol>
            <li>
              <label for="post_author_id_1">
                <input type="radio" id="post_author_id_1" value="1"> Justin
              </label>
            </li>
            <li>
              <label for="post_author_id_3">
                <input type="radio" id="post_author_id_3" value="3"> Kate
              </label>
            </li>
            <li>
              <label for="post_author_id_2">
                <input type="radio" id="post_author_id_2" value="2"> Amelia
              </label>
            </li>
          </ol>
        </fieldset>
      </li>
    </ol>
  </fieldset>
</form>

The :collection option can be used to customize the choices

<%= f.input :author, :as => :radio, :collection => @authors %>
<%= f.input :author, :as => :radio, :collection => Author.all %>
<%= f.input :author, :as => :radio, :collection => Author.some_named_scope %>
<%= f.input :author, :as => :radio, :collection => Author.pluck(:full_name, :id) %>
<%= f.input :author, :as => :radio, :collection => Author.pluck(Arel.sql("CONCAT(`first_name`, ' ', `last_name`)"), :id)) %>
<%= f.input :author, :as => :radio, :collection => [Author.find_by_login("justin"), Category.find_by_name("kate")] %>
<%= f.input :author, :as => :radio, :collection => ["Justin", "Kate"] %>
<%= f.input :author, :as => :radio, :collection => [["Justin", "justin"], ["Kate", "kate"]] %>
<%= f.input :author, :as => :radio, :collection => [["Justin", "1"], ["Kate", "3"]] %>
<%= f.input :author, :as => :radio, :collection => [["Justin", 1], ["Kate", 3]] %>
<%= f.input :author, :as => :radio, :collection => [["Justin", :justin], ["Kate", :kate]] %>
<%= f.input :author, :as => :radio, :collection => [:justin, :kate] %>
<%= f.input :author, :as => :radio, :collection => 1..5 %>

Set HTML attributes on each <input type="radio"> tag with :input_html

<%= f.input :author, :as => :radio, :input_html => { :size => 20, :multiple => true, :class => "special" } %>

Set HTML attributes on the <li> wrapper with :wrapper_html

<%= f.input :author, :as => :radio, :wrapper_html => { :class => "special" } %>

:value_as_class can be used to add a class to the <li> wrapped around each choice using the radio value for custom styling of each choice

<%= f.input :author, :as => :radio, :value_as_class => true %>

Set HTML options on a specific radio input option with a 3rd element in the array for a collection member

<%= f.input :author, :as => :radio, :collection => [["Test", 'test'], ["Try", "try", {:disabled => true}]]

Using ActiveRecord enum attribute with i18n translation:

# post.rb
class Post < ActiveRecord::Base
  enum :status => [ :active, :archived ]
end
# en.yml
en:
  activerecord:
    attributes:
      post:
        statuses:
          active: I am active!
          archived: I am archived!
# form
<%= f.input :status, :as => :radio %>

See Also:

Instance Attribute Summary

Attributes included from Base

#builder, #method, #object, #object_name, #options, #template

Instance Method Summary collapse

Methods included from Base::Choices

#choice_html_options, #choice_html_safe_value, #choice_input_dom_id, #choice_label, #choice_value, #choice_wrapping, #choice_wrapping_html_options, #choices_group_wrapping, #choices_group_wrapping_html_options, #choices_wrapping, #choices_wrapping_html_options, #custom_choice_html_options, #default_choice_html_options, #legend_html, #value_as_class?

Methods included from Base::Collections

#collection, #collection_for_boolean, #collection_from_association, #collection_from_enum, #collection_from_enum?, #collection_from_options, #label_and_value_method, #label_and_value_method_from_collection, #label_method, #label_method_from_options, #raw_collection, #send_or_call, #send_or_call_or_object, #value_method, #value_method_from_options

Methods included from Base

#initialize, #removed_option!, #warn_and_correct_option!, #warn_deprecated_option!

Methods included from Base::Wrapping

#input_wrapping, #wrapper_classes, #wrapper_classes_raw, #wrapper_dom_id, #wrapper_html_options, #wrapper_html_options_raw

Methods included from Base::Labelling

#label_from_options, #label_html, #label_text, #localized_label, #render_label?, #requirement_text, #requirement_text_or_proc

Methods included from LocalizedString

#model_name

Methods included from Base::Associations

#association, #association_primary_key, #belongs_to?, #has_many?, #reflection

Methods included from Base::Fileish

#file?

Methods included from Base::Validations

#autofocus?, #column_limit, #limit, #not_required_through_negated_validation!, #not_required_through_negated_validation?, #optional?, #required?, #required_attribute?, #responds_to_global_required?, #validation_integer_only?, #validation_limit, #validation_max, #validation_min, #validation_step, #validations, #validations?, #validator_relevant?

Methods included from Base::Naming

#as, #attributized_method_name, #humanized_method_name, #input_name, #sanitized_method_name, #sanitized_object_name

Methods included from Base::Hints

#hint?, #hint_html, #hint_text, #hint_text_from_options

Methods included from Base::Errors

#error_first_html, #error_html, #error_keys, #error_list_html, #error_none_html, #error_sentence_html, #errors, #errors?

Methods included from Base::Database

#column, #column?

Methods included from Base::Options

#formtastic_options, #input_options

Methods included from Base::Html

#dom_id, #dom_index, #input_html_options

Instance Method Details

#choice_html(choice) ⇒ Object



147
148
149
150
151
152
153
# File 'lib/formtastic/inputs/radio_input.rb', line 147

def choice_html(choice)        
  template.(:label,
    builder.radio_button(input_name, choice_value(choice), input_html_options.merge(choice_html_options(choice)).merge(:required => false)) << 
    choice_label(choice),
    label_html_options.merge(:for => choice_input_dom_id(choice), :class => nil)
  )
end

#label_html_optionsObject

Override to remove the for attribute since this isn't associated with any element, as it's nested inside the legend.



157
158
159
# File 'lib/formtastic/inputs/radio_input.rb', line 157

def label_html_options
  super.merge(:for => nil)
end

#to_htmlObject



132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/formtastic/inputs/radio_input.rb', line 132

def to_html
  input_wrapping do
    choices_wrapping do
      legend_html <<
      choices_group_wrapping do
        collection.map { |choice| 
          choice_wrapping(choice_wrapping_html_options(choice)) do
            choice_html(choice)
          end
        }.join("\n").html_safe
      end
    end
  end
end