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

Inherits:
HtmlHelper::HtmlBuilder show all
Defined in:
lib/hanami/helpers/form_helper/form_builder.rb

Overview

Form builder

See Also:

Since:

  • 0.2.0

Constant Summary collapse

BROWSER_METHODS =

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

Set of HTTP methods that are understood by web browsers

Since:

  • 0.2.0

%w(GET POST).freeze
EXCLUDED_CSRF_METHODS =

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

Set of HTTP methods that should NOT generate CSRF token

Since:

  • 0.2.0

%w(GET).freeze
CHECKED =

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

Checked attribute value

See Also:

Since:

  • 0.2.0

'checked'.freeze
SELECTED =

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

Selected attribute value for option

See Also:

Since:

  • 0.2.0

'selected'.freeze
ACCEPT_SEPARATOR =

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

Separator for accept attribute of file input

See Also:

  • #file_input

Since:

  • 0.2.0

','.freeze
INPUT_ID_REPLACEMENT =

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

Replacement for input id interpolation

See Also:

Since:

  • 0.2.0

'-\k<token>'.freeze
DEFAULT_UNCHECKED_VALUE =

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

Default value for unchecked check box

See Also:

Since:

  • 0.2.0

'0'.freeze
DEFAULT_CHECKED_VALUE =

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

Default value for checked check box

See Also:

Since:

  • 0.2.0

'1'.freeze

Constants inherited from HtmlHelper::HtmlBuilder

HtmlHelper::HtmlBuilder::CONTENT_TAGS, HtmlHelper::HtmlBuilder::EMPTY_TAGS, HtmlHelper::HtmlBuilder::NEWLINE

Instance Method Summary collapse

Methods inherited from HtmlHelper::HtmlBuilder

#empty_tag, #encode, #fragment, #method_missing, #nested?, #resolve, #tag, #text

Constructor Details

#initialize(form, attributes, params, &blk) ⇒ Hanami::Helpers::FormHelper::FormBuilder #initialize(form, attributes, params, &blk) ⇒ Hanami::Helpers::FormHelper::FormBuilder

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.

Instantiate a form builder

Overloads:

  • #initialize(form, attributes, params, &blk) ⇒ Hanami::Helpers::FormHelper::FormBuilder

    Top level form

    Parameters:

    • form (Hanami::Helpers:FormHelper::Form)

      the form

    • attributes (::Hash)

      a set of HTML attributes

    • params (Hanami::Action::Params)

      request params

    • blk (Proc)

      a block that describes the contents of the form

  • #initialize(form, attributes, params, &blk) ⇒ Hanami::Helpers::FormHelper::FormBuilder

    Nested form

    Parameters:

    • form (Hanami::Helpers:FormHelper::Form)

      the form

    • attributes (Hanami::Helpers::FormHelper::Values)

      user defined values

    • blk (Proc)

      a block that describes the contents of the form

Since:

  • 0.2.0


99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 99

def initialize(form, attributes, context = nil, &blk) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
  super()

  @context    = context
  @blk        = blk
  @verb       = nil
  @csrf_token = nil

  # Nested form
  if @context.nil? && attributes.is_a?(Values)
    @values      = attributes
    @attributes  = {}
    @name        = form
  else
    @form        = form
    @name        = form.name
    @values      = Values.new(form.values, @context.params)
    @attributes  = attributes
    @verb_method = verb_method
    @csrf_token  = csrf_token
  end
end

Dynamic Method Handling

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

Instance Method Details

#_attributes(type, name, attributes) ⇒ Object (private)

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.

Return a set of default HTML attributes

Since:

  • 0.2.0


959
960
961
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 959

def _attributes(type, name, attributes)
  { type: type, name: _input_name(name), id: _input_id(name), value: _value(name) }.merge(attributes)
end

#_attributes_for_check_box(name, attributes) ⇒ Object (private)

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.

HTML attributes for check box

See Also:

Since:

  • 0.2.0


1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 1025

