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

Inherits:
Object
  • Object
show all
Includes:
View::Helpers::EscapeHelper, View::Helpers::TagHelper
Defined in:
lib/hanami/helpers/form_helper/form_builder.rb

Overview

A range of convenient methods for building the fields within an HTML form, integrating with request params and template locals to populate the fields with appropriate values.

See Also:

Since:

  • 2.1.0

Instance Method Summary collapse

Constructor Details

#initialize(inflector:, form_attributes:, base_name: nil, values: Values.new) ⇒ self

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new form builder.

Parameters:

  • inflector (Dry::Inflector)

    the app inflector

  • base_name (String, nil) (defaults to: nil)

    the base name to use for all fields in the form

  • values (Hanami::Helpers::FormHelper::Values) (defaults to: Values.new)

    the values for the form

See Also:

Since:

  • 2.1.0



109
110
111
112
113
114
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 109

def initialize(inflector:, form_attributes:, base_name: nil, values: Values.new)
  @base_name = base_name
  @values = values
  @form_attributes = form_attributes
  @inflector = inflector
end

Instance Method Details

#button(content, **attributes) ⇒ String #button(**attributes, &block) ⇒ String

Returns a button tag.

Examples:

Basic usage

f.button("Click me")
=> <button>Click me</button>

HTML Attributes

f.button("Click me", class: "btn btn-secondary")
=> <button class="btn btn-secondary">Click me</button>

Returning content from a block

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

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

Overloads:

  • #button(content, **attributes) ⇒ String

    Returns a button tag with the given content.

    Parameters:

    • content (String)

      the content for the tag

    • attributes (Hash)

      the tag’s HTML attributes

  • #button(**attributes, &block) ⇒ String

    Returns a button tag with the return value of the given block as the tag’s content.

    Parameters:

    • attributes (Hash)

      the tag’s HTML attributes

    Yield Returns:

    • (String)

      the tag content

Returns:

  • (String)

    the tag

Since:

  • 2.1.0



1123
1124
1125
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 1123

def button(...)
  tag.button(...)
end

#call(content, **attributes) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Since:

  • 2.1.0



118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 118

def call(content, **attributes)
  attributes["accept-charset"] ||= DEFAULT_CHARSET

  method_override, original_form_method = _form_method(attributes)
  csrf_token, token = _csrf_token(values, attributes)

  tag.form(**attributes) do
    (+"").tap { |inner|
      inner << input(type: "hidden", name: "_method", value: original_form_method) if method_override
      inner << input(type: "hidden", name: "_csrf_token", value: token) if csrf_token
      inner << content
    }.html_safe
  end
end

#check_box(name, **attributes) ⇒ String

Returns the tags for a check box.

