модуль 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 — это существующая запись с именем «Иван Иванов» и 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 1305
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 будет отмечен. Дополнительные опции тега input могут быть переданы в виде хеша с options. Значение checked_value по умолчанию равно 1, а значение unchecked_value по умолчанию равно 0, что удобно для булевых значений.
Особенности
Спецификация HTML гласит, что неотмеченные checkboxes не передаются, и поэтому веб-браузеры их не отправляют. К сожалению, это создаёт проблему: если у модели 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 1335
def color_field(object_name, method, options = {})
Tags::ColorField.new(object_name, method, self, options).render
end Возвращает text_field типа «цвет».
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 1399
def date_field(object_name, method, options = {})
Tags::DateField.new(object_name, method, self, options).render
end Возвращает text_field типа «дата».
date_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="date" />
Значение по умолчанию генерируется путём вызова strftime с «%Y-%m-%d» для значения объекта, что обеспечивает ожидаемое поведение для экземпляров DateTime и ActiveSupport::TimeWithZone. Вы всё ещё можете переопределить это, явно передав опцию «значение», например:
@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" />
Вы можете создать значения для атрибутов «мин» и «макс», передав экземпляры 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 как значения для «мин» и «макс».
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 1457
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" />
Вы можете создать значения для атрибутов «мин» и «макс», передав экземпляры 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 как значения для «мин» и «макс».
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 1511
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 1052
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 Ограничивает поля ввода явным ограничением или моделью. Похоже на то, как 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, предназначенных для работы с объектом в качестве базы, как FormOptionsHelper#collection_select и DateHelper#datetime_select.
# File actionview/lib/action_view/helpers/form_helper.rb, line 1002
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, он передаёт объект 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, которые предназначены для работы с объектом в качестве базового, например, 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_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 %> Когда используется коллекция, может потребоваться знать индекс каждого объекта в массиве. Для этой цели доступен метод index в объекте FormBuilder.
<%= form_for @person do |person_form| %>
...
<%= person_form.fields_for :projects do |project_fields| %>
Project #<%= project_fields.index %>
...
<% end %>
...
<% end %> Обратите внимание, что fields_for автоматически сгенерирует скрытое поле для хранения ID записи. Существуют ситуации, когда это скрытое поле не нужно, и вы можете передать include_id: false для предотвращения автоматического рендеринга скрытого поля fields_for.
# File actionview/lib/action_view/helpers/form_helper.rb, line 1217
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 428
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 управлять поведением отправки. -
: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, которые предназначены для работы с объектом в качестве базы, например, FormOptionsHelper#collection_select и 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 изменять ее поведение. Отправка формы будет работать точно так же, как обычная отправка с точки зрения стороны приема (все элементы доступны в 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 не используют идентификаторы в вложенных моделях, поэтому в этом случае вы хотите иметь возможность отключить скрытый идентификатор.
В следующем примере модель Post имеет несколько комментариев, хранящихся в ней в базе данных 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
Если вам не нужно привязывать форму к экземпляру модели, ознакомьтесь с 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 737
def form_with(model: nil, scope: nil, url: nil, format: nil, **options, &block)
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, &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: 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] соответственно.
Для удобства сравнения в примерах выше отсутствуют кнопка отправки, а также автоматически генерируемые скрытые поля, которые обеспечивают поддержку 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— область, с которой следует префикс имени поля ввода, и, таким образом, как отправленные параметры группируются в контроллерах. -
:namespace— пространство имён для вашей формы, чтобы обеспечить уникальность идентификаторов элементов формы. Атрибут пространства имён будет префиксным символом подчёркивания в сгенерированном HTML-идентификаторе. -
:model— объект модели, для вывода:urlи:scopeпо нему, плюс заполнение значений полей ввода. Так, если атрибутtitleустановлен на «Привет!», значение поля вводаtitleбудет «Привет!». Если модель является новой записью, генерируется форма создания, если же запись существующей — форма обновления. Передайте:scopeили:urlдля переопределения значений по умолчанию. Например, преобразуйтеparams[:post]вparams[:article]. -
:authenticity_token— токен подлинности для использования в форме. Переопределите с помощью пользовательского токена подлинности или передайтеfalse, чтобы вообще пропустить поле токена подлинности. Полезно при отправке на внешний ресурс, например, платежный шлюз, который может ограничивать допустимые поля. Дистанционные формы могут опустить встроенный токен подлинности, установивconfig.action_view.embed_authenticity_token_in_remote_forms = false. Это полезно при кэшировании фрагментов форм. Дистанционные формы получают токен подлинности из тегаmeta, поэтому встраивание не требуется, если вы поддерживаете браузеры без JavaScript. -
:local— по умолчанию форма отправляется с помощью обычных HTTP-запросов. Включите удалённые и незаметные XHR-отправку сlocal: false. Дистанционные формы могут быть включены по умолчанию, установивconfig.action_view.form_with_generates_remote_forms = true. -
:skip_enforcing_utf8— Если установлено в true, скрытый ввод с именем utf8 не выводится. -
:builder— Переопределить объект, используемый для построения формы. -
:id— необязательный атрибут HTML id. -
:class— необязательный атрибут HTML class. -
:data— необязательные атрибуты HTML 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, предназначенные для работы с объектом в качестве основы, таких как 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: @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>
Удаление скрытых идентификаторов моделей
Метод form_with автоматически включает идентификатор модели в качестве скрытого поля в форме. Это используется для поддержания связи между данными формы и связанной с ней моделью. Некоторые системы ORM не используют идентификаторы вложенных моделей, поэтому в этом случае вы хотите иметь возможность отключить скрытый идентификатор.
В следующем примере модель 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 1122 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, :cost) do |translation|
content_tag(:span, translation, class: "cost_label")
end
# => <label for="post_cost"><span class="cost_label">Total cost</span></label>
label(:post, :cost) do |builder|
content_tag(:span, builder.translation, class: "cost_label")
end
# => <label for="post_cost"><span class="cost_label">Total cost</span></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 1476
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 1519
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 1167
def password_field(object_name, method, options = {})
Tags::PasswordField.new(object_name, method, self, options).render
end Возвращает тег input типа “password”, настроенный для доступа к указанному атрибуту (определяемому method) объекта, назначенного шаблону (определяемому object). Дополнительные параметры тега input могут быть переданы в виде хеша с 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 1327
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 1527
def range_field(object_name, method, options = {})
Tags::RangeField.new(object_name, method, self, options).render
end Возвращает тег input типа “range”.
Параметры
-
Поддерживает те же параметры, что и range_field_tag
# File actiontext/app/helpers/action_text/tag_helper.rb, line 77
def rich_text_area(object_name, method, options = {})
Tags::ActionText.new(object_name, method, self, options).render
end Возвращает тег trix-editor, который инициализирует JavaScript-редактор Trix, а также скрытое поле, в которое Trix записывает изменения, чтобы содержимое отправлялось при отправке формы.
Параметры
-
:class- По умолчанию «trix-content», что обеспечивает применение стилей по умолчанию. -
:value- Добавляет значение по умолчанию в тег HTML input.
Пример
form_with(model: @message) do |form| form.rich_text_area :content end # <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> form_with(model: @message) do |form| form.rich_text_area :content, value: "<h1>Default message</h1>" end # <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 1358
def search_field(object_name, method, options = {})
Tags::SearchField.new(object_name, method, self, options).render
end Возвращает поле ввода типа “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 1367
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 1245
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 1146
def text_field(object_name, method, options = {})
Tags::TextField.new(object_name, method, self, options).render
end Возвращает тег input типа “text”, настроенный для доступа к указанному атрибуту (определяемому method) объекта, назначенного шаблону (определяемому object). Дополнительные параметры тега input могут быть переданы в виде хеша с options. Эти параметры будут добавлены к HTML в качестве атрибутов 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(:post, :title, maxlength: 30, class: "title_input")
# => <input type="text" id="post_title" name="post[title]" maxlength="30" size="30" value="#{@post.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 1428
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 1502
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 1493
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–2020 David Heinemeier Hansson
Licensed under the MIT License.