Class: Hanami::Helpers::FormHelper::FormBuilder
- Inherits:
-
HtmlHelper::HtmlBuilder
- Object
- HtmlHelper::HtmlBuilder
- Hanami::Helpers::FormHelper::FormBuilder
- Includes:
- EscapeHelper
- Defined in:
- lib/hanami/helpers/form_helper/form_builder.rb
Overview
Form builder
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
%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
%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
'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
'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
','.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
'-\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
'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
'1'.freeze
Constants inherited from HtmlHelper::HtmlBuilder
HtmlHelper::HtmlBuilder::CONTENT_TAGS, HtmlHelper::HtmlBuilder::EMPTY_TAGS, HtmlHelper::HtmlBuilder::NEWLINE
Instance Method Summary collapse
-
#button(content, attributes = {}, &blk) ⇒ Object
Button.
-
#check_box(name, attributes = {}) ⇒ Object
Check box.
-
#color_field(name, attributes = {}) ⇒ Object
Color input.
-
#datalist(name, values, list, attributes = {}) ⇒ Object
Datalist input.
-
#date_field(name, attributes = {}) ⇒ Object
Date input.
-
#datetime_field(name, attributes = {}) ⇒ Object
Datetime input.
-
#datetime_local_field(name, attributes = {}) ⇒ Object
Datetime Local input.
-
#email_field(name, attributes = {}) ⇒ Object
Email input.
-
#fields_for(name, value = nil) {|index| ... } ⇒ Object
Nested fields.
-
#fields_for_collection(name) {|index, value| ... } ⇒ Object
Nested collections.
-
#fieldset(content = nil, attributes = {}) ⇒ Object
Fieldset.
-
#file_field(name, attributes = {}) ⇒ Object
File input.
-
#hidden_field(name, attributes = {}) ⇒ Object
Hidden input.
-
#image_button(source, attributes = {}) ⇒ Object
Image button.
-
#initialize(form, attributes, context = nil, params = nil, &blk) ⇒ Hanami::Helpers::FormHelper::FormBuilder
constructor
private
Instantiate a form builder.
-
#label(content = nil, **attributes, &blk) ⇒ Object
Label tag.
-
#month_field(name, attributes = {}) ⇒ Object
Month field.
-
#number_field(name, attributes = {}) ⇒ Object
Number input.
-
#password_field(name, attributes = {}) ⇒ Object
Password input.
-
#radio_button(name, value, attributes = {}) ⇒ Object
Radio input.
-
#range_field(name, attributes = {}) ⇒ Object
Range input.
-
#search_field(name, attributes = {}) ⇒ Object
Search input.
-
#select(name, values, attributes = {}) ⇒ Object
Select input.
-
#submit(content, attributes = {}, &blk) ⇒ Object
Submit button.
-
#tel_field(name, attributes = {}) ⇒ Object
Telephone input.
-
#text_area(name, content = nil, attributes = {}) ⇒ Object
Text-area input.
-
#text_field(name, attributes = {}) ⇒ Object
(also: #input_text)
Text input.
-
#time_field(name, attributes = {}) ⇒ Object
Time field.
-
#to_s ⇒ Hanami::Utils::Escape::SafeString
private
Resolves all the nodes and generates the markup.
-
#url_field(name, attributes = {}) ⇒ Object
URL input.
-
#week_field(name, attributes = {}) ⇒ Object
Week field.
Methods inherited from HtmlHelper::HtmlBuilder
#empty_tag, #encode, #fragment, #method_missing, #nested?, #resolve, #respond_to_missing?, #tag, #text
Constructor Details
#initialize(form, attributes, context, 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
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 103 def initialize(form, attributes, context = nil, params = nil, &blk) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength super() @context = context @blk = blk @verb = nil @csrf_token = nil # Nested form if @context.nil? && attributes.is_a?(Values) @values = attributes @attributes = {} @name = form else @form = form @name = form.name @values = Values.new(form.values, params || @context.params) @attributes = attributes @verb_method = verb_method @csrf_token = csrf_token end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class Hanami::Helpers::HtmlHelper::HtmlBuilder
Instance Method Details
#button(content, attributes = {}) ⇒ Object #button(attributes = {}, &blk) ⇒ Object
Button
1443 1444 1445 1446 1447 1448 1449 1450 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 1443 def (content, attributes = {}, &blk) if content.is_a?(::Hash) attributes = content content = nil end super end |
#check_box(name, attributes = {}) ⇒ Object
Check box
It renders a check box input.
When a form is submitted, browsers don’t send the value of unchecked check boxes. If an user unchecks a check box, their browser won’t send the unchecked value. On the server side the corresponding value is missing, so the application will assume that the user action never happened.
To solve this problem the form renders a hidden field with the “unchecked value”. When the user unchecks the input, the browser will ignore it, but it will still send the value of the hidden input. See the examples below.
When editing a resource, the form automatically assigns the checked="checked"
attribute.
523 524 525 526 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 523 def check_box(name, attributes = {}) _hidden_field_for_check_box(name, attributes) input _attributes_for_check_box(name, attributes) end |
#color_field(name, attributes = {}) ⇒ Object
Color input
552 553 554 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 552 def color_field(name, attributes = {}) input _attributes(:color, name, attributes) end |
#datalist(name, values, list, attributes = {}) ⇒ Object
Datalist input
1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 1383 def datalist(name, values, list, attributes = {}) # rubocop:disable Metrics/MethodLength attrs = attributes.dup = 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()) end end end |
#date_field(name, attributes = {}) ⇒ Object
Date input
580 581 582 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 580 def date_field(name, attributes = {}) input _attributes(:date, name, attributes) end |
#datetime_field(name, attributes = {}) ⇒ Object
Datetime input
608 609 610 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 608 def datetime_field(name, attributes = {}) input _attributes(:datetime, name, attributes) end |
#datetime_local_field(name, attributes = {}) ⇒ Object
Datetime Local input
636 637 638 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 636 def datetime_local_field(name, attributes = {}) input _attributes(:'datetime-local', name, attributes) end |
#email_field(name, attributes = {}) ⇒ Object
Email input
748 749 750 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 748 def email_field(name, attributes = {}) input _attributes(:email, name, attributes) end |
#fields_for(name, value = nil) {|index| ... } ⇒ Object
Nested fields
The inputs generated by the wrapped block will be prefixed with the given name It supports infinite levels of nesting.
207 208 209 210 211 212 213 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 207 def fields_for(name, value = nil) current_name = @name @name = _input_name(name) yield(name, value) ensure @name = current_name end |
#fields_for_collection(name) {|index, value| ... } ⇒ Object
Nested collections
Supports nesting for collections, with infinite levels of nesting.
296 297 298 299 300 301 302 303 304 305 306 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 296 def fields_for_collection(name, &block) current_name = @name base_value = _value(name) @name = _input_name(name) base_value.each_with_index do |value, index| fields_for(index, value, &block) end ensure @name = current_name end |
#fieldset(content = nil, attributes = {}) ⇒ Object
Fieldset
420 421 422 423 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 420 def fieldset(content = nil, attributes = {}) # This is here only for documentation purposes super end |
#file_field(name, attributes = {}) ⇒ Object
File input
**PLEASE REMEMBER TO ADD enctype: 'multipart/form-data'
ATTRIBUTE TO THE FORM**
885 886 887 888 889 890 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 885 def file_field(name, attributes = {}) attributes[:accept] = Array(attributes[:accept]).join(ACCEPT_SEPARATOR) if attributes.key?(:accept) attributes = { type: :file, name: _displayed_input_name(name), id: _input_id(name) }.merge(attributes) input(attributes) end |
#hidden_field(name, attributes = {}) ⇒ Object
Hidden input
826 827 828 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 826 def hidden_field(name, attributes = {}) input _attributes(:hidden, name, attributes) end |
#image_button(source, attributes = {}) ⇒ Object
Image button
Visual submit button
**Please note:** for security reasons, please use the absolute URL of the image
1480 1481 1482 1483 1484 1485 1486 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 1480 def (source, attributes = {}) attrs = attributes.dup attrs[:type] = :image attrs[:src] = escape_url(source) input attrs end |
#label(content = nil, **attributes, &blk) ⇒ 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.
382 383 384 385 386 387 388 389 390 391 392 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 382 def label(content = nil, **attributes, &blk) attributes = { for: _for(content, attributes.delete(:for)) }.merge(attributes) content = case content when String, Hanami::Utils::String, NilClass content else Utils::String.capitalize(content) end super(content, attributes, &blk) end |
#month_field(name, attributes = {}) ⇒ Object
Month field
692 693 694 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 692 def month_field(name, attributes = {}) input _attributes(:month, name, attributes) end |
#number_field(name, attributes = {}) ⇒ Object
Number input
You can also make use of the ‘max`, `min`, and `step` attributes for the HTML5 number field.
917 918 919 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 917 def number_field(name, attributes = {}) input _attributes(:number, name, attributes) end |
#password_field(name, attributes = {}) ⇒ Object
Password input
1142 1143 1144 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 1142 def password_field(name, attributes = {}) input({ type: :password, name: _displayed_input_name(name), id: _input_id(name), value: nil }.merge(attributes)) end |
#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.
1121 1122 1123 1124 1125 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 1121 def (name, value, attributes = {}) attributes = { type: :radio, name: _displayed_input_name(name), value: value }.merge(attributes) attributes[:checked] = CHECKED if _value(name).to_s == value.to_s input(attributes) end |
#range_field(name, attributes = {}) ⇒ Object
Range input
You can also make use of the ‘max`, `min`, and `step` attributes for the HTML5 number field.
948 949 950 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 948 def range_field(name, attributes = {}) input _attributes(:range, name, attributes) end |
#search_field(name, attributes = {}) ⇒ Object
Search input
1067 1068 1069 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 1067 def search_field(name, attributes = {}) input _attributes(:search, name, attributes) end |
#select(name, values, attributes = {}) ⇒ Object
Select input
Values is used to generate the list of <option>
tags, it is an Enumerable
of pairs of content (the displayed text) and value (the tag’s attribute), in that respective order (please refer to the examples for more clarity).
If request params have a value that corresponds to one of the given values, it automatically sets the selected
attribute on the <option>
tag. This Hanami::Controller integration happens without any developer intervention.
1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 1297 def select(name, values, attributes = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength = attributes.delete(:options) { {} } multiple = attributes[:multiple] attributes = { name: _select_input_name(name, multiple), id: _input_id(name) }.merge(attributes) prompt = .delete(:prompt) selected = .delete(:selected) input_value = _value(name) super(attributes) do option(prompt, disabled: true) if prompt already_selected = nil values.each do |content, value| if (multiple || !already_selected) && (already_selected = _select_option_selected?(value, selected, input_value, multiple)) option(content, { value: value, selected: SELECTED }.merge()) else option(content, { value: value }.merge()) end end end end |
#submit(content, attributes = {}) ⇒ Object #submit(attributes = {}, &blk) ⇒ Object
Submit button
1532 1533 1534 1535 1536 1537 1538 1539 1540 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 1532 def submit(content, attributes = {}, &blk) if content.is_a?(::Hash) attributes = content content = nil end attributes = { type: :submit }.merge(attributes) (content, attributes, &blk) end |
#tel_field(name, attributes = {}) ⇒ Object
Telephone input
807 808 809 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 807 def tel_field(name, attributes = {}) input _attributes(:tel, name, attributes) end |
#text_area(name, content = nil, attributes = {}) ⇒ Object
Text-area input
1004 1005 1006 1007 1008 1009 1010 1011 1012 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 1004 def text_area(name, content = nil, attributes = {}) if content.respond_to?(:to_hash) attributes = content content = nil end attributes = { name: _displayed_input_name(name), id: _input_id(name) }.merge(attributes) textarea(content || _value(name), attributes) end |
#text_field(name, attributes = {}) ⇒ Object Also known as: input_text
Text input
1038 1039 1040 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 1038 def text_field(name, attributes = {}) input _attributes(:text, name, attributes) end |
#time_field(name, attributes = {}) ⇒ Object
Time field
664 665 666 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 664 def time_field(name, attributes = {}) input _attributes(:time, name, attributes) end |
#to_s ⇒ Hanami::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
135 136 137 138 139 140 141 142 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 135 def to_s if toplevel? _method_override! form(@blk, @attributes) end super end |
#url_field(name, attributes = {}) ⇒ Object
URL input
776 777 778 779 780 781 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 776 def url_field(name, attributes = {}) attrs = attributes.dup attrs[:value] = escape_url(attrs.fetch(:value) { _value(name) }) input _attributes(:url, name, attrs) end |
#week_field(name, attributes = {}) ⇒ Object
Week field
720 721 722 |
# File 'lib/hanami/helpers/form_helper/form_builder.rb', line 720 def week_field(name, attributes = {}) input _attributes(:week, name, attributes) end |