class Hanami::Helpers::FormHelper::FormBuilder
Form
builder
@since 0.2.0
Constants
- ACCEPT_SEPARATOR
Separator for accept attribute of file input
@since 0.2.0 @api private
@see Hanami::Helpers::FormHelper::FormBuilder#file_input
- BROWSER_METHODS
Set of HTTP methods that are understood by web browsers
@since 0.2.0 @api private
- CHECKED
Checked attribute value
@since 0.2.0 @api private
- DEFAULT_CHECKED_VALUE
Default value for checked check box
@since 0.2.0 @api private
- DEFAULT_UNCHECKED_VALUE
Default value for unchecked check box
@since 0.2.0 @api private
- EXCLUDED_CSRF_METHODS
Set of HTTP methods that should NOT generate CSRF token
@since 0.2.0 @api private
- INPUT_ID_REPLACEMENT
Replacement for input id interpolation
@since 0.2.0 @api private
@see Hanami::Helpers::FormHelper::FormBuilder#_input_id
- SELECTED
Selected attribute value for option
@since 0.2.0 @api private
Public Class Methods
Instantiate a form builder
@overload initialize(form, attributes, context, params, &blk)
Top level form @param form [Hanami::Helpers:FormHelper::Form] the form @param attributes [::Hash] a set of HTML attributes @param context [Hanami::Helpers::FormHelper] @param params [Hash] optional set of params to override the ones that are coming from the view context @param blk [Proc] a block that describes the contents of the form
@overload initialize(form, attributes, params, &blk)
Nested form @param form [Hanami::Helpers:FormHelper::Form] the form @param attributes [Hanami::Helpers::FormHelper::Values] user defined values @param blk [Proc] a block that describes the contents of the form
@return [Hanami::Helpers::FormHelper::FormBuilder] the form builder
@since 0.2.0 @api private
Hanami::Helpers::HtmlHelper::HtmlBuilder::new
# File lib/hanami/helpers/form_helper/form_builder.rb, line 103 def initialize(form, attributes, context = nil, params = nil, &blk) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength super() @context = context @blk = blk @verb = nil @csrf_token = nil # Nested form if @context.nil? && attributes.is_a?(Values) @values = attributes @attributes = {} @name = form else @form = form @name = form.name @values = Values.new(form.values, params || @context.params) @attributes = attributes @verb_method = verb_method @csrf_token = csrf_token end end
Public Instance Methods
Check box
It renders a check box input.
When a form is submitted, browsers don't send the value of unchecked check boxes. If an user unchecks a check box, their browser won't send the unchecked value. On the server side the corresponding value is missing, so the application will assume that the user action never happened.
To solve this problem the form renders a hidden field with the “unchecked value”. When the user unchecks the input, the browser will ignore it, but it will still send the value of the hidden input. See the examples below.
When editing a resource, the form automatically assigns the checked="checked"
attribute.
@param name [Symbol] the input name @param attributes [Hash] HTML attributes to pass to the input tag @option attributes [String] :checked_value (defaults to “1”) @option attributes [String] :unchecked_value (defaults to “0”)
@since 0.2.0
@example Basic usage
<%= check_box :free_shipping %> <!-- output --> <input type="hidden" name="delivery[free_shipping]" value="0"> <input type="checkbox" name="delivery[free_shipping]" id="delivery-free-shipping" value="1">
@example HTML Attributes
<%= check_box :free_shipping, class: "form-check-input" %> <!-- output --> <input type="hidden" name="delivery[free_shipping]" value="0"> <input type="checkbox" name="delivery[free_shipping]" id="delivery-free-shipping" value="1" class="form-check-input">
@example Specify (un)checked values
<%= check_box :free_shipping, checked_value: 'true', unchecked_value: 'false' %> <!-- output --> <input type="hidden" name="delivery[free_shipping]" value="false"> <input type="checkbox" name="delivery[free_shipping]" id="delivery-free-shipping" value="true">
@example Automatic “checked” attribute
# For this example the params are: # # { delivery: { free_shipping: '1' } } <%= check_box :free_shipping %> <!-- output --> <input type="hidden" name="delivery[free_shipping]" value="0"> <input type="checkbox" name="delivery[free_shipping]" id="delivery-free-shipping" value="1" checked="checked">
@example Force “checked” attribute
# For this example the params are: # # { delivery: { free_shipping: '0' } } <%= check_box :free_shipping, checked: 'checked' %> <!-- output --> <input type="hidden" name="delivery[free_shipping]" value="0"> <input type="checkbox" name="delivery[free_shipping]" id="delivery-free-shipping" value="1" checked="checked">
@example Multiple check boxes
<%= check_box :languages, name: 'book[languages][]', value: 'italian', id: nil check_box :languages, name: 'book[languages][]', value: 'english', id: nil %> <!-- output --> <input type="checkbox" name="book[languages][]" value="italian"> <input type="checkbox" name="book[languages][]" value="english">
@example Automatic “checked” attribute for multiple check boxes
# For this example the params are: # # { book: { languages: ['italian'] } } <%= check_box :languages, name: 'book[languages][]', value: 'italian', id: nil check_box :languages, name: 'book[languages][]', value: 'english', id: nil %> <!-- output --> <input type="checkbox" name="book[languages][]" value="italian" checked="checked"> <input type="checkbox" name="book[languages][]" value="english">
# File lib/hanami/helpers/form_helper/form_builder.rb, line 523 def check_box(name, attributes = {}) _hidden_field_for_check_box(name, attributes) input _attributes_for_check_box(name, attributes) end
Color input
@param name [Symbol] the input name @param attributes [Hash] HTML attributes to pass to the input tag
@since 0.2.0
@example Basic usage
<%= # ... color_field :background %> <!-- output --> <input type="color" name="user[background]" id="user-background" value="">
@example HTML Attributes
<%= # ... color_field :background, class: "form-control" %> <!-- output --> <input type="color" name="user[background]" id="user-background" value="" class="form-control">
# File lib/hanami/helpers/form_helper/form_builder.rb, line 552 def color_field(name, attributes = {}) input _attributes(:color, name, attributes) end
Datalist input
@param name [Symbol] the input name @param values [Array,Hash] a collection that is transformed into <option>
tags. @param list [String] the name of list for the text input, it's also the id of datalist @param attributes [Hash] HTML attributes to pass to the input tag
@since 0.4.0
@example Basic Usage
<%= # ... values = ['Italy', 'United States'] datalist :stores, values, 'books' %> <!-- output --> <input type="text" name="book[store]" id="book-store" value="" list="books"> <datalist id="books"> <option value="Italy"></option> <option value="United States"></option> </datalist>
@example Options As Hash
<%= # ... values = Hash['Italy' => 'it', 'United States' => 'us'] datalist :stores, values, 'books' %> <!-- output --> <input type="text" name="book[store]" id="book-store" value="" list="books"> <datalist id="books"> <option value="Italy">it</option> <option value="United States">us</option> </datalist>
@example Specify Custom Attributes For Datalist Input
<%= # ... values = ['Italy', 'United States'] datalist :stores, values, 'books', datalist: { class: 'form-control' } %> <!-- output --> <input type="text" name="book[store]" id="book-store" value="" list="books"> <datalist id="books" class="form-control"> <option value="Italy"></option> <option value="United States"></option> </datalist>
@example Specify Custom Attributes For Options List
<%= # ... values = ['Italy', 'United States'] datalist :stores, values, 'books', options: { class: 'form-control' } %> <!-- output --> <input type="text" name="book[store]" id="book-store" value="" list="books"> <datalist id="books"> <option value="Italy" class="form-control"></option> <option value="United States" class="form-control"></option> </datalist>
# File lib/hanami/helpers/form_helper/form_builder.rb, line 1383 def datalist(name, values, list, attributes = {}) # rubocop:disable Metrics/MethodLength attrs = attributes.dup options = attrs.delete(:options) || {} datalist = attrs.delete(:datalist) || {} attrs[:list] = list datalist[:id] = list text_field(name, attrs) super(datalist) do values.each do |value, content| option(content, { value: value }.merge(options)) end end end
Date input
@param name [Symbol] the input name @param attributes [Hash] HTML attributes to pass to the input tag
@since 0.2.0
@example Basic usage
<%= # ... date_field :birth_date %> <!-- output --> <input type="date" name="user[birth_date]" id="user-birth-date" value="">
@example HTML Attributes
<%= # ... date_field :birth_date, class: "form-control" %> <!-- output --> <input type="date" name="user[birth_date]" id="user-birth-date" value="" class="form-control">
# File lib/hanami/helpers/form_helper/form_builder.rb, line 580 def date_field(name, attributes = {}) input _attributes(:date, name, attributes) end
Datetime input
@param name [Symbol] the input name @param attributes [Hash] HTML attributes to pass to the input tag
@since 0.2.0
@example Basic usage
<%= # ... datetime_field :delivered_at %> <!-- output --> <input type="datetime" name="delivery[delivered_at]" id="delivery-delivered-at" value="">
@example HTML Attributes
<%= # ... datetime_field :delivered_at, class: "form-control" %> <!-- output --> <input type="datetime" name="delivery[delivered_at]" id="delivery-delivered-at" value="" class="form-control">
# File lib/hanami/helpers/form_helper/form_builder.rb, line 608 def datetime_field(name, attributes = {}) input _attributes(:datetime, name, attributes) end
Datetime Local input
@param name [Symbol] the input name @param attributes [Hash] HTML attributes to pass to the input tag
@since 0.2.0
@example Basic usage
<%= # ... datetime_local_field :delivered_at %> <!-- output --> <input type="datetime-local" name="delivery[delivered_at]" id="delivery-delivered-at" value="">
@example HTML Attributes
<%= # ... datetime_local_field :delivered_at, class: "form-control" %> <!-- output --> <input type="datetime-local" name="delivery[delivered_at]" id="delivery-delivered-at" value="" class="form-control">
# File lib/hanami/helpers/form_helper/form_builder.rb, line 636 def datetime_local_field(name, attributes = {}) input _attributes(:'datetime-local', name, attributes) end
Email input
@param name [Symbol] the input name @param attributes [Hash] HTML attributes to pass to the input tag
@since 0.2.0
@example Basic usage
<%= # ... email_field :email %> <!-- output --> <input type="email" name="user[email]" id="user-email" value="">
@example HTML Attributes
<%= # ... email_field :email, class: "form-control" %> <!-- output --> <input type="email" name="user[email]" id="user-email" value="" class="form-control">
# File lib/hanami/helpers/form_helper/form_builder.rb, line 748 def email_field(name, attributes = {}) input _attributes(:email, name, attributes) end
Nested fields
The inputs generated by the wrapped block will be prefixed with the given name It supports infinite levels of nesting.
@param name [Symbol] the nested name, it's used to generate input
names, ids, and to lookup params to fill values.
@yield [index] @yieldparam [Integer] index iterative index (it starts from zero)
@since 0.2.0
@example Basic usage
<%= form_for :delivery, routes.deliveries_path do text_field :customer_name fields_for :address do text_field :street end submit 'Create' end %> <!-- output --> <form action="/deliveries" method="POST" accept-charset="utf-8" id="delivery-form"> <input type="hidden" name="_csrf_token" value="920cd5bfaecc6e58368950e790f2f7b4e5561eeeab230aa1b7de1b1f40ea7d5d"> <input type="text" name="delivery[customer_name]" id="delivery-customer-name" value=""> <input type="text" name="delivery[address][street]" id="delivery-address-street" value=""> <button type="submit">Create</button> </form>
@example Multiple levels of nesting
<%= form_for :delivery, routes.deliveries_path do text_field :customer_name fields_for :address do text_field :street fields_for :location do text_field :city text_field :country end end submit 'Create' end %> <!-- output --> <form action="/deliveries" method="POST" accept-charset="utf-8" id="delivery-form"> <input type="hidden" name="_csrf_token" value="920cd5bfaecc6e58368950e790f2f7b4e5561eeeab230aa1b7de1b1f40ea7d5d"> <input type="text" name="delivery[customer_name]" id="delivery-customer-name" value=""> <input type="text" name="delivery[address][street]" id="delivery-address-street" value=""> <input type="text" name="delivery[address][location][city]" id="delivery-address-location-city" value=""> <input type="text" name="delivery[address][location][country]" id="delivery-address-location-country" value=""> <button type="submit">Create</button> </form>
# File lib/hanami/helpers/form_helper/form_builder.rb, line 207 def fields_for(name, value = nil) current_name = @name @name = _input_name(name) yield(name, value) ensure @name = current_name end
Nested collections
Supports nesting for collections, with infinite levels of nesting.
@param name [Symbol] the nested name, it's used to generate input
names, ids, and to lookup params to fill values.
@yield [index, value] @yieldparam [Integer] index iterative index (it starts from zero) @yieldparam [Object] value an item of the collection
@example Basic usage
<%= form_for :delivery, routes.deliveries_path do text_field :customer_name fields_for_collection :addresses do text_field :street end submit 'Create' end %> <!-- output --> <form action="/deliveries" method="POST" accept-charset="utf-8" id="delivery-form"> <input type="hidden" name="_csrf_token" value="920cd5bfaecc6e58368950e790f2f7b4e5561eeeab230aa1b7de1b1f40ea7d5d"> <input type="text" name="delivery[customer_name]" id="delivery-customer-name" value=""> <input type="text" name="delivery[addresses][][street]" id="delivery-address-0-street" value=""> <input type="text" name="delivery[addresses][][street]" id="delivery-address-1-street" value=""> <button type="submit">Create</button> </form>
@example Yield index and value
<%= form_for(:bill, routes.bill_path(id: bill.id), { bill: bill }, method: :patch, class: 'form-horizontal') do fieldset do legend "Addresses" fields_for_collection :addresses do |i, address| div class: "form-group" do text "Address id: #{address.id}" label :street input_text :street, class: "form-control", placeholder: "Street", "data-funky": "index-#{i}" end end label :ensure_names end submit submit_label, class: "btn btn-default" end %> <!-- output --> <form action="/bills/1" method="POST" accept-charset="utf-8" id="bill-form" class="form-horizontal"> <input type="hidden" name="_method" value="PATCH"> <input type="hidden" name="_csrf_token" value="920cd5bfaecc6e58368950e790f2f7b4e5561eeeab230aa1b7de1b1f40ea7d5d"> <fieldset> <legend>Addresses</legend> <div class="form-group"> Address id: 23 <label for="bill-addresses-0-street">Street</label> <input type="text" name="bill[addresses][][street]" id="bill-addresses-0-street" value="5th Ave" class="form-control" placeholder="Street" data-funky="index-0"> </div> <div class="form-group"> Address id: 42 <label for="bill-addresses-1-street">Street</label> <input type="text" name="bill[addresses][][street]" id="bill-addresses-1-street" value="4th Ave" class="form-control" placeholder="Street" data-funky="index-1"> </div> <label for="bill-ensure-names">Ensure names</label> </fieldset> <button type="submit" class="btn btn-default">Update</button> </form>
# File lib/hanami/helpers/form_helper/form_builder.rb, line 296 def fields_for_collection(name, &block) current_name = @name base_value = _value(name) @name = _input_name(name) base_value.each_with_index do |value, index| fields_for(index, value, &block) end ensure @name = current_name end
Fieldset
@param content [Symbol,String,NilClass] the content @param attributes [Hash] HTML attributes to pass to the label tag
@since 1.0.0
@example Basic usage
<%= # ... fieldset do legend "Author" fields_for :author do label :name text_field :name end end %> <!-- output --> <fieldset> <legend>Author</legend> <label for="book-author-name">Name</label> <input type="text" name="book[author][name]" id="book-author-name" value=""> </fieldset>
# File lib/hanami/helpers/form_helper/form_builder.rb, line 420 def fieldset(content = nil, attributes = {}) # This is here only for documentation purposes super end
File input
**PLEASE REMEMBER TO ADD enctype: 'multipart/form-data'
ATTRIBUTE TO THE FORM**
@param name [Symbol] the input name @param attributes [Hash] HTML attributes to pass to the input tag @option attributes [String,Array] :accept Optional set of accepted MIME Types @option attributes [TrueClass,FalseClass] :multiple Optional, allow multiple file upload
@since 0.2.0
@example Basic usage
<%= # ... file_field :avatar %> <!-- output --> <input type="file" name="user[avatar]" id="user-avatar">
@example HTML Attributes
<%= # ... file_field :avatar, class: "avatar-upload" %> <!-- output --> <input type="file" name="user[avatar]" id="user-avatar" class="avatar-upload">
@example Accepted MIME Types
<%= # ... file_field :resume, accept: 'application/pdf,application/ms-word' %> <!-- output --> <input type="file" name="user[resume]" id="user-resume" accept="application/pdf,application/ms-word">
@example Accepted MIME Types (as array)
<%= # ... file_field :resume, accept: ['application/pdf', 'application/ms-word'] %> <!-- output --> <input type="file" name="user[resume]" id="user-resume" accept="application/pdf,application/ms-word">
@example Accepted multiple file upload (as array)
<%= # ... file_field :resume, multiple: true %> <!-- output --> <input type="file" name="user[resume]" id="user-resume" multiple="multiple">
# File lib/hanami/helpers/form_helper/form_builder.rb, line 885 def file_field(name, attributes = {}) attributes[:accept] = Array(attributes[:accept]).join(ACCEPT_SEPARATOR) if attributes.key?(:accept) attributes = { type: :file, name: _displayed_input_name(name), id: _input_id(name) }.merge(attributes) input(attributes) end
Label tag
The first param content
can be a Symbol
that represents the target field (Eg. :extended_title
), or a String
which is used as it is.
@param content [Symbol,String] the field name or a content string @param attributes [Hash] HTML attributes to pass to the label tag
@since 0.2.0
@example Basic usage
<%= # ... label :extended_title %> <!-- output --> <label for="book-extended-title">Extended title</label>
@example HTML attributes
<%= # ... label :title, class: "form-label" %> <!-- output --> <label for="book-title" class="form-label">Title</label>
@example Custom content
<%= # ... label 'Title', for: :extended_title %> <!-- output --> <label for="book-extended-title">Title</label>
@example Custom “for” attribute
<%= # ... label :extended_title, for: 'ext-title' %> <!-- output --> <label for="ext-title">Extended title</label>
@example Nested fields usage
<%= # ... fields_for :address do label :city text_field :city end %> <!-- output --> <label for="delivery-address-city">City</label> <input type="text" name="delivery[address][city] id="delivery-address-city" value="">
@example Block syntax
<%= # ... label for: :free_shipping do text "Free shipping" abbr "*", title: "optional", "aria-label": "optional" end %> <!-- output --> <label for="book-free-shipping"> Free Shipping <abbr title="optional" aria-label="optional">*</abbr> </label>
# File lib/hanami/helpers/form_helper/form_builder.rb, line 382 def label(content = nil, **attributes, &blk) attributes = { for: _for(content, attributes.delete(:for)) }.merge(attributes) content = case content when String, Hanami::Utils::String, NilClass content else Utils::String.capitalize(content) end super(content, attributes, &blk) end
Month field
@param name [Symbol] the input name @param attributes [Hash] HTML attributes to pass to the input tag
@since 1.0.0
@example Basic usage
<%= # ... month_field :release_month %> <!-- output --> <input type="month" name="book[release_month]" id="book-release-month" value="">
@example HTML Attributes
<%= # ... month_field :release_month, class: "form-control" %> <!-- output --> <input type="month" name="book[release_month]" id="book-release-month" value="" class="form-control">
# File lib/hanami/helpers/form_helper/form_builder.rb, line 692 def month_field(name, attributes = {}) input _attributes(:month, name, attributes) end
Number input
You can also make use of the `max`, `min`, and `step` attributes for the HTML5 number field.
@param name [Symbol] the input name @param attributes [Hash] HTML attributes to pass to the number input
@example Basic usage
<%= # ... number_field :percent_read %> <!-- output --> <input type="number" name="book[percent_read]" id="book-percent-read" value="">
@example Advanced attributes
<%= # ... number_field :priority, min: 1, max: 10, step: 1 %> <!-- output --> <input type="number" name="book[percent_read]" id="book-precent-read" value="" min="1" max="10" step="1">
# File lib/hanami/helpers/form_helper/form_builder.rb, line 917 def number_field(name, attributes = {}) input _attributes(:number, name, attributes) end
Password input
@param name [Symbol] the input name @param attributes [Hash] HTML attributes to pass to the input tag
@since 0.2.0
@example Basic usage
<%= # ... password_field :password %> <!-- output --> <input type="password" name="signup[password]" id="signup-password" value="">
# File lib/hanami/helpers/form_helper/form_builder.rb, line 1142 def password_field(name, attributes = {}) input({ type: :password, name: _displayed_input_name(name), id: _input_id(name), value: nil }.merge(attributes)) end
Range input
You can also make use of the `max`, `min`, and `step` attributes for the HTML5 number field.
@param name [Symbol] the input name @param attributes [Hash] HTML attributes to pass to the number input
@since 1.0.0
@example Basic usage
<%= # ... range_field :discount_percentage %> <!-- output --> <input type="range" name="book[discount_percentage]" id="book-discount-percentage" value="">
@example Advanced attributes
<%= # ... range_field :discount_percentage, min: 1, max: 10, step: 1 %> <!-- output --> <input type="number" name="book[discount_percentage]" id="book-discount-percentage" value="" min="1" max="10" step="1">
# File lib/hanami/helpers/form_helper/form_builder.rb, line 948 def range_field(name, attributes = {}) input _attributes(:range, name, attributes) end
Search input
@param name [Symbol] the input name @param attributes [Hash] HTML attributes to pass to the input tag
@since 1.0.0
@example Basic usage
<%= # ... search_field :q %> <!-- output --> <input type="search" name="search[q]" id="search-q" value="">
@example HTML Attributes
<%= # ... search_field :q, class: "form-control" %> <!-- output --> <input type="search" name="search[q]" id="search-q" value="" class="form-control">
# File lib/hanami/helpers/form_helper/form_builder.rb, line 1067 def search_field(name, attributes = {}) input _attributes(:search, name, attributes) end
Select input
@param name [Symbol] the input name @param values [Hash] a Hash to generate <option>
tags. @param attributes [Hash] HTML attributes to pass to the input tag
Values
is used to generate the list of <option>
tags, it is an Enumerable
of pairs of content (the displayed text) and value (the tag's attribute), in that respective order (please refer to the examples for more clarity).
If request params have a value that corresponds to one of the given values, it automatically sets the selected
attribute on the <option>
tag. This Hanami::Controller integration happens without any developer intervention.
@since 0.2.0
@example Basic usage
<%= # ... values = Hash['Italy' => 'it', 'United States' => 'us'] select :store, values %> <!-- output --> <select name="book[store]" id="book-store"> <option value="it">Italy</option> <option value="us">United States</option> </select>
@example HTML Attributes
<%= # ... values = Hash['Italy' => 'it', 'United States' => 'us'] select :store, values, class: "form-control" %> <!-- output --> <select name="book[store]" id="book-store" class="form-control"> <option value="it">Italy</option> <option value="us">United States</option> </select>
@example Automatic selected option
# Given the following params: # # book: { # store: 'it' # } <%= # ... values = Hash['Italy' => 'it', 'United States' => 'us'] select :store, values %> <!-- output --> <select name="book[store]" id="book-store"> <option value="it" selected="selected">Italy</option> <option value="us">United States</option> </select>
@example Prompt option
<%= # ... values = Hash['Italy' => 'it', 'United States' => 'us'] select :store, values, options: { prompt: 'Select a store' } %> <!-- output --> <select name="book[store]" id="book-store"> <option>Select a store</option> <option value="it">Italy</option> <option value="us">United States</option> </select>
@example Selected option
<%= # ... values = Hash['Italy' => 'it', 'United States' => 'us'] select :store, values, options: { selected: book.store } %> <!-- output --> <select name="book[store]" id="book-store"> <option value="it" selected="selected">Italy</option> <option value="us">United States</option> </select>
@example Prompt option and HTML attributes
<%= # ... values = Hash['Italy' => 'it', 'United States' => 'us'] select :store, values, options: { prompt: 'Select a store' }, class: "form-control" %> <!-- output --> <select name="book[store]" id="book-store" class="form-control"> <option disabled="disabled">Select a store</option> <option value="it">Italy</option> <option value="us">United States</option> </select>
@example Multiple select
<%= # ... values = Hash['Italy' => 'it', 'United States' => 'us'] select :stores, values, multiple: true %> <!-- output --> <select name="book[store][]" id="book-store" multiple="multiple"> <option value="it">Italy</option> <option value="us">United States</option> </select>
@example Multiple select and HTML attributes
<%= # ... values = Hash['Italy' => 'it', 'United States' => 'us'] select :stores, values, multiple: true, class: "form-control" %> <!-- output --> <select name="book[store][]" id="book-store" multiple="multiple" class="form-control"> <option value="it">Italy</option> <option value="us">United States</option> </select>
@example Array with repeated entries
<%= # ... values = [['Italy', 'it'], ['---', ''], ['Afghanistan', 'af'], ... ['Italy', 'it'], ... ['Zimbabwe', 'zw']] select :stores, values %> <!-- output --> <select name="book[store]" id="book-store"> <option value="it">Italy</option> <option value="">---</option> <option value="af">Afghanistan</option> ... <option value="it">Italy</option> ... <option value="zw">Zimbabwe</option> </select>
# File lib/hanami/helpers/form_helper/form_builder.rb, line 1297 def select(name, values, attributes = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength options = attributes.delete(:options) { {} } multiple = attributes[:multiple] attributes = { name: _select_input_name(name, multiple), id: _input_id(name) }.merge(attributes) prompt = options.delete(:prompt) selected = options.delete(:selected) input_value = _value(name) super(attributes) do option(prompt, disabled: true) if prompt already_selected = nil values.each do |content, value| if (multiple || !already_selected) && (already_selected = _select_option_selected?(value, selected, input_value, multiple)) option(content, { value: value, selected: SELECTED }.merge(options)) else option(content, { value: value }.merge(options)) end end end end
Submit button
@overload submit(content, attributes = {})
Use string content @param content [String] The content @param attributes [Hash] HTML attributes to pass to the button tag
@overload submit(attributes = {}, &blk)
Use block content @param attributes [Hash] HTML attributes to pass to the button tag @param blk [Proc] the block content
@since 0.2.0
@example Basic usage
<%= # ... submit 'Create' %> <!-- output --> <button type="submit">Create</button>
@example HTML Attributes
<%= # ... submit 'Create', class: "btn btn-primary" %> <!-- output --> <button type="submit" class="btn btn-primary">Create</button>
@example Block
<%= # ... button class: "btn btn-primary" do span class: 'oi oi-check' end %> <!-- output --> <button type="submit" class="btn btn-primary"> <span class="oi oi-check"></span> </button>
# File lib/hanami/helpers/form_helper/form_builder.rb, line 1532 def submit(content, attributes = {}, &blk) if content.is_a?(::Hash) attributes = content content = nil end attributes = { type: :submit }.merge(attributes) button(content, attributes, &blk) end
Telephone input
@param name [Symbol] the input name @param attributes [Hash] HTML attributes to pass to the input tag
@since 1.0.0
@example Basic usage
<%= # ... tel_field :telephone %> <!-- output --> <input type="tel" name="user[telephone]" id="user-telephone" value="">
@example HTML Attributes
<%= # ... telurl_field :telephone, class: "form-control" %> <!-- output --> <input type="tel" name="user[telephone]" id="user-telephone" value="" class="form-control">
# File lib/hanami/helpers/form_helper/form_builder.rb, line 807 def tel_field(name, attributes = {}) input _attributes(:tel, name, attributes) end
Text-area input
@param name [Symbol] the input name @param content [String] the content of the textarea @param attributes [Hash] HTML attributes to pass to the textarea tag
@since 0.2.5
@example Basic usage
<%= # ... text_area :hobby %> <!-- output --> <textarea name="user[hobby]" id="user-hobby"></textarea>
@example Set content
<%= # ... text_area :hobby, 'Football' %> <!-- output --> <textarea name="user[hobby]" id="user-hobby">Football</textarea>
@example Set content and HTML attributes
<%= # ... text_area :hobby, 'Football', class: 'form-control' %> <!-- output --> <textarea name="user[hobby]" id="user-hobby" class="form-control">Football</textarea>
@example Omit content and specify HTML attributes
<%= # ... text_area :hobby, class: 'form-control' %> <!-- output --> <textarea name="user[hobby]" id="user-hobby" class="form-control"></textarea>
@example Force blank value
<%= # ... text_area :hobby, '', class: 'form-control' %> <!-- output --> <textarea name="user[hobby]" id="user-hobby" class="form-control"></textarea>
# File lib/hanami/helpers/form_helper/form_builder.rb, line 1004 def text_area(name, content = nil, attributes = {}) if content.respond_to?(:to_hash) attributes = content content = nil end attributes = { name: _displayed_input_name(name), id: _input_id(name) }.merge(attributes) textarea(content || _value(name), attributes) end
Text input
@param name [Symbol] the input name @param attributes [Hash] HTML attributes to pass to the input tag
@since 0.2.0
@example Basic usage
<%= # ... text_field :first_name %> <!-- output --> <input type="text" name="user[first_name]" id="user-first-name" value="">
@example HTML Attributes
<%= # ... text_field :first_name, class: "form-control" %> <!-- output --> <input type="text" name="user[first_name]" id="user-first-name" value="" class="form-control">
# File lib/hanami/helpers/form_helper/form_builder.rb, line 1038 def text_field(name, attributes = {}) input _attributes(:text, name, attributes) end
Time field
@param name [Symbol] the input name @param attributes [Hash] HTML attributes to pass to the input tag
@since 1.0.0
@example Basic usage
<%= # ... time_field :release_hour %> <!-- output --> <input type="time" name="book[release_hour]" id="book-release-hour" value="">
@example HTML Attributes
<%= # ... time_field :release_hour, class: "form-control" %> <!-- output --> <input type="time" name="book[release_hour]" id="book-release-hour" value="" class="form-control">
# File lib/hanami/helpers/form_helper/form_builder.rb, line 664 def time_field(name, attributes = {}) input _attributes(:time, name, attributes) end
Resolves all the nodes and generates the markup
@return [Hanami::Utils::Escape::SafeString] the output
@since 0.2.0 @api private
@see Hanami::Helpers::HtmlHelper::HtmlBuilder#to_s
@see www.rubydoc.info/gems/hanami-utils/Hanami/Utils/Escape/SafeString
Hanami::Helpers::HtmlHelper::HtmlBuilder#to_s
# File lib/hanami/helpers/form_helper/form_builder.rb, line 135 def to_s if toplevel? _method_override! form(@blk, @attributes) end super end
URL input
@param name [Symbol] the input name @param attributes [Hash] HTML attributes to pass to the input tag
@since 1.0.0
@example Basic usage
<%= # ... url_field :website %> <!-- output --> <input type="url" name="user[website]" id="user-website" value="">
@example HTML Attributes
<%= # ... url_field :website, class: "form-control" %> <!-- output --> <input type="url" name="user[website]" id="user-website" value="" class="form-control">
# File lib/hanami/helpers/form_helper/form_builder.rb, line 776 def url_field(name, attributes = {}) attrs = attributes.dup attrs[:value] = escape_url(attrs.fetch(:value) { _value(name) }) input _attributes(:url, name, attrs) end
Week field
@param name [Symbol] the input name @param attributes [Hash] HTML attributes to pass to the input tag
@since 1.0.0
@example Basic usage
<%= # ... week_field :release_week %> <!-- output --> <input type="week" name="book[release_week]" id="book-release-week" value="">
@example HTML Attributes
<%= # ... week_field :release_week, class: "form-control" %> <!-- output --> <input type="week" name="book[release_week]" id="book-release-week" value="" class="form-control">
# File lib/hanami/helpers/form_helper/form_builder.rb, line 720 def week_field(name, attributes = {}) input _attributes(:week, name, attributes) end
Protected Instance Methods
A set of options to pass to the sub form helpers.
@api private @since 0.2.0
# File lib/hanami/helpers/form_helper/form_builder.rb, line 1548 def options Hash[name: @name, values: @values, verb: @verb, csrf_token: @csrf_token] end
Private Instance Methods
Return a set of default HTML attributes
@api private @since 0.2.0
# File lib/hanami/helpers/form_helper/form_builder.rb, line 1594 def _attributes(type, name, attributes) attrs = { type: type, name: _displayed_input_name(name), id: _input_id(name), value: _value(name) } attrs.merge!(attributes) attrs[:value] = escape_html(attrs[:value]) attrs end
HTML attributes for check box
@api private @since 0.2.0
@see Hanami::Helpers::FormHelper::FormBuilder#check_box
# File lib/hanami/helpers/form_helper/form_builder.rb, line 1672 def _attributes_for_check_box(name, attributes) attributes = { type: :checkbox, name: _displayed_input_name(name), id: _input_id(name), value: attributes.delete(:checked_value) || DEFAULT_CHECKED_VALUE }.merge(attributes) attributes[:checked] = CHECKED if _check_box_checked?(attributes[:value], _value(name)) attributes end
@api private
# File lib/hanami/helpers/form_helper/form_builder.rb, line 1729 def _check_box_checked?(value, input_value) !input_value.nil? && (input_value.to_s == value.to_s || input_value.is_a?(TrueClass) || input_value.is_a?(Array) && input_value.include?(value)) end
Input name
HTML attribute
@api private @since 1.0.0
# File lib/hanami/helpers/form_helper/form_builder.rb, line 1614 def _displayed_input_name(name) _input_name(name).gsub(/\[\d+\]/, '[]') end
Input for
HTML attribute
@api private @since 0.2.0
# File lib/hanami/helpers/form_helper/form_builder.rb, line 1641 def _for(content, name) case name when String, Hanami::Utils::String name else _input_id(name || content) end end
Input id
HTML attribute
@api private @since 0.2.0
# File lib/hanami/helpers/form_helper/form_builder.rb, line 1622 def _input_id(name) name = _input_name(name).gsub(/\[(?<token>[[[:word:]]\-]*)\]/, INPUT_ID_REPLACEMENT) Utils::String.dasherize(name) end
Full input name, used to construct the input attributes.
@api private @since 0.2.0
# File lib/hanami/helpers/form_helper/form_builder.rb, line 1606 def _input_name(name) "#{@name}[#{name}]" end
@api private @since 1.2.0
# File lib/hanami/helpers/form_helper/form_builder.rb, line 1706 def _is_current_value?(input_value, value) return unless input_value value.to_s == input_value.to_s end
@api private @since 1.2.0
# File lib/hanami/helpers/form_helper/form_builder.rb, line 1722 def _is_in_input_values?(multiple, input_value, value) return unless multiple && input_value.is_a?(Array) input_value.include?(value) end
@api private @since 1.2.0
# File lib/hanami/helpers/form_helper/form_builder.rb, line 1714 def _is_in_selected_values?(multiple, selected, value) return unless multiple && selected.is_a?(Array) selected.include?(value) end
Prepare for method override
@api private @since 0.2.0
# File lib/hanami/helpers/form_helper/form_builder.rb, line 1566 def _method_override! if BROWSER_METHODS.include?(@verb_method) @attributes[:method] = @verb_method else @attributes[:method] = DEFAULT_METHOD @verb = @verb_method end end
@api private
# File lib/hanami/helpers/form_helper/form_builder.rb, line 1686 def _select_input_name(name, multiple) select_name = _displayed_input_name(name) select_name = "#{select_name}[]" if multiple select_name end
@api private
# File lib/hanami/helpers/form_helper/form_builder.rb, line 1693 def _select_option_selected?(value, selected, input_value, multiple) if input_value && selected.nil? value.to_s == input_value.to_s else (value == selected) || _is_in_selected_values?(multiple, selected, value) || _is_current_value?(input_value, value) || _is_in_input_values?(multiple, input_value, value) end end
Input value
HTML attribute
@api private @since 0.2.0
# File lib/hanami/helpers/form_helper/form_builder.rb, line 1631 def _value(name) @values.get( *_input_name(name).split(/[\[\]]+/).map(&:to_sym) ) end
Return CSRF Protection token from view context
@api private @since 0.2.0
# File lib/hanami/helpers/form_helper/form_builder.rb, line 1586 def csrf_token @context.csrf_token if @context.respond_to?(:csrf_token) && !EXCLUDED_CSRF_METHODS.include?(@verb_method) end
Check the current builder is top-level
@api private @since 0.2.0
# File lib/hanami/helpers/form_helper/form_builder.rb, line 1558 def toplevel? @attributes.any? end
Return the method from attributes
@api private
# File lib/hanami/helpers/form_helper/form_builder.rb, line 1578 def verb_method (@attributes.fetch(:method) { DEFAULT_METHOD }).to_s.upcase end