When editing a resource, the form automatically assigns the ‘checked` HTML attribute for the check box tag.

Returns a hidden input tag in preceding the check box input tag. This ensures that unchecked values are submitted with the form.

Examples:

Basic usage

f.check_box("delivery.free_shipping")

# =>
<input type="hidden" name="delivery[free_shipping]" value="0">
<input type="checkbox" name="delivery[free_shipping]" id="delivery-free-shipping" value="1">

HTML Attributes

f.check_box("delivery.free_shipping", class: "form-check-input")

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

Specifying checked and unchecked values

f.check_box("delivery.free_shipping", checked_value: "true", unchecked_value: "false")

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

# Given the request params:
# {delivery: {free_shipping: "1"}}
f.check_box("delivery.free_shipping")

=>
<input type="hidden" name="delivery[free_shipping]" value="0">
<input type="checkbox" name="delivery[free_shipping]" id="delivery-free-shipping" value="1" checked="checked">

Forcing the “checked” attribute

# Given the request params:
# {delivery: {free_shipping: "0"}}
f.check_box("deliver.free_shipping", checked: "checked")

=>
<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 for an array of values

f.check_box("book.languages", name: "book[languages][]", value: "italian", id: nil)
f.check_box("book.languages", name: "book[languages][]", value: "english", id: nil)

=>
<input type="checkbox" name="book[languages][]" value="italian">
<input type="checkbox" name="book[languages][]" value="english">

Automatic “checked” attribute for an array of values

# Given the request params:
# {book: {languages: ["italian"]}}
f.check_box("book.languages", name: "book[languages][]", value: "italian", id: nil)
f.check_box("book.languages", name: "book[languages][]", value: "english", id: nil)

=>
<input type="checkbox" name="book[languages][]" value="italian" checked="checked">
<input type="checkbox" name="book[languages][]" value="english">

Parameters:

  • name (String)

    the input name

  • attributes (Hash)

    the HTML attributes for the check box tag

Options Hash (**attributes):

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

Returns:

  • (String)

    the tags

Since:

  • 2.1.0



405
406
407
408
409
410
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 405

def check_box(name, **attributes)
  (+"").tap { |output|
    output << _hidden_field_for_check_box(name, attributes).to_s
    output << input(**_attributes_for_check_box(name, attributes))
  }.html_safe
end

#color_field(name, **attributes) ⇒ String

Returns a color input tag.

Examples:

Basic usage

f.color_field("user.background")
=> <input type="color" name="user[background]" id="user-background" value="">

HTML Attributes

f.color_field("user.background", class: "form-control")
=> <input type="color" name="user[background]" id="user-background" value="" class="form-control">

Parameters:

  • name (String)

    the input name

  • attributes (Hash)

    the tag’s HTML attributes

Returns:

  • (String)

    the tag

Since:

  • 2.1.0



429
430
431
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 429

def color_field(name, **attributes)
  input(**_attributes(:color, name, attributes))
end

#datalist(name, values, list, **attributes) ⇒ String

Returns a datalist input tag.

Examples:

Basic Usage

values = ["Italy", "Australia"]
f.datalist("book.stores", values, "books")

=>
<input type="text" name="book[store]" id="book-store" value="" list="books">
<datalist id="books">
  <option value="Italy"></option>
  <option value="Australia"></option>
</datalist>

Options As Hash

values = Hash["Italy" => "it", "Australia" => "au"]
f.datalist("book.stores", values, "books")

=>
<input type="text" name="book[store]" id="book-store" value="" list="books">
<datalist id="books">
  <option value="Italy">it</option>
  <option value="Australia">au</option>
</datalist>

Specifying custom attributes for the datalist input

values = ["Italy", "Australia"]
f.datalist "book.stores", values, "books", datalist: {class: "form-control"}

=>
<input type="text" name="book[store]" id="book-store" value="" list="books">
<datalist id="books" class="form-control">
  <option value="Italy"></option>
  <option value="Australia"></option>
</datalist>

Specifying custom attributes for the options list

values = ["Italy", "Australia"]
f.datalist("book.stores", values, "books", options: {class: "form-control"})

=>
<input type="text" name="book[store]" id="book-store" value="" list="books">
<datalist id="books">
  <option value="Italy" class="form-control"></option>
  <option value="Australia" class="form-control"></option>
</datalist>

Parameters:

  • name (String)

    the input name

  • values (Array, Hash)

    a collection that is transformed into ‘<option>` tags

  • list (String)

    the name of list for the text input; also the id of datalist

  • attributes (Hash)

    the tag’s HTML attributes

Returns:

  • (String)

    the tag

Since:

  • 2.1.0



1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 1068

def datalist(name, values, list, **attributes)
  options = attributes.delete(:options) || {}
  datalist = attributes.delete(:datalist) || {}

  attributes[:list] = list
  datalist[:id] = list

  (+"").tap { |output|
    output << text_field(name, **attributes)
    output << tag.datalist(**datalist) {
      (+"").tap { |inner|
        values.each do |value, content|
          inner << tag.option(content, value: value, **options)
        end
      }.html_safe
    }
  }.html_safe
end

#date_field(name, **attributes) ⇒ String

Returns a date input tag.

Examples:

Basic usage

f.date_field("user.birth_date")
# => <input type="date" name="user[birth_date]" id="user-birth-date" value="">

HTML Attributes

f.date_field("user.birth_date", class: "form-control")
=> <input type="date" name="user[birth_date]" id="user-birth-date" value="" class="form-control">

Parameters:

  • name (String)

    the input name

  • attributes (Hash)

    the tag’s HTML attributes

Returns:

  • (String)

    the tag

Since:

  • 2.1.0



450
451
452
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 450

def date_field(name, **attributes)
  input(**_attributes(:date, name, attributes))
