Class: Hanami::Helpers::FormHelper::FormBuilder

Inherits:
HtmlHelper::HtmlBuilder show all
Includes:
EscapeHelper
Defined in:
gems/gems/hanami-helpers-1.3.0/lib/hanami/helpers/form_helper/form_builder.rb

Overview

Form builder

See Also:

Since:

  • 0.2.0

Instance Method Summary collapse

Methods included from EscapeHelper

#escape_html, #escape_html_attribute, #escape_url, #raw

Methods inherited from HtmlHelper::HtmlBuilder

#text

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Hanami::Helpers::HtmlHelper::HtmlBuilder

Instance Method Details

#button(content, attributes = {}) ⇒ Object #button(attributes = {}, &blk) ⇒ Object

Button

Examples:

Basic usage

<%=
  # ...
  button 'Click me'
%>

<!-- output -->
<button>Click me</button>

HTML Attributes

<%=
  # ...
  button 'Click me', class: "btn btn-secondary"
%>

<!-- output -->
<button class="btn btn-secondary">Click me</button>

Block

<%=
  # ...
  button class: "btn btn-secondary" do
    span class: 'oi oi-check'
  end
%>

<!-- output -->
<button class="btn btn-secondary">
  <span class="oi oi-check"></span>
</button>

Overloads:

  • #button(content, attributes = {}) ⇒ Object

    Use string content

    Parameters:

    • content (String)

      The content

    • attributes (Hash) (defaults to: {})

      HTML attributes to pass to the button tag

  • #button(attributes = {}, &blk) ⇒ Object

    Use block content

    Parameters:

    • attributes (Hash) (defaults to: {})

      HTML attributes to pass to the button tag

    • blk (Proc)

      the block content

Since:

  • 1.0.0

def button(content, attributes = {}, &blk)
  if content.is_a?(::Hash)
    attributes = content
    content = nil
  end

  super
end

#check_box(name, attributes = {}) ⇒ Object

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.

Examples:

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">

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">

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">

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">

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">

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">

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">

Parameters:

  • name (Symbol)

    the input name

  • attributes (Hash) (defaults to: {})

    HTML attributes to pass to the input tag

Options Hash (attributes):

  • :checked_value (String) — default: defaults to "1"
  • :unchecked_value (String) — default: defaults to "0"

Since:

  • 0.2.0

def check_box(name, attributes = {})
  _hidden_field_for_check_box(name, attributes)
  input _attributes_for_check_box(name, attributes)
end

#color_field(name, attributes = {}) ⇒ Object

Color input

Examples:

Basic usage

<%=
  # ...
  color_field :background
%>

<!-- output -->
<input type="color" name="user[background]" id="user-background" value="">

HTML Attributes

<%=
  # ...
  color_field :background, class: "form-control"
%>

<!-- output -->
<input type="color" name="user[background]" id="user-background" value="" class="form-control">

Parameters:

  • name (Symbol)

    the input name

  • attributes (Hash) (defaults to: {})

    HTML attributes to pass to the input tag

Since:

  • 0.2.0

def color_field(name, attributes = {})
  input _attributes(:color, name, attributes)
end

#datalist(name, values, list, attributes = {}) ⇒ Object

Datalist input

Examples:

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>

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>

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>

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>

Parameters:

  • name (Symbol)

    the input name

  • values (Array, Hash)

    a collection that is transformed into <option> tags.

  • list (String)

    the name of list for the text input, it's also the id of datalist

  • attributes (Hash) (defaults to: {})

    HTML attributes to pass to the input tag

Since:

  • 0.4.0

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_field(name, attributes = {}) ⇒ Object

Date input

Examples:

Basic usage

<%=
  # ...
  date_field :birth_date
%>

<!-- output -->
<input type="date" name="user[birth_date]" id="user-birth-date" value="">

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">

Parameters:

  • name (Symbol)

    the input name

  • attributes (Hash) (defaults to: {})

    HTML attributes to pass to the input tag

Since:

  • 0.2.0

def date_field(name, attributes = {})
  input _attributes(:date, name, attributes)
end

#datetime_field(name, attributes = {}) ⇒ Object

Datetime input

Examples:

Basic usage

