Module: Hanami::Helpers::FormHelper

Includes:
View::Helpers::TagHelper
Included in:
Extensions::View::StandardHelpers
Defined in:
lib/hanami/helpers/form_helper.rb,
lib/hanami/helpers/form_helper/values.rb,
lib/hanami/helpers/form_helper/form_builder.rb

Overview

Helper methods for generating HTML forms.

These helpers will be automatically available in your view templates, part classes and scope classes.

This module provides one primary method: #form_for, yielding an HTML form builder. This integrates with request params and template locals to populate the form with appropriate values.

Since:

  • 2.1.0

Defined Under Namespace

Classes: FormBuilder, Values

Constant Summary collapse

DEFAULT_METHOD =

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 HTTP method for form

Since:

  • 2.1.0

"POST"
DEFAULT_CHARSET =

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 charset

Since:

  • 2.1.0

"utf-8"
CSRF_TOKEN =

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.

CSRF Token session key

This name of this key is shared with the hanami and hanami-controller gems.

Since:

  • 2.1.0

:_csrf_token

Instance Method Summary collapse

Instance Method Details

#_form_csrf_tokenObject

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



206
207
208
209
210
# File 'lib/hanami/helpers/form_helper.rb', line 206

def _form_csrf_token
  return unless _context.request.session_enabled?

  _context.csrf_token
end

#_form_for_paramsObject

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



200
201
202
# File 'lib/hanami/helpers/form_helper.rb', line 200

def _form_for_params
  _context.request.params
end

#_form_for_valuesObject

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



188
189
190
191
192
193
194
195
196
# File 'lib/hanami/helpers/form_helper.rb', line 188

def _form_for_values
  if respond_to?(:_locals) # Scope
    _locals
  elsif respond_to?(:_name) # Part
    {_name => self}
  else
    {}
  end
end

#csrf_meta_tagsString?

Returns CSRF meta tags for use via unobtrusive JavaScript (UJS) libraries.

Examples:

csrf_meta_tags

=>
<meta name="csrf-param" content="_csrf_token">
<meta name="csrf-token" content="4a038be85b7603c406dcbfad4b9cdf91ec6ca138ed6441163a07bb0fdfbe25b5">

Returns:

  • (String, nil)

    the tags, if a CSRF token is available, or nil

Since:

  • 2.1.0



179
180
181
182
183
184
# File 'lib/hanami/helpers/form_helper.rb', line 179

def csrf_meta_tags
  return unless (token = _form_csrf_token)

  tag.meta(name: "csrf-param", content: CSRF_TOKEN) +
    tag.meta(name: "csrf-token", content: token)
end

#form_for(base_name, url, values: _form_for_values, params: _form_for_params, **attributes) {|f| ... } ⇒ String #form_for(url, values: _form_for_values, params: _form_for_params, **attributes) {|f| ... } ⇒ String

Yields a form builder for constructing an HTML form and returns the resulting form string.

See FormBuilder for the methods for building the form’s fields.

Examples:

Basic usage

<%= form_for("book", "/books", class: "form-horizontal") do |f| %>
  <div>
    <%= f.label "title" %>
    <%= f.text_field "title", class: "form-control" %>
  </div>

  <%= f.submit "Create" %>
<% end %>

=>
<form action="/books" method="POST" accept-charset="utf-8" class="form-horizontal">
  <input type="hidden" name="_csrf_token" value="920cd5bfaecc6e58368950e790f2f7b4e5561eeeab230aa1b7de1b1f40ea7d5d">
  <div>
    <label for="book-title">Title</label>
    <input type="text" name="book[title]" id="book-title" value="Test Driven Development">
  </div>

  <button type="submit">Create</button>
</form>

Without base name


<%= form_for("/books", class: "form-horizontal") do |f| %>
  <div>
    <%= f.label "books.title" %>
    <%= f.text_field "books.title", class: "form-control" %>
  </div>

  <%= f.submit "Create" %>
<% end %>

=>
<form action="/books" method="POST" accept-charset="utf-8" class="form-horizontal">
  <input type="hidden" name="_csrf_token" value="920cd5bfaecc6e58368950e790f2f7b4e5561eeeab230aa1b7de1b1f40ea7d5d">
  <div>
    <label for="book-title">Title</label>
    <input type="text" name="book[title]" id="book-title" value="Test Driven Development">
  </div>

  <button type="submit">Create</button>
</form>

Method override

<%= form_for("/books/123", method: :put) do |f|
  <%= f.text_field "book.title" %>
  <%= f.submit "Update" %>
<% end %>

=>
<form action="/books/123" accept-charset="utf-8" method="POST">
  <input type="hidden" name="_method" value="PUT">
  <input type="hidden" name="_csrf_token" value="920cd5bfaecc6e58368950e790f2f7b4e5561eeeab230aa1b7de1b1f40ea7d5d">
  <input type="text" name="book[title]" id="book-title" value="Test Driven Development">

  <button type="submit">Update</button>
</form>

Overriding values

<%= form_for("/songs", values: {song: {title: "Envision"}}) do |f| %>
  <%= f.text_field "song.title" %>
  <%= f.submit "Create" %>
<%= end %>

=>
<form action="/songs" accept-charset="utf-8" method="POST">
  <input type="hidden" name="_csrf_token" value="920cd5bfaecc6e58368950e790f2f7b4e5561eeeab230aa1b7de1b1f40ea7d5d">
  <input type="text" name="song[title]" id="song-title" value="Envision">

  <button type="submit">Create</button>
</form>

Overloads:

  • #form_for(base_name, url, values: _form_for_values, params: _form_for_params, **attributes) {|f| ... } ⇒ String

    Builds the form using the given base name for all fields.

    Parameters:

    • base_name (String)

      the base

    • url (String)

      the URL for submitting the form

    • values (Hash) (defaults to: _form_for_values)

      values to be used for populating form field values; optional, defaults to the template’s locals or to a part’s ‘=> self`

    • params (Hash) (defaults to: _form_for_params)

      request param values to be used for populating form field values; these are used in preference over the ‘values`; optional, defaults to the current request’s params

    • attributes (Hash)

      the HTML attributes for the form tag

    Yield Parameters:

  • #form_for(url, values: _form_for_values, params: _form_for_params, **attributes) {|f| ... } ⇒ String

    Parameters:

    • url (String)

      the URL for submitting the form

    • values (Hash) (defaults to: _form_for_values)

      values to be used for populating form field values; optional, defaults to the template’s locals or to a part’s ‘=> self`

    • params (Hash) (defaults to: _form_for_params)

      request param values to be used for populating form field values; these are used in preference over the ‘values`; optional, defaults to the current request’s params

    • attributes (Hash)

      the HTML attributes for the form tag

    Yield Parameters:

Returns:

  • (String)

    the form HTML

See Also:

Since:

  • 2.1.0



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/hanami/helpers/form_helper.rb', line 149

def form_for(base_name, url = nil, values: _form_for_values, params: _form_for_params, **attributes)
  url, base_name = base_name, nil if url.nil?

  values = Values.new(values: values, params: params, csrf_token: _form_csrf_token)

  builder = FormBuilder.new(
    base_name: base_name,
    values: values,
    inflector: _context.inflector,
    form_attributes: attributes
  )

  content = (block_given? ? yield(builder) : "").html_safe

  builder.call(content, action: url, **attributes)
end