end

#datetime_field(name, **attributes) ⇒ String

Returns a datetime input tag.

Examples:

Basic usage

f.datetime_field("delivery.delivered_at")
=> <input type="datetime" name="delivery[delivered_at]" id="delivery-delivered-at" value="">

HTML Attributes

f.datetime_field("delivery.delivered_at", class: "form-control")
=> <input type="datetime" name="delivery[delivered_at]" id="delivery-delivered-at" value="" class="form-control">

Parameters:

  • name (String)

    the input name

  • attributes (Hash)

    the tag’s HTML attributes

Returns:

  • (String)

    the tag

Since:

  • 2.1.0



471
472
473
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 471

def datetime_field(name, **attributes)
  input(**_attributes(:datetime, name, attributes))
end

#datetime_local_field(name, **attributes) ⇒ String

Returns a datetime-local input tag.

Examples:

Basic usage

f.datetime_local_field("delivery.delivered_at")
=> <input type="datetime-local" name="delivery[delivered_at]" id="delivery-delivered-at" value="">

HTML Attributes

f.datetime_local_field("delivery.delivered_at", class: "form-control")
=> <input type="datetime-local" name="delivery[delivered_at]" id="delivery-delivered-at" value="" class="form-control">

Parameters:

  • name (String)

    the input name

  • attributes (Hash)

    the tag’s HTML attributes

Returns:

  • (String)

    the tag

Since:

  • 2.1.0



492
493
494
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 492

def datetime_local_field(name, **attributes)
  input(**_attributes(:"datetime-local", name, attributes))
end

#email_field(name, **attributes) ⇒ String

Returns an email input tag.

Examples:

Basic usage

f.email_field("user.email")
=> <input type="email" name="user[email]" id="user-email" value="">

HTML Attributes

f.email_field("user.email", class: "form-control")
=> <input type="email" name="user[email]" id="user-email" value="" class="form-control">

Parameters:

  • name (String)

    the input name

  • attributes (Hash)

    the tag’s HTML attributes

Returns:

  • (String)

    the tag

Since:

  • 2.1.0



576
577
578
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 576

def email_field(name, **attributes)
  input(**_attributes(:email, name, attributes))
end

#fields_for(name, *yield_args) {|the| ... } ⇒ Object

Applies the base input name to all fields within the given block.

This can be helpful when generating a set of nested fields.

This is a convenience only. You can achieve the same result by including the base name at the beginning of each input name.

Examples:

Basic usage

<% f.fields_for "address" do |fa| %>
  <%= fa.text_field "street" %>
  <%= fa.text_field "suburb" %>
<% end %>

# A convenience for:
# <%= f.text_field "address.street" %>
# <%= f.text_field "address.suburb" %>

=>
<input type="text" name="delivery[customer_name]" id="delivery-customer-name" value="">
<input type="text" name="delivery[address][street]" id="delivery-address-street" value="">

Multiple levels of nesting

<% f.fields_for "address" do |fa| %>
  <%= fa.text_field "street" %>

  <% fa.fields_for "location" do |fl| %>
    <%= fl.text_field "city" %>
  <% end %>
<% end %>

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

Parameters:

  • name (String)

    the base name to be used for all fields in the block

Yield Parameters:

  • the (FormBuilder)

    form builder for the nested fields

Since:

  • 2.1.0



172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 172

def fields_for(name, *yield_args)
  new_base_name = [base_name, name.to_s].compact.join(INPUT_NAME_SEPARATOR)

  builder = self.class.new(
    base_name: new_base_name,
    values: values,
    form_attributes: form_attributes,
    inflector: inflector
  )

  yield(builder, *yield_args)
end

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

Yields to the given block for each element in the matching collection value, and applies the base input name to all fields within the block.

Use this whenever generating form fields for an collection of nested fields.

Examples:

Basic usage

<% f.fields_for_collection("addresses") do |fa| %>
  <%= fa.text_field("street") %>
<% end %>

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

Yielding index and value

<% f.fields_for_collection("bill.addresses") do |fa, i, address| %>
  <div class="form-group">
    Address id: <%= address.id %>
    <%= fa.label("street") %>
    <%= fa.text_field("street", data: {index: i.to_s}) %>
  </div>