<%=
  # ...
  datetime_field :delivered_at
%>

<!-- output -->
<input type="datetime" name="delivery[delivered_at]" id="delivery-delivered-at" value="">

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">

Parameters:

  • name (Symbol)

    the input name

  • attributes (Hash) (defaults to: {})

    HTML attributes to pass to the input tag

Since:

  • 0.2.0

def datetime_field(name, attributes = {})
  input _attributes(:datetime, name, attributes)
end

#datetime_local_field(name, attributes = {}) ⇒ Object

Datetime Local input

Examples:

Basic usage

<%=
  # ...
  datetime_local_field :delivered_at
%>

<!-- output -->
<input type="datetime-local" name="delivery[delivered_at]" id="delivery-delivered-at" value="">

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">

Parameters:

  • name (Symbol)

    the input name

  • attributes (Hash) (defaults to: {})

    HTML attributes to pass to the input tag

Since:

  • 0.2.0

def datetime_local_field(name, attributes = {})
  input _attributes(:datetime-local', name, attributes)
end

#email_field(name, attributes = {}) ⇒ Object

Email input

Examples:

Basic usage

<%=
  # ...
  email_field :email
%>

<!-- output -->
<input type="email" name="user[email]" id="user-email" value="">

HTML Attributes

<%=
  # ...
  email_field :email, class: "form-control"
%>

<!-- output -->
<input type="email" name="user[email]" id="user-email" value="" class="form-control">

Parameters:

  • name (Symbol)

    the input name

  • attributes (Hash) (defaults to: {})

    HTML attributes to pass to the input tag

Since:

  • 0.2.0

def email_field(name, attributes = {})
  input _attributes(:email, name, attributes)
end

#fields_for(name, value = nil) {|index| ... } ⇒ Object

Nested fields

The inputs generated by the wrapped block will be prefixed with the given name It supports infinite levels of nesting.

Examples:

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>

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>

Parameters:

  • name (Symbol)

    the nested name, it's used to generate input names, ids, and to lookup params to fill values.

Yields:

  • (index)

Yield Parameters:

  • index (Integer)

    iterative index (it starts from zero)

Since:

  • 0.2.0

def fields_for(name, value = nil)
  current_name = @name
  @name        = _input_name(name)
  yield(name, value)
ensure
  @name = current_name
end

#fields_for_collection(name) {|index, value| ... } ⇒ Object

Nested collections

Supports nesting for collections, with infinite levels of nesting.

Examples:

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>

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>

Parameters:

  • name (Symbol)

    the nested name, it's used to generate input names, ids, and to lookup params to fill values.

Yields:

  • (index, value)

Yield Parameters:

  • index (Integer)

    iterative index (it starts from zero)

  • value (Object)

    an item of the collection

Since:

  • 0.2.0

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(content = nil, attributes = {}) ⇒ Object

Fieldset

Examples:

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>

Parameters:

  • content (Symbol, String, NilClass) (defaults to: nil)

    the content

  • attributes (Hash) (defaults to: {})

    HTML attributes to pass to the label tag

Since:

  • 1.0.0

def fieldset(content = nil, attributes = {})
  # This is here only for documentation purposes
  super
end

#file_field(name, attributes = {}) ⇒ Object

File input

PLEASE REMEMBER TO ADD enctype: 'multipart/form-data' ATTRIBUTE TO THE FORM

Examples:

Basic usage

<%=
  # ...
  file_field :avatar
%>

<!-- output -->
<input type="file" name="user[avatar]" id="user-avatar">

HTML Attributes

<%=
  # ...
  file_field :avatar, class: "avatar-upload"
%>

<!-- output -->
<input type="file" name="user[avatar]" id="user-avatar" class="avatar-upload">

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">

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">

Accepted multiple file upload (as array)

<%=
  # ...
  file_field :resume, multiple: true
%>

<!-- output -->
<input type="file" name="user[resume]" id="user-resume" multiple="multiple">

Parameters:

  • name (Symbol)

    the input name

  • attributes (Hash) (defaults to: {})

    HTML attributes to pass to the input tag

Options Hash (attributes):

  • :accept (String, Array)

    Optional set of accepted MIME Types

  • :multiple (TrueClass, FalseClass)

    Optional, allow multiple file upload

Since:

  • 0.2.0

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

#hidden_field(name, attributes = {}) ⇒ Object

Hidden input

Examples:

Basic usage

<%=
  # ...
  hidden_field :customer_id
%>

<!-- output -->
<input type="hidden" name="delivery[customer_id]" id="delivery-customer-id" value="">

Parameters:

  • name (Symbol)

    the input name

  • attributes (Hash) (defaults to: {})

    HTML attributes to pass to the input tag

Since:

  • 0.2.0

def hidden_field(name, attributes = {})
  input _attributes(:hidden, name, attributes)
end

#image_button(source, attributes = {}) ⇒ Object

Image button

Visual submit button

Please note: for security reasons, please use the absolute URL of the image

Examples:

Basic usage

<%=
  # ...
  image_button "https://hanamirb.org/assets/button.png"
%>

<!-- output -->
<input type="image" src="https://hanamirb.org/assets/button.png">

HTML Attributes

<%=
  # ...
  image_button "https://hanamirb.org/assets/button.png", name: "image", width: "50"
%>

<!-- output -->
<input name="image" width="50" type="image" src="https://hanamirb.org/assets/button.png">

Parameters:

  • source (String)

    The absolute URL of the image

  • attributes (Hash) (defaults to: {})

    HTML attributes to pass to the button tag

Since:

  • 1.0.0

def image_button(source, attributes = {})
  attrs = attributes.dup
  attrs[:type] = :image
  attrs[:src]  = escape_url(source)

  input attrs
end

#label(content, attributes = {}) ⇒ Object

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.

Examples:

Basic usage

<%=
  # ...
  label :extended_title
%>

<!-- output -->
<label for="book-extended-title">Extended title</label>

HTML attributes

<%=
  # ...
  label :title, class: "form-label"
%>

<!-- output -->
<label for="book-title" class="form-label">Title</label>

Custom content

<%=
  # ...
  label 'Title', for: :extended_title
%>

<!-- output -->
<label for="book-extended-title">Title</label>

Custom “for” attribute

<%=
  # ...
  label :extended_title, for: 'ext-title'
%>

<!-- output -->
<label for="ext-title">Extended title</label>

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="">

Parameters:

  • content (Symbol, String)

    the field name or a content string

  • attributes (Hash) (defaults to: {})

    HTML attributes to pass to the label tag

Since:

  • 0.2.0

def label(content, attributes = {})
  attributes = { for: _for(content, attributes.delete(:for)) }.merge(attributes)
  content    = case content
               when String, Hanami::Utils::String
                 content
               else
                 Utils::String.capitalize(content)
               end

  super(content, attributes)
end

#month_field(name, attributes = {}) ⇒ Object

Month field

Examples:

Basic usage

<%=
  # ...
  month_field :release_month
%>

<!-- output -->
<input type="month" name="book[release_month]" id="book-release-month" value="">

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">

Parameters:

  • name (Symbol)

    the input name

  • attributes (Hash) (defaults to: {})

    HTML attributes to pass to the input tag

Since:

  • 1.0.0

def month_field(name, attributes = {})
  input _attributes(:month, name, attributes)
end

#number_field(name, attributes = {}) ⇒ Object

Number input

You can also make use of the max, min, and step attributes for the HTML5 number field.

Examples:

Basic usage

<%=
  # ...
  number_field :percent_read
%>

<!-- output -->
<input type="number" name="book[percent_read]" id="book-percent-read" value="">

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">

Parameters:

  • name (Symbol)

    the input name

  • attributes (Hash) (defaults to: {})

    HTML attributes to pass to the number input

Since:

  • 0.2.0

def number_field(name, attributes = {})
  input _attributes(:number, name, attributes)
end

#password_field(name, attributes = {}) ⇒ Object

Password input

Examples:

Basic usage

<%=
  # ...
  password_field :password
%>

<!-- output -->
<input type="password" name="signup[password]" id="signup-password" value="">

Parameters:

  • name (Symbol)

    the input name

  • attributes (Hash) (defaults to: {})

    HTML attributes to pass to the input tag

Since:

  • 0.2.0

def password_field(name, attributes = {})
  input({ type: :password, name: _displayed_input_name(name), id: _input_id(name), value: nil }.merge(attributes))
end

#radio_button(name, value, attributes = {}) ⇒ Object

Radio input

If request params have a value that corresponds to the given value, it automatically sets the checked attribute. This Hanami::Controller integration happens without any developer intervention.

Examples:

Basic usage

<%=
  # ...
  radio_button :category, 'Fiction'
  radio_button :category, 'Non-Fiction'
%>

<!-- output -->
<input type="radio" name="book[category]" value="Fiction">
<input type="radio" name="book[category]" value="Non-Fiction">

HTML Attributes

<%=
  # ...
  radio_button :category, 'Fiction', class: "form-check"
  radio_button :category, 'Non-Fiction', class: "form-check"
%>

<!-- output -->
<input type="radio" name="book[category]" value="Fiction" class="form-check">
<input type="radio" name="book[category]" value="Non-Fiction" class="form-check">

Automatic checked value

# Given the following params:
#
# book: {
#   category: 'Non-Fiction'
# }

<%=
  # ...
  radio_button :category, 'Fiction'
  radio_button :category, 'Non-Fiction'
%>

<!-- output -->
<input type="radio" name="book[category]" value="Fiction">
<input type="radio" name="book[category]" value="Non-Fiction" checked="checked">

Parameters:

  • name (Symbol)

    the input name

  • value (String)

    the input value

  • attributes (Hash) (defaults to: {})

    HTML attributes to pass to the input tag

Since:

  • 0.2.0

def radio_button(name, value, attributes = {})
  attributes = { type: :radio, name: _displayed_input_name(name), value: value }.merge(attributes)
  attributes[:checked] = CHECKED if _value(name).to_s == value.to_s
  input(attributes)
end

#range_field(name, attributes = {}) ⇒ Object

Range input

You can also make use of the max, min, and step attributes for the HTML5 number field.

Examples:

Basic usage

<%=
  # ...
  range_field :discount_percentage
%>

<!-- output -->
<input type="range" name="book[discount_percentage]" id="book-discount-percentage" value="">

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">

Parameters:

  • name (Symbol)

    the input name

  • attributes (Hash) (defaults to: {})

    HTML attributes to pass to the number input

Since:

  • 1.0.0

def range_field(name, attributes = {})
  input _attributes(:range, name, attributes)
end

#search_field(name, attributes = {}) ⇒ Object

Search input

Examples:

Basic usage

<%=
  # ...
  search_field :q
%>

<!-- output -->
<input type="search" name="search[q]" id="search-q" value="">

HTML Attributes

<%=
  # ...
  search_field :q, class: "form-control"
%>

<!-- output -->
<input type="search" name="search[q]" id="search-q" value="" class="form-control">

Parameters:

  • name (Symbol)

    the input name

  • attributes (Hash) (defaults to: {})

    HTML attributes to pass to the input tag

Since:

  • 1.0.0

def search_field(name, attributes = {})
  input _attributes(:search, name, attributes)
end

#select(name, values, attributes = {}) ⇒ Object

Select input

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.

Examples:

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>

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>

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>

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>

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>

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>Select a store</option>
  <option value="it">Italy</option>
  <option value="us">United States</option>
</select>

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>

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>

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>

Parameters:

  • name (Symbol)

    the input name

  • values (Hash)

    a Hash to generate <option> tags.

  • attributes (Hash) (defaults to: {})

    HTML attributes to pass to the input tag

Since:

  • 0.2.0

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) unless prompt.nil?

    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(content, attributes = {}) ⇒ Object #submit(attributes = {}, &blk) ⇒ Object

