модуль ActionView::Helpers::FormHelper
Справочные инструменты Action View для форм
Справочные инструменты для форм предназначены для упрощения работы с ресурсами по сравнению с использованием обычного HTML.
Обычно форма, предназначенная для создания или обновления ресурса, отражает идентификацию ресурса несколькими способами: (i) URL, к которому отправляется форма (атрибут элемента формы action) должен привести к маршрутизации запроса к соответствующему действию контроллера (с соответствующим параметром :id в случае существующего ресурса), (ii) имена полей ввода должны быть такими, чтобы в контроллере их значения отображались в соответствующих местах в хэше params, и (iii) для существующего ресурса, когда форма первоначально отображается, поля ввода, соответствующие атрибутам ресурса, должны отображать текущие значения этих атрибутов.
В Rails это обычно достигается путём создания формы с помощью form_with или form_for и ряда связанных вспомогательных методов. Эти методы генерируют соответствующий тег form и возвращают объект генератора формы, который знает модель, к которой относится форма. Поля ввода создаются путём вызова методов, определённых в генераторе формы, что позволяет генерировать соответствующие имена и значения по умолчанию, соответствующие атрибутам модели, а также удобные идентификаторы и т. д. Конвенции в сгенерированных именах полей позволяют контроллерам получать данные формы в виде красиво структурированного хэша params без каких-либо усилий с вашей стороны.
Например, для создания новой персоны вы обычно создаёте новый экземпляр Person в действии PeopleController#new, @person, и во шаблоне представления передаёте этот объект в form_with или form_for:
<%= form_with model: @person do |f| %> <%= f.label :first_name %>: <%= f.text_field :first_name %><br /> <%= f.label :last_name %>: <%= f.text_field :last_name %><br /> <%= f.submit %> <% end %>
Сгенерированный HTML для этого будет (с учётом форматирования):
<form action="/people" class="new_person" id="new_person" method="post"> <input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" /> <label for="person_first_name">First name</label>: <input id="person_first_name" name="person[first_name]" type="text" /><br /> <label for="person_last_name">Last name</label>: <input id="person_last_name" name="person[last_name]" type="text" /><br /> <input name="commit" type="submit" value="Create Person" /> </form>
Как вы видите, HTML отражает знания о ресурсе в нескольких местах, таких как путь, по которому должна отправляться форма, или имена полей ввода.
В частности, благодаря соглашениям, используемым в сгенерированных именах полей, контроллер получает вложенный хэш params[:person] с атрибутами персоны, заданными в форме. Этот хэш готов к передаче в Person.new:
@person = Person.new(params[:person]) if @person.save # success else # error handling end
Интересно, что тот же код представления в предыдущем примере можно использовать для редактирования персоны. Если @person является существующим ресурсом с именем «Иван Иванов» и ID 256, вышеприведённый код выдаст:
<form action="/people/256" class="edit_person" id="edit_person_256" method="post"> <input name="_method" type="hidden" value="patch" /> <input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" /> <label for="person_first_name">First name</label>: <input id="person_first_name" name="person[first_name]" type="text" value="John" /><br /> <label for="person_last_name">Last name</label>: <input id="person_last_name" name="person[last_name]" type="text" value="Smith" /><br /> <input name="commit" type="submit" value="Update Person" /> </form>
Обратите внимание, что конечная точка, значения по умолчанию и метка кнопки отправки настроены для @person. Это работает таким образом, потому что используемые вспомогательные методы знают, является ли ресурс новой записью или нет, и генерируют HTML соответственно.
Контроллер снова получит данные формы в params[:person], готовые к передаче в Person#update:
if @person.update(params[:person]) # success else # error handling end
Вот как обычно работают с ресурсами.
Публичные методы экземпляров
# File actionview/lib/action_view/helpers/form_helper.rb, line 1347
def checkbox(object_name, method, options = {}, checked_value = "1", unchecked_value = "0")
Tags::CheckBox.new(object_name, method, self, checked_value, unchecked_value, options).render
end Возвращает тег checkbox, настроенный для доступа к указанному атрибуту (определяемому method) объекта, назначенного шаблону (определяемому object). Этот объект должен быть экземпляром объекта (@object), а не локальным объектом. Ожидается, что method вернёт целое число, и если это целое число больше нуля, то checkbox будет отмечен. Дополнительные параметры тега input могут быть переданы в виде хэша с options. Значение checked_value по умолчанию равно 1, а значение по умолчанию unchecked_value установлено в 0, что удобно для булевых значений.
Параметры
-
Любые стандартные атрибуты HTML для тега могут быть переданы, например
:class. -
:checked-trueилиfalseпринудительно устанавливает состояние checkbox в отмеченное или не отмеченное. -
:include_hidden- Если установлено в false, вспомогательное скрытое поле, описанное ниже, не будет сгенерировано.
Особенности
Спецификация HTML гласит, что неотмеченные checkbox не отправляются, и поэтому веб-браузеры их не отправляют. К сожалению, это приводит к проблеме: если у модели Invoice установлен флаг paid, и в форме редактирования платного счета пользователь сбросил checkbox, параметр paid не отправляется. Таким образом, любое выражение массового присваивания, например
@invoice.update(params[:invoice])
не обновит флаг.
Для предотвращения этого, помощник генерирует вспомогательное скрытое поле перед каждым checkbox. Скрытое поле имеет то же имя, а его атрибуты имитируют неотмеченный checkbox.
Таким образом, клиент отправляет либо только скрытое поле (что указывает на то, что checkbox не отмечен), либо оба поля. Поскольку спецификация HTML гласит, что пары ключ/значение должны отправляться в том же порядке, в котором они появляются в форме, а извлечение параметров получает последнюю встречаемость любого повторяющегося ключа в строке запроса, это работает для обычных форм.
К сожалению, этот обходной путь не работает, когда checkbox находится внутри массивоподобного параметра, как в
<%= fields_for "project[invoice_attributes][]", invoice, index: nil do |form| %> <%= form.checkbox :paid %> ... <% end %>
потому что повторение имён параметров именно то, что Rails пытается различить элементы массива. Для каждого элемента с отмеченным checkbox вы получаете дополнительный "фантомный" элемент только с этим атрибутом, назначенным в «0».
В этом случае предпочтительно использовать checkbox_tag или использовать хэши вместо массивов.
Примеры
# Let's say that @article.validated? is 1:
checkbox("article", "validated")
# => <input name="article[validated]" type="hidden" value="0" />
# <input checked="checked" type="checkbox" id="article_validated" name="article[validated]" value="1" />
# Let's say that @puppy.gooddog is "no":
checkbox("puppy", "gooddog", {}, "yes", "no")
# => <input name="puppy[gooddog]" type="hidden" value="no" />
# <input type="checkbox" id="puppy_gooddog" name="puppy[gooddog]" value="yes" />
checkbox("eula", "accepted", { class: 'eula_check' }, "yes", "no")
# => <input name="eula[accepted]" type="hidden" value="no" />
# <input type="checkbox" class="eula_check" id="eula_accepted" name="eula[accepted]" value="yes" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1378
def color_field(object_name, method, options = {})
Tags::ColorField.new(object_name, method, self, options).render
end Возвращает text_field типа “color”.
color_field("car", "color")
# => <input id="car_color" name="car[color]" type="color" value="#000000" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1442
def date_field(object_name, method, options = {})
Tags::DateField.new(object_name, method, self, options).render
end Возвращает text_field типа “date”.
date_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="date" />
Значение по умолчанию генерируется, пытаясь вызвать strftime с «%Y-%m-%d» на значении объекта, что обеспечивает ожидаемое поведение для экземпляров DateTime и ActiveSupport::TimeWithZone. Вы можете переопределить это, явно передав параметр «value», например:
@user.born_on = Date.new(1984, 1, 27)
date_field("user", "born_on", value: "1984-05-12")
# => <input id="user_born_on" name="user[born_on]" type="date" value="1984-05-12" />
Вы можете создать значения для атрибутов «min» и «max», передав экземпляры Date или Time в хэш параметров.
date_field("user", "born_on", min: Date.today)
# => <input id="user_born_on" name="user[born_on]" type="date" min="2014-05-20" />
В качестве альтернативы, вы можете передать String, отформатированный как дата ISO8601, в качестве значений для «min» и «max».
date_field("user", "born_on", min: "2014-05-20")
# => <input id="user_born_on" name="user[born_on]" type="date" min="2014-05-20" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1515
def datetime_field(object_name, method, options = {})
Tags::DatetimeLocalField.new(object_name, method, self, options).render
end Возвращает text_field типа “datetime-local”.
datetime_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="datetime-local" />
Значение по умолчанию генерируется, пытаясь вызвать strftime с «%Y-%m-%dT%T» на значении объекта, что обеспечивает ожидаемое поведение для экземпляров DateTime и ActiveSupport::TimeWithZone.
@user.born_on = Date.new(1984, 1, 12)
datetime_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="datetime-local" value="1984-01-12T00:00:00" />
Вы можете создать значения для атрибутов «min» и «max», передав экземпляры Date или Time в хэш параметров.
datetime_field("user", "born_on", min: Date.today)
# => <input id="user_born_on" name="user[born_on]" type="datetime-local" min="2014-05-20T00:00:00.000" />
В качестве альтернативы, вы можете передать String, отформатированный как дата-время ISO8601, в качестве значений для «min» и «max».
datetime_field("user", "born_on", min: "2014-05-20T00:00:00")
# => <input id="user_born_on" name="user[born_on]" type="datetime-local" min="2014-05-20T00:00:00.000" />
По умолчанию, предоставляемые значения даты и времени будут отформатированы, включая секунды. Вы можете отобразить только дату, час и минуту, передав include_seconds: false.
@user.born_on = Time.current
datetime_field("user", "born_on", include_seconds: false)
# => <input id="user_born_on" name="user[born_on]" type="datetime-local" value="2014-05-20T14:35" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1569
def email_field(object_name, method, options = {})
Tags::EmailField.new(object_name, method, self, options).render
end Возвращает text_field типа “email”.
email_field("user", "address")
# => <input id="user_address" name="user[address]" type="email" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1080
def fields(scope = nil, model: nil, **options, &block)
options = { allow_method_names_outside_object: true, skip_default_ids: !form_with_generates_ids }.merge!(options)
if model
model = _object_for_form_builder(model)
scope ||= model_name_from_record_or_class(model).param_key
end
builder = instantiate_builder(scope, model, options)
capture(builder, &block)
end Ограничивает поля ввода с помощью явного ограничения или модели. Подобно тому, как form_with делает это с :scope или :model, за исключением того, что не выводит теги формы.
# Using a scope prefixes the input field names:
<%= fields :comment do |fields| %>
<%= fields.text_field :body %>
<% end %>
# => <input type="text" name="comment[body]">
# Using a model infers the scope and assigns field values:
<%= fields model: Comment.new(body: "full bodied") do |fields| %>
<%= fields.text_field :body %>
<% end %>
# => <input type="text" name="comment[body]" value="full bodied">
# Using +fields+ with +form_with+:
<%= form_with model: @article do |form| %>
<%= form.text_field :title %>
<%= form.fields :comment do |fields| %>
<%= fields.text_field :body %>
<% end %>
<% end %> Подобно form_with, передаётся экземпляр FormBuilder, связанный с ограничением или моделью, так что все сгенерированные имена полей имеют префикс, либо с переданным ограничением, либо с ограничением, полученным из :model.
Смешивание с другими помощниками форм
Хотя form_with использует объект FormBuilder, можно смешивать и сочетать автономные методы FormHelper и методы из FormTagHelper:
<%= fields model: @comment do |fields| %> <%= fields.text_field :body %> <%= textarea :commenter, :biography %> <%= checkbox_tag "comment[all_caps]", "1", @comment.commenter.hulk_mode? %> <% end %>
То же самое относится к методам в FormOptionsHelper и DateHelper, предназначенным для работы с объектом в качестве базы, например, FormOptionsHelper#collection_select и DateHelper#datetime_select.
# File actionview/lib/action_view/helpers/form_helper.rb, line 1029
def fields_for(record_name, record_object = nil, options = {}, &block)
options = { model: record_object, allow_method_names_outside_object: false, skip_default_ids: false }.merge!(options)
fields(record_name, **options, &block)
end Создаёт область действия вокруг определённого объекта модели, например form_with, но не создаёт сами теги формы. Это делает fields_for подходящим для указания дополнительных объектов модели в той же форме.
Хотя использование и назначение fields_for аналогично form_with‘s, его сигнатура метода немного отличается. Как и form_with, он передаёт объект FormBuilder, связанный с конкретным объектом модели, в блок, и внутри блока можно вызывать методы для генерации полей, связанных с объектом модели. Поля могут отражать объект модели двумя способами — как они названы (а значит, как представлено значение отправки в хэше params в контроллере) и какие значения по умолчанию отображаются при первом отображении полей формы. Для того, чтобы оба этих параметра можно было указать независимо, можно передать в метод отдельно как имя объекта (представленное символом или строкой), так и сам объект —
<%= form_with model: @person do |person_form| %>
First name: <%= person_form.text_field :first_name %>
Last name : <%= person_form.text_field :last_name %>
<%= fields_for :permission, @person.permission do |permission_fields| %>
Admin? : <%= permission_fields.checkbox :admin %>
<% end %>
<%= person_form.submit %>
<% end %> В этом случае поле флажка будет представлено HTML-тегом input с атрибутом name permission[admin], и переданное значение будет отображаться в контроллере как params[:permission][:admin]. Если @person.permission — это существующий объект с атрибутом admin, начальное состояние флажка при первом отображении будет отражать значение @person.permission.admin.
Часто это можно упростить, передав просто имя объекта модели в fields_for —
<%= fields_for :permission do |permission_fields| %> Admin?: <%= permission_fields.checkbox :admin %> <% end %>
…в этом случае, если :permission также является именем переменной экземпляра @permission, начальное состояние поля ввода будет отражать значение атрибута этой переменной @permission.admin.
В качестве альтернативы, вы можете передать только сам объект модели (если первый аргумент не является строкой или символом fields_for, fields_for поймёт, что имя опущено) —
<%= fields_for @person.permission do |permission_fields| %> Admin?: <%= permission_fields.checkbox :admin %> <% end %>
и fields_for определит необходимое имя поля из класса объекта модели, например, если @person.permission, относится к классу Permission, поле всё равно будет называться permission[admin].
Примечание: Это также работает для методов в FormOptionsHelper и DateHelper, которые разработаны для работы с объектом в качестве базы, например FormOptionsHelper#collection_select и DateHelper#datetime_select.
Примеры вложенных атрибутов
Когда объект, относящийся к текущей области действия, имеет метод-запись вложенного атрибута для определённого атрибута, fields_for создаст новую область действия для этого атрибута. Это позволяет создавать формы, которые устанавливают или изменяют атрибуты родительского объекта и его ассоциаций в один приём.
Методы записи вложенных атрибутов — это обычные методы записи, названные по имени ассоциации. Наиболее распространённый способ определения этих методов записи — с помощью accepts_nested_attributes_for в определении модели или путём определения метода с соответствующим именем. Например: метод записи атрибута для ассоциации :address называется address_attributes=.
Будет ли создан экземпляр формы для одного к одному или для одного ко многим, зависит от того, возвращает ли обычный метод чтения один объект или массив объектов.
Один к одному
Рассмотрим класс Person, который возвращает один Address из метода чтения address и отвечает на метод записи address_attributes=:
class Person
def address
@address
end
def address_attributes=(attributes)
# Process the attributes hash
end
end
Теперь эта модель может быть использована с вложенным fields_for, например так:
<%= form_with model: @person do |person_form| %>
...
<%= person_form.fields_for :address do |address_fields| %>
Street : <%= address_fields.text_field :street %>
Zip code: <%= address_fields.text_field :zip_code %>
<% end %>
...
<% end %> Если адрес уже является ассоциацией Person, можно использовать accepts_nested_attributes_for для определения метода записи за вас:
class Person < ActiveRecord::Base has_one :address accepts_nested_attributes_for :address end
Если нужно удалить связанную модель через форму, нужно сначала включить это с помощью параметра :allow_destroy для accepts_nested_attributes_for:
class Person < ActiveRecord::Base has_one :address accepts_nested_attributes_for :address, allow_destroy: true end
Теперь, когда вы используете элемент формы с параметром _destroy со значением, которое вычисляется как true, вы удалите связанную модель (например, 1, ‘1’, true или ‘true’):
<%= form_with model: @person do |person_form| %>
...
<%= person_form.fields_for :address do |address_fields| %>
...
Delete: <%= address_fields.checkbox :_destroy %>
<% end %>
...
<% end %> Один ко многим
Рассмотрим класс Person, который возвращает массив экземпляров Project из метода чтения projects и отвечает на метод записи projects_attributes=:
class Person
def projects
[@project1, @project2]
end
def projects_attributes=(attributes)
# Process the attributes hash
end
end
Обратите внимание, что метод записи projects_attributes= фактически необходим для fields_for, чтобы правильно идентифицировать :projects как коллекцию и установить правильные индексы в разметке формы.
Если projects уже является ассоциацией Person, можно использовать accepts_nested_attributes_for для определения метода записи за вас:
class Person < ActiveRecord::Base has_many :projects accepts_nested_attributes_for :projects end
Теперь эту модель можно использовать с вложенным fields_for. Блок, переданный в вызов вложенного fields_for, будет повторяться для каждого экземпляра в коллекции:
<%= form_with model: @person do |person_form| %>
...
<%= person_form.fields_for :projects do |project_fields| %>
<% if project_fields.object.active? %>
Name: <%= project_fields.text_field :name %>
<% end %>
<% end %>
...
<% end %> Также можно указать используемый экземпляр:
<%= form_with model: @person do |person_form| %>
...
<% @person.projects.each do |project| %>
<% if project.active? %>
<%= person_form.fields_for :projects, project do |project_fields| %>
Name: <%= project_fields.text_field :name %>
<% end %>
<% end %>
<% end %>
...
<% end %> Или коллекцию:
<%= form_with model: @person do |person_form| %>
...
<%= person_form.fields_for :projects, @active_projects do |project_fields| %>
Name: <%= project_fields.text_field :name %>
<% end %>
...
<% end %> Если нужно удалить связанные модели через форму, нужно сначала включить это с помощью параметра :allow_destroy для accepts_nested_attributes_for:
class Person < ActiveRecord::Base has_many :projects accepts_nested_attributes_for :projects, allow_destroy: true end
Это позволит указать, какие модели нужно удалить в хэше атрибутов, добавив элемент формы для параметра _destroy со значением, которое вычисляется как true (например, 1, ‘1’, true или ‘true’):
<%= form_with model: @person do |person_form| %>
...
<%= person_form.fields_for :projects do |project_fields| %>
Delete: <%= project_fields.checkbox :_destroy %>
<% end %>
...
<% end %> Когда используется коллекция, возможно, вам понадобится знать индекс каждого объекта в массиве. Для этого доступен метод index в объекте FormBuilder.
<%= form_with model: @person do |person_form| %>
...
<%= person_form.fields_for :projects do |project_fields| %>
Project #<%= project_fields.index %>
...
<% end %>
...
<% end %> Обратите внимание, что fields_for автоматически сгенерирует скрытое поле для хранения идентификатора записи, если оно отвечает методу persisted?. В некоторых случаях это скрытое поле не нужно, и вы можете передать include_id: false для предотвращения автоматического рендеринга fields_for.
# File actionview/lib/action_view/helpers/form_helper.rb, line 1248
def file_field(object_name, method, options = {})
options = { include_hidden: multiple_file_field_include_hidden }.merge!(options)
Tags::FileField.new(object_name, method, self, convert_direct_upload_option_to_url(options.dup)).render
end Возвращает тег ввода для загрузки файлов, настроенный для доступа к указанному атрибуту (определённому method) объекта, назначенного шаблону (определённого object). Дополнительные параметры тега ввода могут быть переданы в виде хэша с options. Эти параметры будут добавлены в HTML как атрибут HTML-элемента, как показано в примере.
Использование этого метода внутри блока form_with установит кодировку окружающего элемента формы на multipart/form-data.
Параметры
-
Создаёт стандартные атрибуты HTML для тега.
-
:disabled— Если установлено в true, пользователь не сможет использовать этот элемент ввода. -
:multiple— Если установлено в true, *в большинстве современных браузеров* пользователь сможет выбрать несколько файлов. -
:include_hidden— Когдаmultiple: trueиinclude_hidden: true, поле будет префиксным полем<input type="hidden">со значением по умолчанию, чтобы поддерживать отправку пустой коллекции файлов. -
:accept— Если установлено на один или несколько MIME-типов, пользователю будет предложен фильтр при выборе файла. Вам всё равно необходимо настроить валидацию модели.
Примеры
file_field(:user, :avatar) # => <input type="file" id="user_avatar" name="user[avatar]" /> file_field(:article, :image, multiple: true) # => <input type="file" id="article_image" name="article[image][]" multiple="multiple" /> file_field(:article, :attached, accept: 'text/html') # => <input accept="text/html" type="file" id="article_attached" name="article[attached]" /> file_field(:article, :image, accept: 'image/png,image/gif,image/jpeg') # => <input type="file" id="article_image" name="article[image]" accept="image/png,image/gif,image/jpeg" /> file_field(:attachment, :file, class: 'file_input') # => <input type="file" id="attachment_file" name="attachment[file]" class="file_input" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 436
def form_for(record, options = {}, &block)
raise ArgumentError, "Missing block" unless block_given?
case record
when String, Symbol
model = false
object_name = record
else
model = record
object = _object_for_form_builder(record)
raise ArgumentError, "First argument in form cannot contain nil or be empty" unless object
object_name = options[:as] || model_name_from_record_or_class(object).param_key
apply_form_for_options!(object, options)
end
remote = options.delete(:remote)
if remote && !embed_authenticity_token_in_remote_forms && options[:authenticity_token].blank?
options[:authenticity_token] = false
end
options[:model] = model
options[:scope] = object_name
options[:local] = !remote
options[:skip_default_ids] = false
options[:allow_method_names_outside_object] = options.fetch(:allow_method_names_outside_object, false)
form_with(**options, &block)
end Создаёт форму, позволяющую пользователю создавать или обновлять атрибуты конкретного объекта модели.
Метод может использоваться несколькими немного разными способами, в зависимости от того, насколько вы хотите полагаться на Rails для автоматического определения того, как должна быть построена форма. Для общего объекта модели форма может быть создана путём передачи form_for строки или символа, представляющего объект, который нас интересует:
<%= form_for :person do |f| %> First name: <%= f.text_field :first_name %><br /> Last name : <%= f.text_field :last_name %><br /> Biography : <%= f.textarea :biography %><br /> Admin? : <%= f.checkbox :admin %><br /> <%= f.submit %> <% end %>
Переменная f передаваемая в блок, является объектом FormBuilder, который содержит знания об объекте модели, представленном :person переданным в form_for. Методы, определенные для FormBuilder, используются для генерации полей, связанных с этой моделью. Таким образом, например,
<%= f.text_field :first_name %>
будет преобразовано в
<%= text_field :person, :first_name %>
что приводит к тегу HTML <input>, атрибут name которого person[first_name]. Это означает, что при отправке формы значение, введенное пользователем, будет доступно в контроллере как params[:person][:first_name].
Для полей, сгенерированных таким образом с помощью FormBuilder, если :person также является именем переменной экземпляра @person, значение по умолчанию для поля, отображаемого при первоначальном отображении формы (например, в ситуации, когда вы редактируете существующий объект), будет значением соответствующего атрибута объекта @person.
Правый аргумент form_for — это необязательный хэш опций:
-
:url— URL, на который должна быть отправлена форма. Он может быть представлен таким же образом, как значения, передаваемые вurl_forилиlink_to. Например, можно напрямую использовать именованный маршрут. Когда модель представляется строкой или символом, как в примере выше, если опция:urlне указана, форма по умолчанию отправляется на текущий URL (мы опишем ниже альтернативное использованиеform_forс ресурсно-ориентированной формой, в которой URL не нужно указывать явно). -
:namespace— пространство имён для вашей формы, чтобы гарантировать уникальность атрибутов id элементов формы. Атрибут пространства имен будет предваряться символом подчеркивания в сгенерированном HTML id. -
:method— метод, используемый при отправке формы, обычно «get» или «post». Если используется «patch», «put», «delete» или другой глагол, добавляется скрытый ввод с именем_method, чтобы смоделировать глагол с отправкой POST. -
:authenticity_token— маркер подлинности для использования в форме. Используйте только если вам нужно передать строку маркера подлинности, или чтобы не добавлять поле authenticity_token вообще (передавfalse). Дистанционные формы могут опустить встраиваемый маркер подлинности, установивconfig.action_view.embed_authenticity_token_in_remote_forms = false. Это полезно, когда вы кэшируете форму по фрагментам. Дистанционные формы получают маркер подлинности из тегаmeta, поэтому встраивание не требуется, если вы поддерживаете браузеры без JavaScript. -
:remote— если установлено в true, позволит неочевидным драйверам JavaScript управлять поведением отправки. -
:enforce_utf8— если установлено в false, скрытый ввод с именем utf8 не выводится. -
:html— необязательные HTML атрибуты для тега формы.
Также обратите внимание, что form_for не создаёт исключительной области. По-прежнему можно использовать как самостоятельные методы FormHelper, так и методы из FormTagHelper. Например:
<%= form_for :person do |f| %> First name: <%= f.text_field :first_name %> Last name : <%= f.text_field :last_name %> Biography : <%= textarea :person, :biography %> Admin? : <%= checkbox_tag "person[admin]", "1", @person.company.admin? %> <%= f.submit %> <% end %>
Это также работает для методов в FormOptionsHelper и DateHelper, которые разработаны для работы с объектом в качестве основы, например, FormOptionsHelper#collection_select и DateHelper#datetime_select.
form_for с объектом модели
В примерах выше объект для создания или редактирования представлялся символом, переданным в form_for, и мы отметили, что строку также можно использовать аналогично. Однако также возможно передать сам объект модели в form_for. Например, если @article это существующий объект, который вы хотите отредактировать, вы можете создать форму, используя
<%= form_for @article do |f| %> ... <% end %>
Это работает почти так же, как описано ранее, с парой небольших исключений. Во-первых, префикс, используемый для именования элементов ввода в форме (следовательно, ключ, который обозначает их в хеше params), фактически получен из класса объекта, например params[:article], если класс объекта — Article. Однако это можно переопределить, используя опцию :as, например:
<%= form_for(@person, as: :client) do |f| %> ... <% end %>
что приведет к params[:client].
Во-вторых, значения полей, отображаемые при первоначальном отображении формы, берутся из атрибутов объекта, переданного в form_for, независимо от того, является ли объект переменной экземпляра. Например, если у нас есть локальная переменная article, представляющая существующий объект,
<%= form_for article do |f| %> ... <% end %>
произведёт форму с полями, начальное состояние которых отражает текущие значения атрибутов объекта article.
Ресурсно-ориентированный стиль
В только что показанных примерах, хотя и не указано явно, нам всё ещё нужно использовать опцию :url для указания того, куда будет отправлена форма. Однако дальнейшее упрощение возможно, если объект, переданный в form_for, является ресурсом, т.е. он соответствует набору маршрутов RESTful, например, определенных с помощью метода resources в config/routes.rb. В этом случае Rails просто выведет соответствующий URL из самого объекта. Например,
<%= form_for @article do |f| %> ... <% end %>
эквивалентно чему-то вроде:
<%= form_for @article, as: :article, url: article_path(@article), method: :patch, html: { class: "edit_article", id: "edit_article_45" } do |f| %>
...
<% end %> И для нового объекта
<%= form_for(Article.new) do |f| %> ... <% end %>
эквивалентно чему-то вроде:
<%= form_for @article, as: :article, url: articles_path, html: { class: "new_article", id: "new_article" } do |f| %>
...
<% end %> Однако вы всё ещё можете переопределить отдельные соглашения, например:
<%= form_for(@article, url: super_articles_path) do |f| %> ... <% end %>
Вы можете опустить атрибут action передав url: false:
<%= form_for(@article, url: false) do |f| %> ... <% end %>
Вы также можете задать формат ответа, например так:
<%= form_for(@article, format: :json) do |f| %> ... <% end %>
Для маршрутов с именованными пространствами, например admin_article_url:
<%= form_for([:admin, @article]) do |f| %> ... <% end %>
Если у вашего ресурса определены ассоциации, например, вы хотите добавить комментарии к документу, учитывая, что маршруты настроены правильно:
<%= form_for([@document, @comment]) do |f| %> ... <% end %>
Где @document = Document.find(params[:id]) и @comment = Comment.new.
Установка метода
Вы можете принудительно заставить форму использовать полный набор HTTP глаголов, установив
method: (:get|:post|:patch|:put|:delete)
в хэше опций. Если глагол не GET или POST, которые изначально поддерживаются HTML формами, форма будет установлена на POST, а скрытый элемент с именем _method будет содержать предназначенный глагол для интерпретации сервером.
Неочевидный JavaScript
Указание:
remote: true
в хэше опций создаёт форму, которая позволит неочевидным драйверам JavaScript изменять её поведение. Отправка формы будет работать так же, как обычная отправка, как её видит сторона получателя (все элементы доступны в params).
Пример:
<%= form_for(@article, remote: true) do |f| %> ... <% end %>
Сгенерированный для этого HTML будет:
<form action='http://www.example.com' method='post' data-remote='true'> <input name='_method' type='hidden' value='patch' /> ... </form>
Установка HTML опций
Вы можете установить атрибуты данных напрямую, передав хэш данных, но все остальные HTML опции должны быть обернуты в ключ HTML. Пример:
<%= form_for(@article, data: { behavior: "autosave" }, html: { name: "go" }) do |f| %>
...
<% end %> Сгенерированный для этого HTML будет:
<form action='http://www.example.com' method='post' data-behavior='autosave' name='go'> <input name='_method' type='hidden' value='patch' /> ... </form>
Удаление скрытых id модели
Метод form_for автоматически включает id модели как скрытое поле в форме. Это используется для поддержания корреляции между данными формы и связанной моделью. Некоторые системы ORM не используют id в вложенных моделях, поэтому в этом случае вам нужно будет отключить скрытый id.
В следующем примере модель статьи имеет много комментариев, хранящихся внутри неё в базе данных NoSQL, поэтому для комментариев нет первичного ключа.
Пример:
<%= form_for(@article) do |f| %>
<%= f.fields_for(:comments, include_id: false) do |cf| %>
...
<% end %>
<% end %> Настраиваемые генераторы форм
Вы также можете создавать формы, используя настраиваемый класс FormBuilder. Подклассируйте FormBuilder и переопределите или определите некоторые дополнительные помощники, а затем используйте свой настраиваемый генератор. Например, предположим, что вы создали помощник для автоматического добавления меток к элементам формы.
<%= form_for @person, url: { action: "create" }, builder: LabellingFormBuilder do |f| %>
<%= f.text_field :first_name %>
<%= f.text_field :last_name %>
<%= f.textarea :biography %>
<%= f.checkbox :admin %>
<%= f.submit %>
<% end %> В этом случае, если вы используете это:
<%= render f %>
Отображаемая в шаблоне форма будет people/_labelling_form, а локальная переменная, ссылающаяся на генератор формы, называется labelling_form.
Настраиваемый класс FormBuilder автоматически объединяется с опциями вложенного вызова fields_for, если не указано явно.
В многих случаях вы захотите обернуть это в другой помощник, поэтому вы можете сделать что-то вроде следующего:
def labelled_form_for(record_or_name_or_array, *args, &block) options = args.extract_options! form_for(record_or_name_or_array, *(args << options.merge(builder: LabellingFormBuilder)), &block) end
Если вам не нужно привязывать форму к экземпляру модели, ознакомьтесь со статьёй FormTagHelper#form_tag.
Форма для внешних ресурсов
Когда вы создаёте формы для внешних ресурсов, иногда вам нужно установить маркер подлинности или просто отобразить форму без него, например, когда вы отправляете данные на веб-сайт платежной системы, количество и типы полей могут быть ограничены.
Чтобы установить маркер подлинности, вам нужно передать параметр :authenticity_token
<%= form_for @invoice, url: external_url, authenticity_token: 'external_token' do |f| %> ... <% end %>
Если вы не хотите, чтобы поле маркера подлинности отображалось вообще, просто передайте false:
<%= form_for @invoice, url: external_url, authenticity_token: false do |f| %> ... <% end %>
# File actionview/lib/action_view/helpers/form_helper.rb, line 756
def form_with(model: false, scope: nil, url: nil, format: nil, **options, &block)
raise ArgumentError, "Passed nil to the :model argument, expect an object or false" if model.nil?
options = { allow_method_names_outside_object: true, skip_default_ids: !form_with_generates_ids }.merge!(options)
if model
if url != false
url ||= if format.nil?
polymorphic_path(model, {})
else
polymorphic_path(model, format: format)
end
end
model = convert_to_model(_object_for_form_builder(model))
scope ||= model_name_from_record_or_class(model).param_key
end
if block_given?
builder = instantiate_builder(scope, model, options)
output = capture(builder, &block)
options[:multipart] ||= builder.multipart?
html_options = html_options_for_form_with(url, model, **options)
form_tag_with_body(html_options, output)
else
html_options = html_options_for_form_with(url, model, **options)
form_tag_html(html_options)
end
end Создаёт тег формы, основанный на смешении URL, областей или моделей.
# Using just a URL: <%= form_with url: articles_path do |form| %> <%= form.text_field :title %> <% end %> # => <form action="/articles" method="post"> <input type="text" name="title" /> </form> # With an intentionally empty URL: <%= form_with url: false do |form| %> <%= form.text_field :title %> <% end %> # => <form method="post"> <input type="text" name="title" /> </form> # Adding a scope prefixes the input field names: <%= form_with scope: :article, url: articles_path do |form| %> <%= form.text_field :title %> <% end %> # => <form action="/articles" method="post"> <input type="text" name="article[title]" /> </form> # Using a model infers both the URL and scope: <%= form_with model: Article.new do |form| %> <%= form.text_field :title %> <% end %> # => <form action="/articles" method="post"> <input type="text" name="article[title]" /> </form> # An existing model makes an update form and fills out field values: <%= form_with model: Article.first do |form| %> <%= form.text_field :title %> <% end %> # => <form action="/articles/1" method="post"> <input type="hidden" name="_method" value="patch" /> <input type="text" name="article[title]" value="<the title of the article>" /> </form> # Though the fields don't have to correspond to model attributes: <%= form_with model: Cat.new do |form| %> <%= form.text_field :cats_dont_have_gills %> <%= form.text_field :but_in_forms_they_can %> <% end %> # => <form action="/cats" method="post"> <input type="text" name="cat[cats_dont_have_gills]" /> <input type="text" name="cat[but_in_forms_they_can]" /> </form>
Параметры в формах доступны в контроллерах в соответствии с их вложенностью имён. Таким образом, поля с именами title и article[title] доступны как params[:title] и params[:article][:title] соответственно.
Для простоты сравнения в примерах выше отсутствуют кнопка отправки, а также автоматически сгенерированные скрытые поля, обеспечивающие поддержку UTF-8 и добавляющие маркер аутентичности, необходимый для защиты от межсайтовых запросов.
Ориентированный на ресурсы стиль
Во многих из представленных примеров :model, переданное в form_with — это ресурс. Он соответствует набору маршрутов RESTful, скорее всего, определённых с помощью resources в config/routes.rb.
Поэтому при передаче такой записи модели Rails определяет URL и метод.
<%= form_with model: @article do |form| %> ... <% end %>
тогда эквивалентно примерно такому:
<%= form_with scope: :article, url: article_path(@article), method: :patch do |form| %> ... <% end %>
А для новой записи
<%= form_with model: Article.new do |form| %> ... <% end %>
эквивалентно примерно такому:
<%= form_with scope: :article, url: articles_path do |form| %> ... <% end %>
form_with параметры
-
:url— URL, на который отправляется форма. Аналогично значениям, переданным вurl_forилиlink_to. Например, вы можете напрямую использовать именованный маршрут. Когда:scopeпередаётся без:url, форма просто отправляется на текущий URL. -
:method— метод, используемый при отправке формы, обычно «get» или «post». Если «patch», «put», «delete» или другой глагол, добавляется скрытое поле с именем_method, чтобы имитировать глагол через post. -
:format— формат маршрута, на который отправляется форма. Полезно при отправке на другой тип ресурса, например,:json. Пропускается, если передаётся:url. -
:scope— область для префикса имён полей ввода, а также для группировки переданных параметров в контроллерах. -
:namespace— пространство имён для вашей формы, чтобы обеспечить уникальность атрибутов id элементов формы. Атрибут пространства имён будет префиксам в HTML id символом подчёркивания. -
:model— объект модели для вывода:urlи:scope, а также заполнения значений полей ввода. Еслиtitleимеет значение «Ahoy!», то значение поля вводаtitleбудет «Ahoy!», Если модель — новая запись, генерируется форма создания, если существующая запись — форма обновления. Передайте:scopeили:urlдля переопределения значений по умолчанию. Например, превратитьparams[:article]вparams[:blog]. -
:authenticity_token— маркер аутентификации для использования в форме. Переопределите пользовательским маркером аутентификации или передайтеfalseдля пропуска поля маркера аутентификации. Полезно при отправке на внешний ресурс, например, на платежную шлюз, который может ограничивать допустимые поля. Дистанционные формы могут опустить встроенный маркер аутентификации, установивconfig.action_view.embed_authenticity_token_in_remote_forms = false. Это полезно при кэшировании фрагментов формы. Дистанционные формы получают маркер аутентификации из тегаmeta, поэтому вставка не нужна, если вы поддерживаете браузеры без JavaScript. -
:local— использовать стандартную отправку формы по HTTP. Если значение равноtrue, форма отправляется по стандартному HTTP. Если значение равноfalse, форма отправляется как «дистанционная форма», которая обрабатывается Rails UJS как XHR. При отсутствии указания поведение определяется изconfig.action_view.form_with_generates_remote_forms, где значение конфигурации на самом деле является инверсией значенияlocal. Начиная с Rails 6.1, значение этой опции конфигурации по умолчанию равноfalse(что эквивалентно передачеlocal: true). В предыдущих версиях Rails значение этой опции конфигурации по умолчанию равноtrue(эквивалентно передачеlocal: false). -
:skip_enforcing_utf8— Если установлено в true, скрытое поле с именем utf8 не выводится. -
:builder— переопределить объект, используемый для построения формы. -
:id— необязательный атрибут HTML id. -
:class— необязательный атрибут HTML class. -
:data— необязательные атрибуты данных HTML. -
:html— другие необязательные атрибуты тега формы HTML.
Примеры
При отсутствии блока form_with генерируется только открывающий тег формы.
<%= form_with(model: @article, url: super_articles_path) %> <%= form_with(model: @article, scope: :blog) %> <%= form_with(model: @article, format: :json) %> <%= form_with(model: @article, authenticity_token: false) %> # Disables the token.
Для маршрутов с именами пространств, например, admin_article_url:
<%= form_with(model: [ :admin, @article ]) do |form| %> ... <% end %>
Если у вашего ресурса определены ассоциации, например, вы хотите добавить комментарии к документу при условии, что маршруты установлены правильно:
<%= form_with(model: [ @document, Comment.new ]) do |form| %> ... <% end %>
Где @document = Document.find(params[:id]).
Смешение с другими помощниками форм
Хотя form_with использует объект FormBuilder, можно смешивать автономные методы FormHelper и методы из FormTagHelper:
<%= form_with scope: :person do |form| %> <%= form.text_field :first_name %> <%= form.text_field :last_name %> <%= textarea :person, :biography %> <%= checkbox_tag "person[admin]", "1", @person.company.admin? %> <%= form.submit %> <% end %>
То же самое касается методов в FormOptionsHelper и DateHelper, предназначенных для работы с объектом в качестве базы, таких как FormOptionsHelper#collection_select и DateHelper#datetime_select.
Указание метода
Вы можете принудительно использовать полный набор HTTP-глаголов, установив
method: (:get|:post|:patch|:put|:delete)
в хеше параметров. Если глагол не GET или POST, которые встроены в HTML-формы, форма будет установлена на POST, и скрытое поле с именем _method будет содержать назначенный глагол, чтобы сервер его интерпретировал.
Установка атрибутов HTML
Вы можете установить атрибуты данных напрямую в хеше данных, но атрибуты HTML, кроме id и class, должны быть обернуты в ключ HTML:
<%= form_with(model: @article, data: { behavior: "autosave" }, html: { name: "go" }) do |form| %>
...
<% end %> генерирует
<form action="/articles/123" method="post" data-behavior="autosave" name="go"> <input name="_method" type="hidden" value="patch" /> ... </form>
Удаление скрытых id моделей
Метод form_with автоматически включает id модели как скрытое поле в форме. Это используется для поддержания корреляции между данными формы и связанной моделью. Некоторые системы ORM не используют идентификаторы вложенных моделей, поэтому в этом случае вы хотите отключить скрытый id.
В следующем примере модель Article имеет много комментариев, хранящихся в ней в базе данных NoSQL, поэтому для комментариев нет первичного ключа.
<%= form_with(model: @article) do |form| %>
<%= form.fields(:comments, skip_id: true) do |fields| %>
...
<% end %>
<% end %> Настраиваемые строители форм
Вы также можете создавать формы, используя настраиваемый класс FormBuilder. Наследуйте от FormBuilder и переопределите или определите ещё несколько помощников, затем используйте своего настраиваемого строителя. Например, предположим, что вы создали помощник, который автоматически добавляет метки к полям ввода формы.
<%= form_with model: @person, url: { action: "create" }, builder: LabellingFormBuilder do |form| %>
<%= form.text_field :first_name %>
<%= form.text_field :last_name %>
<%= form.textarea :biography %>
<%= form.checkbox :admin %>
<%= form.submit %>
<% end %> В этом случае, если вы используете:
<%= render form %>
Рендерируемый шаблон people/_labelling_form, а локальная переменная, ссылающаяся на строителя формы, называется labelling_form.
Настраиваемый класс FormBuilder автоматически объединяется с параметрами вложенного вызова fields, если он явно не установлен.
Во многих случаях вы захотите обернуть вышеуказанное в другой помощник, поэтому вы можете сделать что-то вроде следующего:
def labelled_form_with(**options, &block) form_with(**options.merge(builder: LabellingFormBuilder), &block) end
Возвращает тег скрытого поля, настроенный для доступа к указанному атрибуту (определённому по method) объекта, назначенного шаблону (определённого по object). Дополнительные параметры тега ввода могут быть переданы в виде хеша с options. Эти параметры будут добавлены в HTML как атрибуты элемента HTML, как показано в примере.
Примеры
hidden_field(:signup, :pass_confirm)
# => <input type="hidden" id="signup_pass_confirm" name="signup[pass_confirm]" value="#{@signup.pass_confirm}" />
hidden_field(:article, :tag_list)
# => <input type="hidden" id="article_tag_list" name="article[tag_list]" value="#{@article.tag_list}" />
hidden_field(:user, :token)
# => <input type="hidden" id="user_token" name="user[token]" value="#{@user.token}" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1152 def label(object_name, method, content_or_options = nil, options = nil, &block) Tags::Label.new(object_name, method, self, content_or_options, options).render(&block) end
Возвращает тег метки, настроенный для подписи поля ввода для указанного атрибута (определённого по method) объекта, назначенного шаблону (определённого по object). Текст метки по умолчанию будет соответствовать имени атрибута, если не найдено перевода в текущем языке I18n (через helpers.label.<modelname>.<attribute>) или вы явно его не укажете. Дополнительные параметры тега метки могут быть переданы в виде хеша с options. Эти параметры будут добавлены в HTML в виде атрибутов элемента HTML, как показано в примере, за исключением параметра :value, который предназначен для обработки меток для тегов radio_button (где значение используется в ID тега ввода).
Примеры
label(:article, :title) # => <label for="article_title">Title</label>
Вы можете локализовать метки на основе имен модели и атрибутов. Например, вы можете определить следующее в своём локали (например, en.yml)
helpers:
label:
article:
body: "Write your entire text here" Что приведет к
label(:article, :body) # => <label for="article_body">Write your entire text here</label>
Локализация также может основываться только на переводе имени атрибута (если вы используете ActiveRecord):
activerecord:
attributes:
article:
cost: "Total cost" label(:article, :cost)
# => <label for="article_cost">Total cost</label>
label(:article, :title, "A short title")
# => <label for="article_title">A short title</label>
label(:article, :title, "A short title", class: "title_label")
# => <label for="article_title" class="title_label">A short title</label>
label(:article, :privacy, "Public Article", value: "public")
# => <label for="article_privacy_public">Public Article</label>
label(:article, :cost) do |translation|
content_tag(:span, translation, class: "cost_label")
end
# => <label for="article_cost"><span class="cost_label">Total cost</span></label>
label(:article, :cost) do |builder|
content_tag(:span, builder.translation, class: "cost_label")
end
# => <label for="article_cost"><span class="cost_label">Total cost</span></label>
label(:article, :terms) do
raw('Accept <a href="/terms">Terms</a>.')
end
# => <label for="article_terms">Accept <a href="/terms">Terms</a>.</label>
# File actionview/lib/action_view/helpers/form_helper.rb, line 1534
def month_field(object_name, method, options = {})
Tags::MonthField.new(object_name, method, self, options).render
end Возвращает text_field типа «месяц».
month_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="month" />
Значение по умолчанию генерируется путем попытки вызвать strftime с «%Y-%m» на значении объекта, что обеспечивает ожидаемое поведение для экземпляров DateTime и ActiveSupport::TimeWithZone.
@user.born_on = Date.new(1984, 1, 27)
month_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="date" value="1984-01" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1578
def number_field(object_name, method, options = {})
Tags::NumberField.new(object_name, method, self, options).render
end Возвращает тег ввода типа «число».
Параметры
Поддерживает те же параметры, что и FormTagHelper#number_field_tag.
# File actionview/lib/action_view/helpers/form_helper.rb, line 1197
def password_field(object_name, method, options = {})
Tags::PasswordField.new(object_name, method, self, options).render
end Возвращает тег ввода типа «пароль», предназначенный для доступа к указанному атрибуту (идентифицируемому по method) объекта, присвоенного шаблону (идентифицируемому по object). Дополнительные параметры тега ввода могут быть переданы в виде хэша с options. Эти параметры будут добавлены в HTML как атрибут элемента HTML, как показано в примере. По соображениям безопасности это поле по умолчанию пустое; передайте значение через options , если этого не требуется.
Примеры
password_field(:login, :pass, size: 20)
# => <input type="password" id="login_pass" name="login[pass]" size="20" />
password_field(:account, :secret, class: "form_input", value: @account.secret)
# => <input type="password" id="account_secret" name="account[secret]" value="#{@account.secret}" class="form_input" />
password_field(:user, :password, onchange: "if ($('#user_password').val().length > 30) { alert('Your password needs to be shorter!'); }")
# => <input type="password" id="user_password" name="user[password]" onchange="if ($('#user_password').val().length > 30) { alert('Your password needs to be shorter!'); }"/>
password_field(:account, :pin, size: 20, class: 'form_input')
# => <input type="password" id="account_pin" name="account[pin]" size="20" class="form_input" />
алиас для telephone_field
# File actionview/lib/action_view/helpers/form_helper.rb, line 1370
def radio_button(object_name, method, tag_value, options = {})
Tags::RadioButton.new(object_name, method, self, tag_value, options).render
end Возвращает тег радиокнопки для доступа к указанному атрибуту (идентифицируемому по method) объекта, присвоенного шаблону (идентифицируемому по object). Если текущее значение method равно tag_value, радиокнопка будет отмечена.
Чтобы принудительно установить радиокнопку, передайте checked: true в хэш options. Вы также можете передать туда параметры HTML.
# Let's say that @article.category returns "rails":
radio_button("article", "category", "rails")
radio_button("article", "category", "java")
# => <input type="radio" id="article_category_rails" name="article[category]" value="rails" checked="checked" />
# <input type="radio" id="article_category_java" name="article[category]" value="java" />
# Let's say that @user.receive_newsletter returns "no":
radio_button("user", "receive_newsletter", "yes")
radio_button("user", "receive_newsletter", "no")
# => <input type="radio" id="user_receive_newsletter_yes" name="user[receive_newsletter]" value="yes" />
# <input type="radio" id="user_receive_newsletter_no" name="user[receive_newsletter]" value="no" checked="checked" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1587
def range_field(object_name, method, options = {})
Tags::RangeField.new(object_name, method, self, options).render
end Возвращает тег ввода типа «диапазон».
Параметры
Поддерживает те же параметры, что и FormTagHelper#range_field_tag.
# File actiontext/app/helpers/action_text/tag_helper.rb, line 87
def rich_textarea(object_name, method, options = {})
Tags::ActionText.new(object_name, method, self, options).render
end Возвращает тег trix-editor, который инициализирует JavaScript-редактор Trix, а также скрытое поле, в которое Trix будет записывать изменения, чтобы содержимое отправлялось при отправке формы.
Параметры
-
:class- По умолчанию «trix-content», что обеспечивает применение стилей по умолчанию. -
:value- Добавляет значение по умолчанию в тег ввода HTML. -
[:data][:direct_upload_url]- По умолчаниюrails_direct_uploads_url. -
[:data][:blob_url_template]- По умолчаниюrails_service_blob_url(":signed_id", ":filename").
Пример
rich_textarea :message, :content # <input type="hidden" name="message[content]" id="message_content_trix_input_message_1"> # <trix-editor id="content" input="message_content_trix_input_message_1" class="trix-content" ...></trix-editor> rich_textarea :message, :content, value: "<h1>Default message</h1>" # <input type="hidden" name="message[content]" id="message_content_trix_input_message_1" value="<h1>Default message</h1>"> # <trix-editor id="content" input="message_content_trix_input_message_1" class="trix-content" ...></trix-editor>
# File actionview/lib/action_view/helpers/form_helper.rb, line 1401
def search_field(object_name, method, options = {})
Tags::SearchField.new(object_name, method, self, options).render
end Возвращает поле ввода типа «поиск» для доступа к указанному атрибуту (идентифицируемому по method) объекта, присвоенного шаблону (идентифицируемому по object_name). Поля ввода типа «поиск» могут отображаться браузерами по-разному.
search_field(:user, :name) # => <input id="user_name" name="user[name]" type="search" /> search_field(:user, :name, autosave: false) # => <input autosave="false" id="user_name" name="user[name]" type="search" /> search_field(:user, :name, results: 3) # => <input id="user_name" name="user[name]" results="3" type="search" /> # Assume request.host returns "www.example.com" search_field(:user, :name, autosave: true) # => <input autosave="com.example.www" id="user_name" name="user[name]" results="10" type="search" /> search_field(:user, :name, onsearch: true) # => <input id="user_name" incremental="true" name="user[name]" onsearch="true" type="search" /> search_field(:user, :name, autosave: false, onsearch: true) # => <input autosave="false" id="user_name" incremental="true" name="user[name]" onsearch="true" type="search" /> search_field(:user, :name, autosave: true, onsearch: true) # => <input autosave="com.example.www" id="user_name" incremental="true" name="user[name]" onsearch="true" results="10" type="search" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1410
def telephone_field(object_name, method, options = {})
Tags::TelField.new(object_name, method, self, options).render
end Возвращает text_field типа «тел».
telephone_field("user", "phone")
# => <input id="user_phone" name="user[phone]" type="tel" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1176
def text_field(object_name, method, options = {})
Tags::TextField.new(object_name, method, self, options).render
end Возвращает тег ввода типа «текст», предназначенный для доступа к указанному атрибуту (идентифицируемому по method) объекта, присвоенного шаблону (идентифицируемому по object). Дополнительные параметры тега ввода могут быть переданы в виде хэша с options. Эти параметры будут добавлены в HTML как атрибут элемента HTML, как показано в примере.
Примеры
text_field(:article, :title, size: 20)
# => <input type="text" id="article_title" name="article[title]" size="20" value="#{@article.title}" />
text_field(:article, :title, class: "create_input")
# => <input type="text" id="article_title" name="article[title]" value="#{@article.title}" class="create_input" />
text_field(:article, :title, maxlength: 30, class: "title_input")
# => <input type="text" id="article_title" name="article[title]" maxlength="30" size="30" value="#{@article.title}" class="title_input" />
text_field(:session, :user, onchange: "if ($('#session_user').val() === 'admin') { alert('Your login cannot be admin!'); }")
# => <input type="text" id="session_user" name="session[user]" value="#{@session.user}" onchange="if ($('#session_user').val() === 'admin') { alert('Your login cannot be admin!'); }"/>
text_field(:snippet, :code, size: 20, class: 'code_input')
# => <input type="text" id="snippet_code" name="snippet[code]" size="20" value="#{@snippet.code}" class="code_input" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1278
def textarea(object_name, method, options = {})
Tags::TextArea.new(object_name, method, self, options).render
end Возвращает набор открывающего и закрывающего тегов textarea, предназначенный для доступа к указанному атрибуту (идентифицируемому по method) объекта, присвоенного шаблону (идентифицируемому по object). Дополнительные параметры тега ввода могут быть переданы в виде хэша с options.
Примеры
textarea(:article, :body, cols: 20, rows: 40)
# => <textarea cols="20" rows="40" id="article_body" name="article[body]">
# #{@article.body}
# </textarea>
textarea(:comment, :text, size: "20x30")
# => <textarea cols="20" rows="30" id="comment_text" name="comment[text]">
# #{@comment.text}
# </textarea>
textarea(:application, :notes, cols: 40, rows: 15, class: 'app_input')
# => <textarea cols="40" rows="15" id="application_notes" name="application[notes]" class="app_input">
# #{@application.notes}
# </textarea>
textarea(:entry, :body, size: "20x20", disabled: 'disabled')
# => <textarea cols="20" rows="20" id="entry_body" name="entry[body]" disabled="disabled">
# #{@entry.body}
# </textarea>
# File actionview/lib/action_view/helpers/form_helper.rb, line 1480
def time_field(object_name, method, options = {})
Tags::TimeField.new(object_name, method, self, options).render
end Возвращает text_field типа «время».
Значение по умолчанию генерируется путем попытки вызвать strftime с «%T.%L» на значении объекта. Если вы передаете include_seconds: false, оно будет отформатировано путем попытки вызвать strftime с «%H:%M» на значении объекта. Также можно переопределить это, передав параметр «value».
Параметры
Поддерживает те же параметры, что и FormTagHelper#time_field_tag.
Примеры
time_field("task", "started_at")
# => <input id="task_started_at" name="task[started_at]" type="time" />
Вы можете создать значения для атрибутов «min» и «max», передав экземпляры Date или Time в хэш параметров.
time_field("task", "started_at", min: Time.now)
# => <input id="task_started_at" name="task[started_at]" type="time" min="01:00:00.000" />
В качестве значений для «min» и «max» также можно передать строку, отформатированную как ISO8601 время.
time_field("task", "started_at", min: "01:00:00")
# => <input id="task_started_at" name="task[started_at]" type="time" min="01:00:00.000" />
По умолчанию, указанное время будет отформатировано, включая секунды. Для отображения только часа и минуты передайте include_seconds: false. Некоторые браузеры отобразят более простой интерфейс, если вы исключите секунды в формате метки времени.
time_field("task", "started_at", value: Time.now, include_seconds: false)
# => <input id="task_started_at" name="task[started_at]" type="time" value="01:00" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1560
def url_field(object_name, method, options = {})
Tags::UrlField.new(object_name, method, self, options).render
end Возвращает text_field типа “url”.
url_field("user", "homepage")
# => <input id="user_homepage" name="user[homepage]" type="url" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1551
def week_field(object_name, method, options = {})
Tags::WeekField.new(object_name, method, self, options).render
end Возвращает text_field типа “week”.
week_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="week" />
Значение по умолчанию генерируется путем вызова strftime с “%Y-W%W” на значении объекта, что делает его поведением, ожидаемым для экземпляров DateTime и ActiveSupport::TimeWithZone.
@user.born_on = Date.new(1984, 5, 12)
week_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="date" value="1984-W19" />
© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.