<% end %>

=>
<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" data-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" data-index="1">
</div>

Parameters:

  • name (String)

    the input name, also used as the base input name for all fields within the block

Yield Parameters:

  • the (FormBuilder)

    form builder for the nested fields

  • the (Integer)

    index of the iteration over the collection, starting from zero

  • the (Object)

    value of the element from the collection

Since:

  • 2.1.0



228
229
230
231
232
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 228

def fields_for_collection(name, &block)
  _value(name).each_with_index do |value, index|
    fields_for("#{name}.#{index}", index, value, &block)
  end
end

#fieldset(**attributes, &block) ⇒ String

Returns a fieldset tag.

Examples:

<%= f.fieldset do %>
  <%= f.legend("Author") %>
  <%= f.label("author.name") %>
  <%= f.text_field("author.name") %>
<% end %>

# =>
<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:

  • attributes (Hash)

    the tag’s HTML attributes

Yield Returns:

  • (String)

    the tag’s content

Returns:

  • (String)

    the tag

Since:

  • 2.1.0



326
327
328
329
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 326

def fieldset(...)
  # This is here only for documentation purposes
  tag.fieldset(...)
end

#file_field(name, **attributes) ⇒ String

Returns a file input tag.

Examples:

Basic usage

f.file_field("user.avatar")
=> <input type="file" name="user[avatar]" id="user-avatar">

HTML Attributes

f.file_field("user.avatar", class: "avatar-upload")
=> <input type="file" name="user[avatar]" id="user-avatar" class="avatar-upload">

Accepted MIME Types

f.file_field("user.resume", accept: "application/pdf,application/ms-word")
=> <input type="file" name="user[resume]" id="user-resume" accept="application/pdf,application/ms-word">

f.file_field("user.resume", accept: ["application/pdf", "application/ms-word"])
=> <input type="file" name="user[resume]" id="user-resume" accept="application/pdf,application/ms-word">

Accept multiple file uploads

f.file_field("user.resume", multiple: true)
=> <input type="file" name="user[resume]" id="user-resume" multiple="multiple">

Parameters:

  • name (String)

    the input name

  • attributes (Hash)

    the tag’s HTML attributes

Options Hash (**attributes):

  • :accept (String, Array)

    Optional set of accepted MIME Types

  • :multiple (Boolean)

    allow multiple file upload

Returns:

  • (String)

    the tag

Since:

  • 2.1.0



671
672
673
674
675
676
677
678
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 671

def file_field(name, **attributes)
  form_attributes[:enctype] = "multipart/form-data"

  attributes[:accept] = Array(attributes[:accept]).join(ACCEPT_SEPARATOR) if attributes.key?(:accept)
  attributes = {type: :file, name: _input_name(name), id: _input_id(name), **attributes}

  input(**attributes)
end

#hidden_field(name, **attributes) ⇒ String

Returns a hidden input tag.

Examples:

f.hidden_field("delivery.customer_id")
=> <input type="hidden" name="delivery[customer_id]" id="delivery-customer-id" value="">

Parameters:

  • name (String)

    the input name

  • attributes (Hash)

    the tag’s HTML attributes

Returns:

  • (String)

    the tag

Since:

  • 2.1.0



637
638
639
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 637

def hidden_field(name, **attributes)
  input(**_attributes(:hidden, name, attributes))
end

#image_button(source, **attributes) ⇒ String

Returns an image input tag, to be used as a visual button for the form.

For security reasons, you should use the absolute URL of the given image.

Examples:

Basic usage

f.image_button("https://hanamirb.org/assets/button.png")
=> <input type="image" src="https://hanamirb.org/assets/button.png">

HTML Attributes

f.image_button("https://hanamirb.org/assets/button.png", name: "image", width: "50")
=> <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)

    the tag’s HTML attributes

Returns:

  • (String)

    the tag

Since:

  • 2.1.0



1146
1147
1148
1149
1150
1151
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 1146

def image_button(source, **attributes)
  attributes[:type] = :image
  attributes[:src] = sanitize_url(source)

  input(**attributes)
end

#inputString

Returns an input tag.

Generates an input tag without any special handling. For more convenience and other advanced features, see the other methods of the form builder.

Examples:

Basic usage

