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



1125
1126
1127
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 1125

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



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

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



431
432
433
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 431

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



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

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



452
453
454
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 452

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



473
474
475
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 473

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



494
495
496
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 494

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



578
579
580
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 578

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 colletion, starting from zero

  • the (Object)

    value of the element from the collection

Since:

  • 2.1.0



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

def fields_for_collection(name, &block)
  collection_base_name = [base_name, name.to_s].compact.join(INPUT_NAME_SEPARATOR)

  _value(name).each_with_index do |value, index|
    fields_for("#{collection_base_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



328
329
330
331
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 328

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



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

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



639
640
641
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 639

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



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

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



1221
1222
1223
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 1221

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



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

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



536
537
538
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 536

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



701
702
703
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 701

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



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

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



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

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



724
725
726
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 724

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



800
801
802
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 800

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



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

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, 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_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



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

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



622
623
624
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 622

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



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

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



778
779
780
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 778

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



515
516
517
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 515

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



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

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



557
558
559
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 557

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