Submit button

Examples:

Basic usage

<%=
  # ...
  submit 'Create'
%>

<!-- output -->
<button type="submit">Create</button>

HTML Attributes

<%=
  # ...
  submit 'Create', class: "btn btn-primary"
%>

<!-- output -->
<button type="submit" class="btn btn-primary">Create</button>

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>

Overloads:

  • #submit(content, attributes = {}) ⇒ Object

    Use string content

    Parameters:

    • content (String)

      The content

    • attributes (Hash) (defaults to: {})

      HTML attributes to pass to the button tag

  • #submit(attributes = {}, &blk) ⇒ Object

    Use block content

    Parameters:

    • attributes (Hash) (defaults to: {})

      HTML attributes to pass to the button tag

    • blk (Proc)

      the block content

Since:

  • 0.2.0

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

#tel_field(name, attributes = {}) ⇒ Object

Telephone input

Examples:

Basic usage

<%=
  # ...
  tel_field :telephone
%>

<!-- output -->
<input type="tel" name="user[telephone]" id="user-telephone" value="">

HTML Attributes

<%=
  # ...
  telurl_field :telephone, class: "form-control"
%>

<!-- output -->
<input type="tel" name="user[telephone]" id="user-telephone" value="" class="form-control">

Parameters:

  • name (Symbol)

    the input name

  • attributes (Hash) (defaults to: {})

    HTML attributes to pass to the input tag