f.input(type: :text, name: "book[title]", id: "book-title", value: book.title)
=> <input type="text" name="book[title]" id="book-title" value="Hanami book">

Parameters:

  • attributes (Hash)

    the tag’s HTML attributes

Yield Returns:

  • (String)

    the tag content

Returns:

  • (String)

    the tag

Since:

  • 2.1.0

  • 2.1.0



1219
1220
1221
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 1219

def input(...)
  tag.input(...)
end

#label(field_name, **attributes) ⇒ String #label(content, **attributes) ⇒ String #label(field_name, **attributes, &block) ⇒ String

Returns a label tag.

Overloads:

  • #label(field_name, **attributes) ⇒ String

    Returns a label tag for the given field name, with a humanized version of the field name as the tag’s content.

    Examples:

    <%= f.label("book.extended_title") %>
    # => <label for="book-extended-title">Extended title</label>

    HTML attributes

    <%= f.label("book.title", class: "form-label") %>
    # => <label for="book-title" class="form-label">Title</label>

    Parameters:

    • field_name (String)

      the field name

    • attributes (Hash)

      the tag attributes

  • #label(content, **attributes) ⇒ String

    Returns a label tag for the field name given as ‘for:`, with the given content string as the tag’s content.

    Examples:

    <%= f.label("Title", for: "book.extended_title") %>
    # => <label for="book-extended-title">Title</label>
    
    f.label("book.extended_title", for: "ext-title")
    # => <label for="ext-title">Extended title</label>

    Parameters:

    • content (String)

      the tag’s content

    • for (String)

      the field name

    • attributes (Hash)

      the tag attributes

  • #label(field_name, **attributes, &block) ⇒ String

    Returns a label tag for the given field name, with the return value of the given block as the tag’s content.

    Examples:

    <%= f.label for: "book.free_shipping" do %>
      Free shipping
      <abbr title="optional" aria-label="optional">*</abbr>
    <% end %>
    
    # =>
    <label for="book-free-shipping">
      Free shipping
      <abbr title="optional" aria-label="optional">*</abbr>
    </label>

    Parameters:

    • field_name (String)

      the field name

    • attributes (Hash)

      the tag attributes

    Yield Returns:

    • (String)

      the tag content

Returns:

  • (String)

    the tag

Since:

  • 2.1.0



290
291
292
293
294
295
296
297
298
299
300
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 290

def label(content = nil, **attributes, &block)
  for_attribute_given = attributes.key?(:for)

  attributes[:for] = _input_id(attributes[:for] || content)

  if content && !for_attribute_given
    content = inflector.humanize(content.to_s.split(INPUT_NAME_SEPARATOR).last)
  end

  tag.label(content, **attributes, &block)
end

#month_field(name, **attributes) ⇒ String

Returns a month input tag.

Examples:

Basic usage

f.month_field("book.release_month")
=> <input type="month" name="book[release_month]" id="book-release-month" value="">

HTML Attributes

f.month_field("book.release_month", class: "form-control")
=> <input type="month" name="book[release_month]" id="book-release-month" value="" class="form-control">

Parameters:

  • name (String)

    the input name

  • attributes (Hash)

    the tag’s HTML attributes

Returns:

  • (String)

    the tag

Since:

  • 2.1.0



534
535
536
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 534

def month_field(name, **attributes)
  input(**_attributes(:month, name, attributes))
end

#number_field(name, **attributes) ⇒ String

Returns a number input tag.

For this tag, you can make use of the ‘max`, `min`, and `step` HTML attributes.

Examples:

Basic usage

f.number_field("book.percent_read")
=> <input type="number" name="book[percent_read]" id="book-percent-read" value="">

Advanced attributes

f.number_field("book.percent_read", min: 1, max: 100, step: 1)
=> <input type="number" name="book[percent_read]" id="book-percent-read" value="" min="1" max="100" step="1">

Parameters:

  • name (String)

    the input name

  • attributes (Hash)

    the tag’s HTML attributes

Returns:

  • (String)

    the tag

Since:

  • 2.1.0



699
700
701
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 699

def number_field(name, **attributes)
  input(**_attributes(:number, name, attributes))
end

#password_field(name, **attributes) ⇒ String

Returns a password input tag.

Examples:

Basic usage