def _attributes_for_check_box(name, attributes)
  attributes = {
    type:  :checkbox,
    name:  _input_name(name),
    id:    _input_id(name),
    value: attributes.delete(:checked_value) || DEFAULT_CHECKED_VALUE
  }.merge(attributes)

  value = _value(name)
  attributes[:checked] = CHECKED if !value.nil? &&
                                    (value == attributes[:value] || value.include?(attributes[:value]))

  attributes
end

#_for(content, name) ⇒ Object (private)

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.

Input for HTML attribute

Since:

  • 0.2.0


994
995
996
997
998
999
1000
1001
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 994

def _for(content, name)
  case name
  when String, Hanami::Utils::String
    name
  else
    _input_id(name || content)
  end
end

#_hidden_field_for_check_box(name, attributes) ⇒ Object (private)

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.

Hidden field for check box

See Also:

Since:

  • 0.2.0


1009
1010
1011
1012
1013
1014
1015
1016
1017
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 1009

def _hidden_field_for_check_box(name, attributes)
  return unless attributes[:value].nil? || !attributes[:unchecked_value].nil?

  input(
    type:  :hidden,
    name:  attributes[:name] || _input_name(name),
    value: attributes.delete(:unchecked_value) || DEFAULT_UNCHECKED_VALUE
  )
end

#_input_id(name) ⇒ Object (private)

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.

Input id HTML attribute

Since:

  • 0.2.0


975
976
977
978
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 975

def _input_id(name)
  name = _input_name(name).gsub(/\[(?<token>[[[:word:]]\-]*)\]/, INPUT_ID_REPLACEMENT)
  Utils::String.new(name).dasherize
end

#_input_name(name) ⇒ Object (private)

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.

Input name HTML attribute

Since:

  • 0.2.0


967
968
969
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 967

def _input_name(name)
  "#{@name}[#{name}]"
end

#_method_override!Object (private)

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.

Prepare for method override

Since:

  • 0.2.0


931
932
933
934
935
936
937
938
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 931

def _method_override!
  if BROWSER_METHODS.include?(@verb_method)
    @attributes[:method] = @verb_method
  else
    @attributes[:method] = DEFAULT_METHOD
    @verb                = @verb_method
  end
end

#_select_input_name(name, multiple) ⇒ Object (private)

Since:

  • 0.2.0


1040
1041
1042
1043
1044
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 1040

def _select_input_name(name, multiple)
  select_name = _input_name(name)
  select_name = "#{select_name}[]" if multiple
  select_name
end

#_select_option_selected?(value, selected, input_value, multiple) ⇒ Boolean (private)

TODO: this has to be refactored

rubocop:disable Metrics/CyclomaticComplexity rubocop:disable Metrics/PerceivedComplexity

Returns:

  • (Boolean)

Since:

  • 0.2.0


1050
1051
1052
1053
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 1050

def _select_option_selected?(value, selected, input_value, multiple)
  value == selected || (multiple && (selected.is_a?(Array) && selected.include?(value))) ||
    value == input_value || (multiple && (input_value.is_a?(Array) && input_value.include?(value)))
end

#_value(name) ⇒ Object (private)

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.

Input value HTML attribute

Since:

  • 0.2.0


984
985
986
987
988
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 984

def _value(name)
  @values.get(
    *_input_name(name).split(/[\[\]]+/).map(&:to_sym)
  )
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">

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


357
358
359
360
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 357

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

Parameters:

  • name (Symbol)

    the input name

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

    HTML attributes to pass to the input tag

Since:

  • 0.2.0


377
378
379
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 377

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

#csrf_tokenObject (private)

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.

Return CSRF Protection token from view context

Since:

  • 0.2.0


951
952
953
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 951

def csrf_token
  @context.csrf_token if @context.respond_to?(:csrf_token) && !EXCLUDED_CSRF_METHODS.include?(@verb_method)
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


871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 871

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

Parameters:

  • name (Symbol)

    the input name

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

    HTML attributes to pass to the input tag

Since:

  • 0.2.0


396
397
398
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 396

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

Parameters:

  • name (Symbol)

    the input name

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

    HTML attributes to pass to the input tag

Since:

  • 0.2.0


415
416
417
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 415

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

Parameters:

  • name (Symbol)

    the input name

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

    HTML attributes to pass to the input tag