Since:

  • 1.0.0

def tel_field(name, attributes = {})
  input _attributes(:tel, name, attributes)
end

#text_area(name, content = nil, attributes = {}) ⇒ Object

Text-area input

Examples:

Basic usage

<%=
  # ...
  text_area :hobby
%>

<!-- output -->
<textarea name="user[hobby]" id="user-hobby"></textarea>

Set content

<%=
  # ...
  text_area :hobby, 'Football'
%>

<!-- output -->
<textarea name="user[hobby]" id="user-hobby">Football</textarea>

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>

Omit content and specify HTML attributes

<%=
  # ...
  text_area :hobby, class: 'form-control'
%>

<!-- output -->
<textarea name="user[hobby]" id="user-hobby" class="form-control"></textarea>

Force blank value

<%=
  # ...
  text_area :hobby, '', class: 'form-control'
%>

<!-- output -->
<textarea name="user[hobby]" id="user-hobby" class="form-control"></textarea>

Parameters:

  • name (Symbol)

    the input name

  • content (String) (defaults to: nil)

    the content of the textarea

  • attributes (Hash) (defaults to: {})

    HTML attributes to pass to the textarea tag

Since:

  • 0.2.5

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_field(name, attributes = {}) ⇒ Object Also known as: input_text

Text input

