модуль ActionView::Helpers::FormHelper
Помощники для форм предназначены для упрощения работы с ресурсами по сравнению с использованием обычного HTML.
Как правило, форма, предназначенная для создания или обновления ресурса, отражает идентификатор ресурса несколькими способами: (i) URL, к которому отправляется форма (атрибут элемента формы action) должен привести к маршрутизации запроса к соответствующему действию контроллера (с соответствующим параметром :id в случае существующего ресурса), (ii) имена полей ввода должны быть такими, чтобы в контроллере их значения появлялись в соответствующих местах в хэше params, и (iii) для существующего ресурса, когда форма первоначально отображается, поля ввода, соответствующие атрибутам ресурса, должны отображать текущие значения этих атрибутов.
В Rails это обычно достигается путем создания формы с помощью form_for и ряда связанных методов-помощников. form_for генерирует соответствующий тег form и возвращает объект генератора форм, который знает модель, к которой относится форма. Поля ввода создаются путем вызова методов, определенных в генераторе форм, что означает, что они могут генерировать соответствующие имена и значения по умолчанию, соответствующие атрибутам модели, а также удобные идентификаторы и т. д. Конвенции в сгенерированных именах полей позволяют контроллерам получать данные формы в виде красиво структурированного хэша params без дополнительных усилий с вашей стороны.
Например, для создания новой персоны обычно создается новый экземпляр Person в действии PeopleController#new, @person, и в шаблоне представления этот объект передается в form_for:
<%= form_for @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 — это существующий ресурс с именем «John Smith» и 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 1294
def check_box(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 отмечен. Дополнительные параметры тега ввода могут быть переданы в виде хэша с options. Значение по умолчанию для checked_value равно 1, а значение по умолчанию для unchecked_value равно 0, что удобно для булевых значений.
Примечание
Спецификация HTML гласит, что неотмеченные checkbox не обрабатываются, и поэтому веб-браузеры их не отправляют. К сожалению, это приводит к проблеме: если у модели Invoice есть флаг paid, и в форме для редактирования платного счета пользователь снимает флажок, параметр paid не отправляется. Таким образом, любое выражение массового назначения, такое как
@invoice.update(params[:invoice])
не обновит флаг.
Для предотвращения этого помощник генерирует дополнительное скрытое поле перед чекбоксом. Скрытое поле имеет то же имя, а его атрибуты имитируют неотмеченный checkbox.
Таким образом, клиент отправляет только скрытое поле (означающее, что checkbox не отмечен) или оба поля. Поскольку спецификация HTML гласит, что пары ключ/значение должны быть отправлены в том же порядке, в котором они появляются в форме, а извлечение параметров получает последнюю встречающуюся повторяющуюся пару ключей в строке запроса, это работает для обычных форм.
К сожалению, это решение не работает, когда checkbox находится внутри массивоподобного параметра, как в
<%= fields_for "project[invoice_attributes][]", invoice, index: nil do |form| %> <%= form.check_box :paid %> ... <% end %>
потому что Rails именно повторяющиеся имена параметров предназначены для различения элементов массива. Для каждого элемента с отмеченным checkbox вы получаете дополнительный «призрачный» элемент только с этим атрибутом, присвоенным «0».
В этом случае предпочтительнее использовать check_box_tag или использовать хэши вместо массивов.
# Let's say that @post.validated? is 1:
check_box("post", "validated")
# => <input name="post[validated]" type="hidden" value="0" />
# <input checked="checked" type="checkbox" id="post_validated" name="post[validated]" value="1" />
# Let's say that @puppy.gooddog is "no":
check_box("puppy", "gooddog", {}, "yes", "no")
# => <input name="puppy[gooddog]" type="hidden" value="no" />
# <input type="checkbox" id="puppy_gooddog" name="puppy[gooddog]" value="yes" />
check_box("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 1324
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 1388
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" />
В качестве альтернативы, вы можете передать строку, отформатированную как дата 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 1446
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" />
В качестве альтернативы, вы можете передать строку, отформатированную как 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" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1500
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 1054
def fields(scope = nil, model: nil, **options, &block)
options[:allow_method_names_outside_object] = true
options[:skip_default_ids] = !form_with_generates_ids
if model
scope ||= model_name_from_record_or_class(model).param_key
end
builder = instantiate_builder(scope, model, options)
capture(builder, &block)
end Ограничивает поля ввода с помощью явного scope или модели. Похоже на то, как 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: @post 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 %> <%= text_area :commenter, :biography %> <%= check_box_tag "comment[all_caps]", "1", @comment.commenter.hulk_mode? %> <% end %>
То же самое относится к методам в FormOptionsHelper и DateHelper, предназначенным для работы с объектом в качестве основы, как ActionView::Helpers::FormOptionsHelper#collection_select и ActionView::Helpers::DateHelper#datetime_select.
# File actionview/lib/action_view/helpers/form_helper.rb, line 1004
def fields_for(record_name, record_object = nil, options = {}, &block)
builder = instantiate_builder(record_name, record_object, options)
capture(builder, &block)
end Создаёт область действия вокруг определённого объекта модели, как #form_for, но не создаёт сами теги формы. Это делает #fields_for подходящим для указания дополнительных объектов модели в той же форме.
Хотя использование и назначение fields_for аналогично form_for, его сигнатура метода немного отличается. Как и form_for, он передаёт объект FormBuilder, связанный с конкретным объектом модели, в блок, и внутри блока можно вызывать методы для создания полей, связанных с объектом модели. Поля могут отражать объект модели двумя способами — как они названы (и, следовательно, как переданные значения отображаются в хэше params в контроллере) и какие значения по умолчанию отображаются, когда форма с полями отображается в первый раз. Для того, чтобы оба этих свойства можно было указать независимо, оба имени объекта (представленного символом или строкой) и сам объект могут быть переданы в метод отдельно —
<%= form_for @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.check_box :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.check_box :admin %> <% end %>
…в этом случае, если :permission также является именем переменной экземпляра @permission, начальное состояние поля ввода будет отражать значение атрибута этой переменной @permission.admin.
В качестве альтернативы, вы можете передать только сам объект модели (если первый аргумент не строка или символ, fields_for поймёт, что имя опущено) —
<%= fields_for @person.permission do |permission_fields| %> Admin?: <%= permission_fields.check_box :admin %> <% end %>
и fields_for выведет необходимое имя поля из класса объекта модели, например, если @person.permission, является экземпляром класса Permission, поле по-прежнему будет называться permission[admin].
Примечание: Это также работает для методов в FormOptionsHelper и DateHelper, которые предназначены для работы с объектом в качестве основы, например, ActionView::Helpers::FormOptionsHelper#collection_select и ActionView::Helpers::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_for @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 %> Если address уже является ассоциацией в 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_for @person do |person_form| %>
...
<%= person_form.fields_for :address do |address_fields| %>
...
Delete: <%= address_fields.check_box :_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_for @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_for @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_for @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_for @person do |person_form| %>
...
<%= person_form.fields_for :projects do |project_fields| %>
Delete: <%= project_fields.check_box :_destroy %>
<% end %>
...
<% end %> Когда используется коллекция, вы можете узнать индекс каждого объекта в массиве. Для этого в объекте FormBuilder доступен метод index.
<%= form_for @person do |person_form| %>
...
<%= person_form.fields_for :projects do |project_fields| %>
Project #<%= project_fields.index %>
...
<% end %>
...
<% end %> Обратите внимание, что #fields_for автоматически сгенерирует скрытое поле для хранения идентификатора записи. В некоторых случаях это скрытое поле не требуется, и вы можете передать include_id: false , чтобы предотвратить автоматическое рендеринг #fields_for.
# File actionview/lib/action_view/helpers/form_helper.rb, line 1206
def file_field(object_name, method, options = {})
Tags::FileField.new(object_name, method, self, convert_direct_upload_option_to_url(options.dup)).render
end Возвращает тег ввода для загрузки файлов, предназначенный для доступа к указанному атрибуту (определяемому method) объекта, присвоенного шаблону (определяемому object). Дополнительные параметры тега ввода можно передать в виде хэша с options. Эти параметры будут добавлены в HTML как атрибуты HTML-элемента, как показано в примере.
Использование этого метода внутри блока form_for задаст кодировку заключённой формы на multipart/form-data.
Параметры
-
Создаёт стандартные атрибуты HTML для тега.
-
:disabled- Если установлено в true, пользователь не сможет использовать этот элемент ввода. -
:multiple- Если установлено в true, *в большинстве современных браузеров* пользователь сможет выбрать несколько файлов. -
:accept- Если установлено на один или несколько MIME-типов, пользователю будет предложен фильтр при выборе файла. Вам всё равно необходимо настроить валидацию модели.
Примеры
file_field(:user, :avatar) # => <input type="file" id="user_avatar" name="user[avatar]" /> file_field(:post, :image, multiple: true) # => <input type="file" id="post_image" name="post[image][]" multiple="multiple" /> file_field(:post, :attached, accept: 'text/html') # => <input accept="text/html" type="file" id="post_attached" name="post[attached]" /> file_field(:post, :image, accept: 'image/png,image/gif,image/jpeg') # => <input type="file" id="post_image" name="post[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 430
def form_for(record, options = {}, &block)
raise ArgumentError, "Missing block" unless block_given?
html_options = options[:html] ||= {}
case record
when String, Symbol
object_name = record
object = nil
else
object = record.is_a?(Array) ? record.last : 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!(record, object, options)
end
html_options[:data] = options.delete(:data) if options.has_key?(:data)
html_options[:remote] = options.delete(:remote) if options.has_key?(:remote)
html_options[:method] = options.delete(:method) if options.has_key?(:method)
html_options[:enforce_utf8] = options.delete(:enforce_utf8) if options.has_key?(:enforce_utf8)
html_options[:authenticity_token] = options.delete(:authenticity_token)
builder = instantiate_builder(object_name, object, options)
output = capture(builder, &block)
html_options[:multipart] ||= builder.multipart?
html_options = html_options_for_form(options[:url] || {}, html_options)
form_tag_with_body(html_options, output)
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.text_area :biography %><br /> Admin? : <%= f.check_box :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 управлять поведением отправки. По умолчанию это поведение — ajax отправка. -
: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 : <%= text_area :person, :biography %> Admin? : <%= check_box_tag "person[admin]", "1", @person.company.admin? %> <%= f.submit %> <% end %>
Это также работает для методов в FormOptionsHelper и DateHelper, которые предназначены для работы с объектом в качестве основы, например, ActionView::Helpers::FormOptionsHelper#collection_select и ActionView::Helpers::DateHelper#datetime_select.
form_for с объектом модели
В примерах выше объект, подлежащий созданию или редактированию, представлялся символом, переданным в form_for, и мы отметили, что строка может быть использована аналогично. Однако также можно передать сам объект модели в form_for. Например, если @post — это существующая запись, которую вы хотите отредактировать, вы можете создать форму с помощью
<%= form_for @post do |f| %> ... <% end %>
Это работает почти так же, как описано ранее, с парой небольших исключений. Во-первых, префикс, используемый для именования элементов ввода в форме (следовательно, ключ, который обозначает их в хэше params ), фактически выводится из класса объекта, например params[:post] , если класс объекта Post. Однако это можно переопределить, используя опцию :as, например:
<%= form_for(@person, as: :client) do |f| %> ... <% end %>
что приведёт к params[:client].
Во-вторых, значения полей, отображаемые при первоначальном отображении формы, берутся из атрибутов объекта, переданного в form_for, независимо от того, является ли объект экземпляром переменной. Например, если у нас есть локальная переменная post, представляющая существующую запись,
<%= form_for post do |f| %> ... <% end %>
отобразит форму с полями, начальное состояние которых отражает текущие значения атрибутов post.
Стиль ориентированный на ресурсы
В только что показанных примерах, хотя и не указано явно, нам всё равно нужно использовать опцию :url для указания места отправки формы. Однако дальнейшее упрощение возможно, если запись, переданная в form_for , является ресурсом, т.е. соответствует набору маршрутов RESTful, например, определённых с помощью метода resources в config/routes.rb. В этом случае Rails просто выведет соответствующий URL из самой записи. Например,
<%= form_for @post do |f| %> ... <% end %>
равнозначно чему-то вроде:
<%= form_for @post, as: :post, url: post_path(@post), method: :patch, html: { class: "edit_post", id: "edit_post_45" } do |f| %>
...
<% end %> А для новой записи
<%= form_for(Post.new) do |f| %> ... <% end %>
равнозначно чему-то вроде:
<%= form_for @post, as: :post, url: posts_path, html: { class: "new_post", id: "new_post" } do |f| %>
...
<% end %> Однако вы можете всё ещё переопределить отдельные соглашения, такие как:
<%= form_for(@post, url: super_posts_path) do |f| %> ... <% end %>
Вы также можете задать формат ответа, например, так:
<%= form_for(@post, format: :json) do |f| %> ... <% end %>
Для маршрутов с именами пространств имён, таких как admin_post_url:
<%= form_for([:admin, @post]) 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 изменять её поведение. Ожидаемое поведение по умолчанию — это отправка XMLHttpRequest в фоновом режиме вместо обычной POST-отправки, но в конечном итоге поведение зависит от реализатора драйвера JavaScript. Несмотря на то, что для сериализации элементов формы используется JavaScript, отправка формы будет работать так же, как и обычная отправка, с точки зрения стороны получения (все элементы доступны в params).
Пример:
<%= form_for(@post, 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(@post, 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>
Удаление скрытых идентификаторов модели
Метод #form_for автоматически включает идентификатор модели в качестве скрытого поля в форме. Это используется для поддержания корреляции между данными формы и связанной с ней моделью. Некоторые системы ORM не используют ID в вложенных моделях, поэтому в этом случае вам нужно будет отключить скрытый ID.
В следующем примере модель Post имеет множество Comments, хранящихся в ней в базе данных NoSQL, поэтому для комментариев нет первичного ключа.
Пример:
<%= form_for(@post) 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.text_area :biography %>
<%= f.check_box :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
Если вам не нужно привязывать форму к экземпляру модели, см. ActionView::Helpers::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 739
def form_with(model: nil, scope: nil, url: nil, format: nil, **options)
options[:allow_method_names_outside_object] = true
options[:skip_default_ids] = !form_with_generates_ids
if model
url ||= polymorphic_path(model, format: format)
model = model.last if model.is_a?(Array)
scope ||= model_name_from_record_or_class(model).param_key
end
if block_given?
builder = instantiate_builder(scope, model, options)
output = capture(builder, &Proc.new)
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: posts_path do |form| %> <%= form.text_field :title %> <% end %> # => <form action="/posts" method="post" data-remote="true"> <input type="text" name="title"> </form> # Adding a scope prefixes the input field names: <%= form_with scope: :post, url: posts_path do |form| %> <%= form.text_field :title %> <% end %> # => <form action="/posts" method="post" data-remote="true"> <input type="text" name="post[title]"> </form> # Using a model infers both the URL and scope: <%= form_with model: Post.new do |form| %> <%= form.text_field :title %> <% end %> # => <form action="/posts" method="post" data-remote="true"> <input type="text" name="post[title]"> </form> # An existing model makes an update form and fills out field values: <%= form_with model: Post.first do |form| %> <%= form.text_field :title %> <% end %> # => <form action="/posts/1" method="post" data-remote="true"> <input type="hidden" name="_method" value="patch"> <input type="text" name="post[title]" value="<the title of the post>"> </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" data-remote="true"> <input type="text" name="cat[cats_dont_have_gills]"> <input type="text" name="cat[but_in_forms_they_can]"> </form>
Параметры в формах доступны в контроллерах в соответствии с их вложенностью имён. Таким образом, поля с именами title и post[title] доступны как params[:title] и params[:post][:title] соответственно.
По умолчанию form_with добавляет атрибут data-remote, отправляя форму через XMLHTTPRequest в фоновом режиме, если используется драйвер Unobtrusive JavaScript, такой как rails-ujs. Смотрите опцию :local для получения дополнительной информации.
Для простоты сравнения в примерах выше отсутствует кнопка отправки, а также автоматически сгенерированные скрытые поля, которые обеспечивают поддержку UTF-8 и добавляют маркер подлинности, необходимый для защиты от межсайтовых атак с подделкой запроса.
Ресурсно-ориентированный стиль
Во многих представленных примерах :model передаваемое в form_with является ресурсом. Он соответствует набору RESTful маршрутов, скорее всего, определённых через resources в config/routes.rb.
Поэтому при передаче такой записи модели Rails определяет URL и метод.
<%= form_with model: @post do |form| %> ... <% end %>
тогда эквивалентно примерно:
<%= form_with scope: :post, url: post_path(@post), method: :patch do |form| %> ... <% end %>
А для новой записи
<%= form_with model: Post.new do |form| %> ... <% end %>
эквивалентно примерно:
<%= form_with scope: :post, url: posts_path do |form| %> ... <% end %>
Опции
-
:url- URL, на который отправляется форма. Аналогично значениям, передаваемым вurl_forилиlink_to. Например, вы можете использовать именованный маршрут напрямую. Если:scopeпередаётся без:url, форма отправляется на текущий URL. -
:method- Метод, используемый при отправке формы, обычно «get» или «post». Если используется «patch», «put», «delete» или другой глагол, добавляется скрытое поле с именем_method, чтобы смоделировать глагол над отправкой POST. -
:format- Формат маршрута, на который отправляется форма. Полезно при отправке на другой тип ресурса, например,:json. Пропускается, если передаётся:url. -
:scope- Область для добавления префикса к именам полей ввода, а также для группировки переданных параметров в контроллерах. -
:model- Объект модели для определения:urlи:scopeи заполнения значений полей ввода. Так, если атрибутtitleустановлен в «Ahoy!», то значение поля вводаtitleбудет «Ahoy!». Если модель — новая запись, генерируется форма создания, в противном случае — форма обновления. Передайте:scopeили:urlдля переопределения значений по умолчанию. Например, преобразуйтеparams[:post]вparams[:article]. -
:authenticity_token- Маркер подлинности, используемый в форме. Переопределите его с помощью настраиваемого маркера подлинности или передайтеfalseдля пропуска поля маркера подлинности. Полезно при отправке на внешний ресурс, такой как платёжный шлюз, который может ограничивать допустимые поля. Дистанционные формы могут опускать встроенный маркер подлинности, установивconfig.action_view.embed_authenticity_token_in_remote_forms = false. Это полезно при кэшировании фрагментов форм. Дистанционные формы получают маркер подлинности из тегаmeta, поэтому встраивание не требуется, если вы поддерживаете браузеры без JavaScript. -
:local- По умолчанию отправка форм является удалённой и незаметной XHR. Отключите удалённую отправку с помощьюlocal: true. -
:skip_enforcing_utf8- По умолчанию выводится скрытое поле с именемutf8для принудительного отправления UTF-8. Установите в значение true, чтобы пропустить это поле. -
:builder- Переопределите объект, используемый для построения формы. -
:id- Дополнительный атрибут id HTML. -
:class- Дополнительный атрибут class HTML. -
:data- Дополнительные атрибуты data HTML. -
:html- Другие дополнительные атрибуты тега формы.
Примеры
Если не передавать блок, form_with генерирует только открывающий тег формы.
<%= form_with(model: @post, url: super_posts_path) %> <%= form_with(model: @post, scope: :article) %> <%= form_with(model: @post, format: :json) %> <%= form_with(model: @post, authenticity_token: false) %> # Disables the token.
Для маршрутов с именованными пространствами, например, admin_post_url:
<%= form_with(model: [ :admin, @post ]) 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 %> <%= text_area :person, :biography %> <%= check_box_tag "person[admin]", "1", @person.company.admin? %> <%= form.submit %> <% end %>
То же самое относится к методам в FormOptionsHelper и DateHelper, предназначенным для работы с объектом в качестве базы, как ActionView::Helpers::FormOptionsHelper#collection_select и ActionView::Helpers::DateHelper#datetime_select.
Установка метода
Вы можете принудительно заставить форму использовать весь набор HTTP-глаголов, установив
method: (:get|:post|:patch|:put|:delete)
в хэше опций. Если глагол не GET или POST, которые изначально поддерживаются HTML-формами, форма будет установлена на POST, а скрытый ввод с именем _method будет содержать целевой глагол, который сервер интерпретирует.
Установка HTML-опций
Вы можете установить атрибуты data непосредственно в хэше данных, но HTML-опции помимо id и class должны быть заключены в ключ HTML:
<%= form_with(model: @post, data: { behavior: "autosave" }, html: { name: "go" }) do |form| %>
...
<% end %> генерирует
<form action="/posts/123" method="post" data-behavior="autosave" name="go"> <input name="_method" type="hidden" value="patch" /> ... </form>
Удаление скрытых id моделей
Метод form_with автоматически включает id модели в качестве скрытого поля в форме. Это используется для поддержания корреляции между данными формы и связанной моделью. Некоторые системы ORM не используют ID вложенных моделей, поэтому в этом случае вы хотите иметь возможность отключить скрытый ID.
В следующем примере модель Post имеет много комментариев, хранящихся в ней в базе данных NoSQL, поэтому для комментариев нет первичного ключа.
<%= form_with(model: @post) 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.text_area :biography %>
<%= form.check_box :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(:post, :tag_list)
# => <input type="hidden" id="post_tag_list" name="post[tag_list]" value="#{@post.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 1114 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 (где значение используется в идентификаторе тега ввода).
Примеры
label(:post, :title) # => <label for="post_title">Title</label>
Вы можете локализовать свои метки на основе имен модели и атрибута. Например, вы можете определить следующее в своём локали (например, en.yml)
helpers:
label:
post:
body: "Write your entire text here" Что затем приведёт к
label(:post, :body) # => <label for="post_body">Write your entire text here</label>
Локализация также может осуществляться исключительно на основе перевода имени атрибута (если вы используете ActiveRecord):
activerecord:
attributes:
post:
cost: "Total cost"
label(:post, :cost)
# => <label for="post_cost">Total cost</label>
label(:post, :title, "A short title")
# => <label for="post_title">A short title</label>
label(:post, :title, "A short title", class: "title_label")
# => <label for="post_title" class="title_label">A short title</label>
label(:post, :privacy, "Public Post", value: "public")
# => <label for="post_privacy_public">Public Post</label>
label(:post, :terms) do
raw('Accept <a href="/terms">Terms</a>.')
end
# => <label for="post_terms">Accept <a href="/terms">Terms</a>.</label> # File actionview/lib/action_view/helpers/form_helper.rb, line 1465
def month_field(object_name, method, options = {})
Tags::MonthField.new(object_name, method, self, options).render
end Возвращает #text_field типа «month».
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 1508
def number_field(object_name, method, options = {})
Tags::NumberField.new(object_name, method, self, options).render
end Возвращает тег input типа “number”.
Параметры
-
Принимает те же параметры, что и number_field_tag
# File actionview/lib/action_view/helpers/form_helper.rb, line 1156
def password_field(object_name, method, options = {})
Tags::PasswordField.new(object_name, method, self, options).render
end Возвращает тег input типа “password”, предназначенный для доступа к указанному атрибуту (идентифицируемому по method) объекта, назначенного шаблону (идентифицируемому по object). Дополнительные параметры тега input могут быть переданы в виде хэша с options. Эти параметры будут добавлены в 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 1316
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 @post.category returns "rails":
radio_button("post", "category", "rails")
radio_button("post", "category", "java")
# => <input type="radio" id="post_category_rails" name="post[category]" value="rails" checked="checked" />
# <input type="radio" id="post_category_java" name="post[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 1516
def range_field(object_name, method, options = {})
Tags::RangeField.new(object_name, method, self, options).render
end Возвращает тег input типа “range”.
Параметры
-
Принимает те же параметры, что и range_field_tag
# File actionview/lib/action_view/helpers/form_helper.rb, line 1347
def search_field(object_name, method, options = {})
Tags::SearchField.new(object_name, method, self, options).render
end Возвращает input типа “search” для доступа к указанному атрибуту (идентифицируемому по method) объекта, назначенного шаблону (идентифицируемому по object_name). Входные данные типа “search” могут отображаться по-разному в разных браузерах.
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 1356
def telephone_field(object_name, method, options = {})
Tags::TelField.new(object_name, method, self, options).render
end Возвращает #text_field типа “tel”.
telephone_field("user", "phone")
# => <input id="user_phone" name="user[phone]" type="tel" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1234
def text_area(object_name, method, options = {})
Tags::TextArea.new(object_name, method, self, options).render
end Возвращает тег textarea, настроенный для доступа к указанному атрибуту (идентифицируемому по method) объекта, назначенного шаблону (идентифицируемому по object). Дополнительные параметры тега input могут быть переданы в виде хэша с options.
Примеры
text_area(:post, :body, cols: 20, rows: 40)
# => <textarea cols="20" rows="40" id="post_body" name="post[body]">
# #{@post.body}
# </textarea>
text_area(:comment, :text, size: "20x30")
# => <textarea cols="20" rows="30" id="comment_text" name="comment[text]">
# #{@comment.text}
# </textarea>
text_area(: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>
text_area(: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 1135
def text_field(object_name, method, options = {})
Tags::TextField.new(object_name, method, self, options).render
end Возвращает тег input типа “text”, настроенный для доступа к указанному атрибуту (идентифицируемому по method) объекта, назначенного шаблону (идентифицируемому по object). Дополнительные параметры тега input могут быть переданы в виде хэша с options. Эти параметры будут добавлены в HTML как атрибуты элемента, как в приведённом примере.
Примеры
text_field(:post, :title, size: 20)
# => <input type="text" id="post_title" name="post[title]" size="20" value="#{@post.title}" />
text_field(:post, :title, class: "create_input")
# => <input type="text" id="post_title" name="post[title]" value="#{@post.title}" class="create_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 1417
def time_field(object_name, method, options = {})
Tags::TimeField.new(object_name, method, self, options).render
end Возвращает #text_field типа “time”.
Значение по умолчанию генерируется путём вызова strftime с “%T.%L” на значении объекта. Его всё ещё можно переопределить, передав параметр “value”.
Параметры
-
Принимает те же параметры, что и 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" />
В качестве альтернативы вы можете передать строку, отформатированную как ISO8601 время, в качестве значений для “min” и “max”.
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" />
# File actionview/lib/action_view/helpers/form_helper.rb, line 1491
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 1482
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–2018 David Heinemeier Hansson
Licensed under the MIT License.