f.password_field("signup.password")
=> <input type="password" name="signup[password]" id="signup-password" value="">

Parameters:

  • name (String)

    the input name

  • attributes (Hash)

    the tag’s HTML attributes

Returns:

  • (String)

    the tag

Since:

  • 2.1.0



861
862
863
864
865
866
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 861

def password_field(name, **attributes)
  attrs = {type: :password, name: _input_name(name), id: _input_id(name), value: nil, **attributes}
  attrs[:value] = EMPTY_STRING if attrs[:value].nil?

  input(**attrs)
end

#radio_button(name, value, **attributes) ⇒ String

Returns a radio input tag.

When editing a resource, the form automatically assigns the ‘checked` HTML attribute for the tag.

Examples:

Basic usage

f.radio_button("book.category", "Fiction")
f.radio_button("book.category", "Non-Fiction")

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

HTML Attributes

f.radio_button("book.category", "Fiction", class: "form-check")
f.radio_button("book.category", "Non-Fiction", class: "form-check")

=>
<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 request params:
# {book: {category: "Non-Fiction"}}
f.radio_button("book.category", "Fiction")
f.radio_button("book.category", "Non-Fiction")

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

Parameters:

  • name (String)

    the input name

  • value (String)

    the input value

  • attributes (Hash)

    the tag’s HTML attributes

Returns:

  • (String)

    the tag

Since:

  • 2.1.0



841
842
843
844
845
846
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 841

def radio_button(name, value, **attributes)
  attributes = {type: :radio, name: _input_name(name), value: value, **attributes}
  attributes[:checked] = true if _value(name).to_s == value.to_s

  input(**attributes)
end

#range_field(name, **attributes) ⇒ String

Returns a range input tag.

For this tag, you can make use of the ‘max`, `min`, and `step` HTML attributes.

Examples:

Basic usage

f.range_field("book.discount_percentage")
=> <input type="range" name="book[discount_percentage]" id="book-discount-percentage" value="">

Advanced attributes