Since:

  • 0.2.0


434
435
436
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 434

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

Parameters:

  • name (Symbol)

    the input name

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

    HTML attributes to pass to the input tag

Since:

  • 0.2.0


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

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

#fields_for(name) ⇒ 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="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="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.

Since:

  • 0.2.0


198
199
200
201
202
203
204
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 198

def fields_for(name)
  current_name = @name
  @name        = _input_name(name)
  yield
ensure
  @name = current_name
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">

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


522
523
524
525
526
527
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 522

def file_field(name, attributes = {})
  attributes[:accept] = Array(attributes[:accept]).join(ACCEPT_SEPARATOR) if attributes.key?(:accept)
  attributes = { type: :file, name: _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


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

def hidden_field(name, attributes = {})
  input _attributes(:hidden, name, attributes)
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.

# Output:
#  <label for="book-extended-title">Extended title</label>

# Output:
#  <label for="book-extended-title">Title</label>

# Output:
#  <label for="ext-title">Extended title</label>

# Output:
#  <label for="delivery-address-city">City</label>
#  <input type="text" name="delivery[address][city] id="delivery-address-city" value="">

Examples:

Basic usage

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

Custom content

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

Custom “for” attribute

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

Nested fields usage

<%=
  # ...
  fields_for :address do
    label :city
    text_field :city
  end
%>

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


256
257
258
259
260
261
262
263
264
265
266
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 256

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.new(content).capitalize
               end

  super(content, 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


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

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


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

def password_field(name, attributes = {})
  input({ type: :password, name: _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">

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


679
680
681
682
683
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 679

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

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

Select input

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 :stores, values
%>

# Output:
#  <select name="book[store]" id="book-store">
#    <option value="it">Italy</option>
#    <option value="us">United States</option>
#  </select>

Automatic selected option

# Given the following params:
#
# book: {
#   store: 'it'
# }

<%=
  # ...
  values = Hash['it' => 'Italy', 'us' => 'United States']
  select :stores, 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['it' => 'Italy', 'us' => 'United States']
  select :stores, 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['it' => 'Italy', 'us' => 'United States']
  select :stores, 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>

Multiple select

<%=
  # ...
  values = Hash['it' => 'Italy', 'us' => 'United States']
  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>

Parameters:

  • name (Symbol)

    the input name

  • values (Hash)

    a Hash to generate <option> tags. Values correspond to value and keys correspond to the content.

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

    HTML attributes to pass to the input tag

Since:

  • 0.2.0


788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 788

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

  super(attributes) do
    option(prompt) unless prompt.nil?

    values.each do |content, value|
      if _select_option_selected?(value, selected, _value(name), attributes[: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 button

Examples:

Basic usage

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

# Output:
#  <button type="submit">Create</button>

Parameters:

  • content (String)

    The content

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

    HTML attributes to pass to the button tag

Since:

  • 0.2.0


902
903
904
905
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 902

def submit(content, attributes = {})
  attributes = { type: :submit }.merge(attributes)
  button(content, 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


610
611
612
613
614
615
616
617
618
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 610

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) }.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="">

Parameters:

  • name (Symbol)

    the input name

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

    HTML attributes to pass to the input tag

Since:

  • 0.2.0


635
636
637
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 635

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

#to_sHanami::Utils::Escape::SafeString

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.

Resolves all the nodes and generates the markup

Returns:

  • (Hanami::Utils::Escape::SafeString)

    the output

See Also:

Since:

  • 0.2.0


131
132
133
134
135
136
137
138
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 131

def to_s
  if toplevel?
    _method_override!
    form(@blk, @attributes)
  end

  super
end

#toplevel?Boolean (private)

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.

Check the current builder is top-level

Returns:

  • (Boolean)

Since:

  • 0.2.0


923
924
925
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 923

def toplevel?
  @attributes.any?
end

#verb_methodObject (private)

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.

Return the method from attributes

Since:

  • 0.2.0


943
944
945
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 943

def verb_method
  (@attributes.fetch(:method) { DEFAULT_METHOD }).to_s.upcase
end