Examples:

Basic usage

<%=
  # ...
  text_field :first_name
%>

<!-- output -->
<input type="text" name="user[first_name]" id="user-first-name" value="">

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">

Parameters:

  • name (Symbol)

    the input name

  • attributes (Hash) (defaults to: {})

    HTML attributes to pass to the input tag

Since:

  • 0.2.0

def text_field(name, attributes = {})
  input _attributes(:text, name, attributes)
end

#time_field(name, attributes = {}) ⇒ Object

Time field

Examples:

Basic usage

<%=
  # ...
  time_field :release_hour
%>

<!-- output -->
<input type="time" name="book[release_hour]" id="book-release-hour" value="">

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">

Parameters:

  • name (Symbol)

    the input name

  • attributes (Hash) (defaults to: {})

    HTML attributes to pass to the input tag

Since:

  • 1.0.0

def time_field(name, attributes = {})
  input _attributes(:time, name, attributes)
end

#url_field(name, attributes = {}) ⇒ Object

URL input

Examples:

Basic usage

<%=
  # ...
  url_field :website
%>

<!-- output -->
<input type="url" name="user[website]" id="user-website" value="">

HTML Attributes

<%=
  # ...
  url_field :website, class: "form-control"
%>

<!-- output -->
<input type="url" name="user[website]" id="user-website" value="" class="form-control">

Parameters:

  • name (Symbol)

    the input name

  • attributes (Hash) (defaults to: {})

    HTML attributes to pass to the input tag

Since:

  • 1.0.0

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(name, attributes = {}) ⇒ Object

Week field

Examples:

Basic usage

<%=
  # ...
  week_field :release_week
%>

<!-- output -->
<input type="week" name="book[release_week]" id="book-release-week" value="">

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">

Parameters:

  • name (Symbol)

    the input name

  • attributes (Hash) (defaults to: {})

    HTML attributes to pass to the input tag

Since:

  • 1.0.0

def week_field(name, attributes = {})
  input _attributes(:week, name, attributes)
end