f.range_field("book.discount_percentage", min: 1, max: 1'0, step: 1)
=> <input type="number" name="book[discount_percentage]" id="book-discount-percentage" value="" min="1" max="100" step="1">

Parameters:

  • name (String)

    the input name

  • attributes (Hash)

    the tag’s HTML attributes

Returns:

  • (String)

    the tag

Since:

  • 2.1.0



722
723
724
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 722

def range_field(name, **attributes)
  input(**_attributes(:range, name, attributes))
end

#search_field(name, **attributes) ⇒ String

Returns a search input tag.

Examples:

Basic usage

f.search_field("search.q")
=> <input type="search" name="search[q]" id="search-q" value="">

HTML Attributes

f.search_field("search.q", class: "form-control")
=> <input type="search" name="search[q]" id="search-q" value="" class="form-control">

Parameters:

  • name (String)

    the input name

  • attributes (Hash)

    the tag’s HTML attributes

Returns:

  • (String)

    the tag

Since:

  • 2.1.0



798
799
800
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 798

def search_field(name, **attributes)
  input(**_attributes(:search, name, attributes))
end

#select(name, values, **attributes) ⇒ String

Returns a select input tag containing option tags for the given values.

The values should be an enumerable of pairs of content (the displayed text for the option) and value (the value for the option) strings.

When editing a resource, automatically assigns the ‘selected` HTML attribute for any option tags matching the resource’s values.

Examples:

Basic usage

values = {"Italy" => "it", "Australia" => "au"}
f.select("book.store", values)

=>
<select name="book[store]" id="book-store">
  <option value="it">Italy</option>
  <option value="au">Australia</option>
</select>

HTML Attributes

values = {"Italy" => "it", "Australia" => "au"}
f.select("book.store", values, class: "form-control")

=>
<select name="book[store]" id="book-store" class="form-control">
  <option value="it">Italy</option>
  <option value="au">Australia</option>
</select>

Selected options

# Given the following request params:
# {book: {store: "it"}}
values = {"Italy" => "it", "Australia" => "au"}
f.select("book.store", values)

=>
<select name="book[store]" id="book-store">
  <option value="it" selected="selected">Italy</option>
  <option value="au">Australia</option>
</select>

Prompt option

values = {"Italy" => "it", "Australia" => "au"}
f.select("book.store", values, options: {prompt: "Select a store"})

=>
<select name="book[store]" id="book-store">
  <option>Select a store</option>
  <option value="it">Italy</option>
  <option value="au">Australia</option>
</select>

Selected option

values = {"Italy" => "it", "Australia" => "au"}
f.select("book.store", values, options: {selected: "it"})

=>
<select name="book[store]" id="book-store">
  <option value="it" selected="selected">Italy</option>
  <option value="au">Australia</option>
</select>

Prompt option and HTML attributes

values = {"Italy" => "it", "Australia" => "au"}
f.select("book.store", values, options: {prompt: "Select a store"}, class: "form-control")

=>
<select name="book[store]" id="book-store" class="form-control">
  <option>Select a store</option>
  <option value="it">Italy</option>
  <option value="au">Australia</option>
</select>

Multiple select

values = {"Italy" => "it", "Australia" => "au"}
f.select("book.stores", values, multiple: true)

=>
<select name="book[store][]" id="book-store" multiple="multiple">
 <option value="it">Italy</option>
  <option value="au">Australia</option>
</select>

Multiple select and HTML attributes

values = {"Italy" => "it", "Australia" => "au"}
f.select("book.stores", values, multiple: true, class: "form-control")

=>
<select name="book[store][]" id="book-store" multiple="multiple" class="form-control">
  <option value="it">Italy</option>
  <option value="au">Australia</option>
</select>

Values as an array, supporting repeated entries

values = [["Italy", "it"],
          ["---", ""],
          ["Afghanistan", "af"],
          ...
          ["Italy", "it"],
          ...
          ["Zimbabwe", "zw"]]
f.select("book.stores", values)

=>
<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 (String)

    the input name

  • values (Hash)

    a Hash to generate ‘<option>` tags.

  • attributes (Hash)

    the tag’s HTML attributes

Returns:

  • (String)

    the tag

Since:

  • 2.1.0



989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 989

def select(name, values, **attributes) # rubocop:disable Metrics/AbcSize
  options = attributes.delete(:options) { {} }
  multiple = attributes[:multiple]
  attributes = {name: _select_input_name(name, multiple), id: _input_id(name), **attributes}
  prompt = options.delete(:prompt)
  selected = options.delete(:selected)
  input_value = _value(name)

  option_tags = []
  option_tags << tag.option(prompt) 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_tags << tag.option(content, value: value, selected: true, **options)
    else
      option_tags << tag.option(content, value: value, **options)
    end
  end

  tag.select(option_tags.join.html_safe, **attributes)
end

#submit(content, **attributes) ⇒ String #submit(**attributes, &blk) ⇒ String

Returns a submit button tag.

Examples:

Basic usage

f.submit("Create")
=> <button type="submit">Create</button>

HTML Attributes

f.submit("Create", class: "btn btn-primary")
=> <button type="submit" class="btn btn-primary">Create</button>

Returning content from a block

<%= f.submit(class: "btn btn-primary") do %>
  <span class="oi oi-check">
<% end %>

=>
<button type="submit" class="btn btn-primary">
  <span class="oi oi-check"></span>
</button>

Overloads:

  • #submit(content, **attributes) ⇒ String

    Returns a submit button tag with the given content.

    Parameters:

    • content (String)

      the content for the tag

    • attributes (Hash)

      the tag’s HTML attributes

  • #submit(**attributes, &blk) ⇒ String

    Returns a submit button tag with the return value of the given block as the tag’s content.

    Parameters:

    • attributes (Hash)

      the tag’s HTML attributes

    Yield Returns:

    • (String)

      the tag content

Returns:

  • (String)

    the tag

Since:

  • 2.1.0



1190
1191
1192
1193
1194
1195
1196
1197
1198
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 1190

def submit(content = nil, **attributes, &blk)
  if content.is_a?(::Hash)
    attributes = content
    content = nil
  end

  attributes = {type: :submit, **attributes}
  tag.button(content, **attributes, &blk)
end

#tel_field(name, **attributes) ⇒ String

Returns a telephone input tag.

Examples:

f.tel_field("user.telephone")
=> <input type="tel" name="user[telephone]" id="user-telephone" value="">

HTML Attributes

f.tel_field("user.telephone", class: "form-control")
=> <input type="tel" name="user[telephone]" id="user-telephone" value="" class="form-control">

Parameters:

  • name (String)

    the input name

  • attributes (Hash)

    the tag’s HTML attributes

Returns:

  • (String)

    the tag

Since:

  • 2.1.0



620
621
622
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 620

def tel_field(name, **attributes)
  input(**_attributes(:tel, name, attributes))
end

#text_area(name, content = nil, **attributes) ⇒ String

Returns a textarea tag.

Examples:

Basic usage

f.text_area("user.hobby")
=> <textarea name="user[hobby]" id="user-hobby"></textarea>

f.text_area "user.hobby", "Football"
=>
<textarea name="user[hobby]" id="user-hobby">
Football</textarea>

HTML attributes

f.text_area "user.hobby", class: "form-control"
=> <textarea name="user[hobby]" id="user-hobby" class="form-control"></textarea>

Parameters:

  • name (String)

    the input name

  • content (String) (defaults to: nil)

    the content of the textarea

  • attributes (Hash)

    the tag’s HTML attributes

Returns:

  • (String)

    the tag

Since:

  • 2.1.0



749
750
751
752
753
754
755
756
757
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 749

def text_area(name, content = nil, **attributes)
  if content.respond_to?(:to_hash)
    attributes = content
    content = nil
  end

  attributes = {name: _input_name(name), id: _input_id(name), **attributes}
  tag.textarea(content || _value(name), **attributes)
end

#text_field(name, **attributes) ⇒ String Also known as: input_text

Returns a text input tag.

Examples:

Basic usage

f.text_field("user.first_name")
=> <input type="text" name="user[first_name]" id="user-first-name" value="">

HTML Attributes

f.text_field("user.first_name", class: "form-control")
=> <input type="text" name="user[first_name]" id="user-first-name" value="" class="form-control">

Parameters:

  • name (String)

    the input name

  • attributes (Hash)

    the tag’s HTML attributes

Returns:

  • (String)

    the tag

Since:

  • 2.1.0



776
777
778
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 776

def text_field(name, **attributes)
  input(**_attributes(:text, name, attributes))
end

#time_field(name, **attributes) ⇒ String

Returns a time input tag.

Examples:

Basic usage

f.time_field("book.release_hour")
=> <input type="time" name="book[release_hour]" id="book-release-hour" value="">

HTML Attributes

f.time_field("book.release_hour", class: "form-control")
=> <input type="time" name="book[release_hour]" id="book-release-hour" value="" class="form-control">

Parameters:

  • name (String)

    the input name

  • attributes (Hash)

    the tag’s HTML attributes

Returns:

  • (String)

    the tag

Since:

  • 2.1.0



513
514
515
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 513

def time_field(name, **attributes)
  input(**_attributes(:time, name, attributes))
end

#url_field(name, **attributes) ⇒ String

Returns a URL input tag.

Examples:

Basic usage

f.url_field("user.website")
=> <input type="url" name="user[website]" id="user-website" value="">

HTML Attributes

f.url_field("user.website", class: "form-control")
=> <input type="url" name="user[website]" id="user-website" value="" class="form-control">

Parameters:

  • name (String)

    the input name

  • attributes (Hash)

    the tag’s HTML attributes

Returns:

  • (String)

    the tag

Since:

  • 2.1.0



597
598
599
600
601
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 597

def url_field(name, **attributes)
  attributes[:value] = sanitize_url(attributes.fetch(:value) { _value(name) })

  input(**_attributes(:url, name, attributes))
end

#week_field(name, **attributes) ⇒ String

Returns a week input tag.

Examples:

Basic usage

f.week_field("book.release_week")
=> <input type="week" name="book[release_week]" id="book-release-week" value="">

HTML Attributes

f.week_field("book.release_week", class: "form-control")
=> <input type="week" name="book[release_week]" id="book-release-week" value="" class="form-control">

Parameters:

  • name (String)

    the input name

  • attributes (Hash)

    the tag’s HTML attributes

Returns:

  • (String)

    the tag

Since:

  • 2.1.0



555
556
557
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 555

def week_field(name, **attributes)
  input(**_attributes(:week, name, attributes))
end