Action View 表单助手¶ ↑
与使用纯 HTML 相比,表单助手旨在使处理资源更加容易。
通常,用于创建或更新资源的表单会在几个方面反映资源的身份:(i) 表单发送到的 URL(表单元素的 action 属性)应能将请求路由到适当的控制器操作(对于现有资源,还需包含适当的 :id 参数),(ii) 输入字段的命名方式应能让其值在控制器中出现在 params 哈希的相应位置,并且 (iii) 对于现有记录,当表单首次显示时,与资源属性对应的输入字段应显示这些属性的当前值。
在 Rails 中,这通常通过使用 form_with 或 form_for 以及一系列相关的助手方法来创建表单来实现。这些方法会生成一个适当的 form 标签,并提供一个了解表单所关联的模型(model)的表单构建器对象。通过调用表单构建器上定义的方法来创建输入字段,这意味着它们能够生成与模型属性相对应的适当名称和默认值,以及方便的 ID 等。生成的字段名称的约定允许控制器能够轻松地以结构化的方式在 params 中接收表单数据。
例如,要创建一个新的人员,您通常会在 PeopleController#new 操作中设置一个 Person 的新实例,即 @person,然后在视图模板中将该对象传递给 form_with 或 form_for。
<%= form_with model: @person do |f| %> <%= f.label :first_name %>: <%= f.text_field :first_name %><br /> <%= f.label :last_name %>: <%= f.text_field :last_name %><br /> <%= f.submit %> <% end %>
这将生成的 HTML 是(格式略有不同)
<form action="/people" class="new_person" id="new_person" method="post"> <input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" /> <label for="person_first_name">First name</label>: <input id="person_first_name" name="person[first_name]" type="text" /><br /> <label for="person_last_name">Last name</label>: <input id="person_last_name" name="person[last_name]" type="text" /><br /> <input name="commit" type="submit" value="Create Person" /> </form>
您可以看到,HTML 在几个地方反映了对资源的了解,例如表单应提交到的路径,或者输入字段的名称。
特别是,由于生成的字段名称遵循约定,控制器将收到一个嵌套的哈希 params[:person],其中包含表单设置的人员属性。该哈希可以直接传递给 Person.new。
@person = Person.new(params[:person]) if @person.save # success else # error handling end
有趣的是,在前面的示例中完全相同的视图代码也可以用于编辑人员。如果 @person 是一个现有记录,名为“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
这就是您通常处理资源的方式。
- C
- D
- E
- F
- H
- L
- M
- N
- P
- R
- S
- T
- U
- W
实例公共方法
check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0") Link
checkbox(object_name, method, options = {}, checked_value = "1", unchecked_value = "0") Link
返回一个复选框标签,该标签经过定制,用于访问模板中指定对象(由 object 标识)的指定属性(由 method 标识)。此对象必须是实例对象(@object),而不是局部对象。它的目的是让 method 返回一个整数,如果该整数大于零,则复选框被选中。可以通过一个包含 options 的哈希来传递输入标签的其他选项。checked_value 默认为 1,而默认的 unchecked_value 设置为 0,这对于布尔值很方便。
选项¶ ↑
-
可以传递任何标准的 HTML 属性给标签,例如
:class。 -
:checked-true或false,强制复选框的状态为选中或未选中。 -
:include_hidden- 如果设置为 false,则不会生成下面描述的辅助隐藏字段。
陷阱¶ ↑
HTML 规范规定未选中的复选框不成功,因此 Web 浏览器不会发送它们。不幸的是,这会引入一个陷阱:如果一个 Invoice 模型有一个 paid 标志,并且在编辑已付款发票的表单中,用户取消了其复选框的选中状态,则不会发送 paid 参数。因此,任何批量赋值的惯用法,如
@invoice.update(params[:invoice])
将不会更新标志。
为了防止这种情况,助手会在每个复选框之前生成一个辅助隐藏字段。隐藏字段具有相同的名称,其属性模仿未选中的复选框。
这样,客户端要么只发送隐藏字段(表示复选框未选中),要么同时发送两个字段。由于 HTML 规范规定键/值对必须按照它们在表单中出现的顺序发送,并且参数提取会获取查询字符串中任何重复键的最后一个出现项,因此这对普通表单来说是有效的。
不幸的是,当复选框位于类似数组的参数中时,此解决方法无效,如下所示:
<%= fields_for "project[invoice_attributes][]", invoice, index: nil do |form| %> <%= form.checkbox :paid %> ... <% end %>
因为参数名称重复正是 Rails 试图区分数组元素的意图。对于每个选中的复选框项,您会得到一个额外的“幽灵”项,其中只有该属性,并赋值为“0”。
在这种情况下,最好使用 FormTagHelper#checkbox_tag 或使用哈希而不是数组。
示例¶ ↑
# Let's say that @article.validated? is 1: checkbox("article", "validated") # => <input name="article[validated]" type="hidden" value="0" /> # <input checked="checked" type="checkbox" id="article_validated" name="article[validated]" value="1" /> # Let's say that @puppy.gooddog is "no": checkbox("puppy", "gooddog", {}, "yes", "no") # => <input name="puppy[gooddog]" type="hidden" value="no" /> # <input type="checkbox" id="puppy_gooddog" name="puppy[gooddog]" value="yes" /> checkbox("eula", "accepted", { class: 'eula_check' }, "yes", "no") # => <input name="eula[accepted]" type="hidden" value="no" /> # <input type="checkbox" class="eula_check" id="eula_accepted" name="eula[accepted]" value="yes" />
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1346 def checkbox(object_name, method, options = {}, checked_value = "1", unchecked_value = "0") Tags::CheckBox.new(object_name, method, self, checked_value, unchecked_value, options).render end
color_field(object_name, method, options = {}) Link
返回类型为“color”的 text_field。
color_field("car", "color") # => <input id="car_color" name="car[color]" type="color" value="#000000" />
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1377 def color_field(object_name, method, options = {}) Tags::ColorField.new(object_name, method, self, options).render end
date_field(object_name, method, options = {}) Link
返回类型为“date”的 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 的实例来说表现符合预期。您仍然可以通过显式传递 “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" />
您可以通过将 Date 或 Time 的实例传递给选项哈希来创建“min”和“max”属性的值。
date_field("user", "born_on", min: Date.today) # => <input id="user_born_on" name="user[born_on]" type="date" min="2014-05-20" />
或者,您可以将格式为 ISO8601 日期的 String 作为“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" />
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1441 def date_field(object_name, method, options = {}) Tags::DateField.new(object_name, method, self, options).render end
datetime_field(object_name, method, options = {}) Link
返回类型为“datetime-local”的 text_field。
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 的实例传递给选项哈希来创建“min”和“max”属性的值。
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 日期时间的 String 作为“min”和“max”的值传递。
datetime_field("user", "born_on", min: "2014-05-20T00:00:00") # => <input id="user_born_on" name="user[born_on]" type="datetime-local" min="2014-05-20T00:00:00.000" />
默认情况下,提供的日期时间将包含秒。通过传递 include_seconds: false,可以只渲染日期、小时和分钟。
@user.born_on = Time.current datetime_field("user", "born_on", include_seconds: false) # => <input id="user_born_on" name="user[born_on]" type="datetime-local" value="2014-05-20T14:35" />
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1514 def datetime_field(object_name, method, options = {}) Tags::DatetimeLocalField.new(object_name, method, self, options).render end
email_field(object_name, method, options = {}) Link
返回类型为“email”的 text_field。
email_field("user", "address") # => <input id="user_address" name="user[address]" type="email" />
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1568 def email_field(object_name, method, options = {}) Tags::EmailField.new(object_name, method, self, options).render end
fields(scope = nil, model: nil, **options, &block) Link
通过显式作用域或模型来限制输入字段。类似于 form_with 使用 :scope 或 :model,但它不输出表单标签。
# Using a scope prefixes the input field names:
<%= fields :comment do |fields| %>
<%= fields.text_field :body %>
<% end %>
# => <input type="text" name="comment[body]">
# Using a model infers the scope and assigns field values:
<%= fields model: Comment.new(body: "full bodied") do |fields| %>
<%= fields.text_field :body %>
<% end %>
# => <input type="text" name="comment[body]" value="full bodied">
# Using `fields` with `form_with`:
<%= form_with model: @article do |form| %>
<%= form.text_field :title %>
<%= form.fields :comment do |fields| %>
<%= fields.text_field :body %>
<% end %>
<% end %>
与 form_with 非常相似,一个与作用域或模型关联的 FormBuilder 实例会被传递,因此任何生成的字段名称都会被加上传递的作用域前缀,或者从 :model 推断出的作用域。
与其他表单助手的混合使用¶ ↑
虽然 form_with 使用 FormBuilder 对象,但也可以混合使用独立的 FormHelper 方法和 FormTagHelper 中的方法。
<%= fields model: @comment do |fields| %> <%= fields.text_field :body %> <%= textarea :commenter, :biography %> <%= checkbox_tag "comment[all_caps]", "1", @comment.commenter.hulk_mode? %> <% end %>
对于 FormOptionsHelper 和 DateHelper 中设计用于以对象为基础的方法,例如 FormOptionsHelper#collection_select 和 DateHelper#datetime_select,也是如此。
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1079 def fields(scope = nil, model: nil, **options, &block) options = { allow_method_names_outside_object: true, skip_default_ids: !form_with_generates_ids }.merge!(options) if model model = _object_for_form_builder(model) scope ||= model_name_from_record_or_class(model).param_key end builder = instantiate_builder(scope, model, options) capture(builder, &block) end
fields_for(record_name, record_object = nil, options = {}, &block) Link
创建与特定模型对象相关的作用域,类似于 form_with,但不创建表单标签本身。这使得 fields_for 适用于在同一表单中指定其他模型对象。
尽管 fields_for 的用法和目的与 form_with 类似,但其方法签名略有不同。与 form_with 一样,它将一个与特定模型对象关联的 FormBuilder 对象传递给一个块,并在块内允许调用构建器上的方法来生成与模型对象关联的字段。字段可以通过两种方式反映模型对象——它们如何命名(因此提交的值如何在控制器中的 params 哈希中显示),以及表单字段首次显示时显示的默认值。为了能够独立指定这两个功能,可以分别将对象名称(由符号或字符串表示)和对象本身传递给方法——
<%= form_with model: @person do |person_form| %>
First name: <%= person_form.text_field :first_name %>
Last name : <%= person_form.text_field :last_name %>
<%= fields_for :permission, @person.permission do |permission_fields| %>
Admin? : <%= permission_fields.checkbox :admin %>
<% end %>
<%= person_form.submit %>
<% end %>
在这种情况下,复选框字段将由一个 HTML input 标签表示,其 name 属性为 permission[admin],提交的值将在控制器中显示为 params[:permission][:admin]。如果 @person.permission 是一个具有 admin 属性的现有记录,则复选框首次显示时,其初始状态将反映 @person.permission.admin 的值。
通常,只需将模型对象的名称传递给 fields_for 即可简化这一点——
<%= fields_for :permission do |permission_fields| %> Admin?: <%= permission_fields.checkbox :admin %> <% end %>
在这种情况下,如果 :permission 也恰好是实例变量 @permission 的名称,则输入字段的初始状态将反映该变量的属性 @permission.admin 的值。
或者,您也可以只传递模型对象本身(如果第一个参数不是字符串或符号,fields_for 将识别出名称已被省略)——
<%= fields_for @person.permission do |permission_fields| %> Admin?: <%= permission_fields.checkbox :admin %> <% end %>
并且 fields_for 将从模型对象的 *类* 中派生出必需的字段名称,例如,如果 @person.permission 的类是 Permission,则字段仍将命名为 permission[admin]。
注意:这同样适用于 FormOptionsHelper 和 DateHelper 中设计用于以对象为基础的方法,例如 FormOptionsHelper#collection_select 和 DateHelper#datetime_select。
嵌套属性示例¶ ↑
当当前作用域的对象对于某个属性具有嵌套属性写入器时,fields_for 将为该属性生成一个新的作用域。这允许您创建表单来一次性设置或修改父对象及其关联对象的属性。
嵌套属性写入器是名为关联的普通 setter 方法。定义这些写入器的最常见方法是在模型定义中使用 accepts_nested_attributes_for,或者定义一个具有正确名称的方法。例如:关联 :address 的属性写入器名为 address_attributes=。
生成的表单构建器是单向的还是多向的,取决于普通读取器方法返回的是一个 *单个* 对象还是一个 *数组* 对象。
一对一¶ ↑
考虑一个 Person 类,它从 address 读取器方法返回一个 *单个* Address 对象,并响应 address_attributes= 写入器方法。
class Person def address @address end def address_attributes=(attributes) # Process the attributes hash end end
现在可以使用嵌套的 fields_for 来使用此模型,如下所示:
<%= form_with model: @person do |person_form| %>
...
<%= person_form.fields_for :address do |address_fields| %>
Street : <%= address_fields.text_field :street %>
Zip code: <%= address_fields.text_field :zip_code %>
<% end %>
...
<% end %>
当 address 已经是 Person 的关联时,您可以使用 accepts_nested_attributes_for 来为您定义写入器方法。
class Person < ActiveRecord::Base has_one :address accepts_nested_attributes_for :address end
如果您想通过表单销毁关联的模型,您必须首先使用 accepts_nested_attributes_for 的 :allow_destroy 选项来启用它。
class Person < ActiveRecord::Base has_one :address accepts_nested_attributes_for :address, allow_destroy: true end
现在,当您使用带有 _destroy 参数的表单元素,并且其值评估为 true 时,您将销毁关联的模型(例如 1、'1'、true 或 'true')。
<%= form_with model: @person do |person_form| %>
...
<%= person_form.fields_for :address do |address_fields| %>
...
Delete: <%= address_fields.checkbox :_destroy %>
<% end %>
...
<% end %>
一对多¶ ↑
考虑一个 Person 类,它从 projects 读取器方法返回一个 *项目* 实例数组,并响应 projects_attributes= 写入器方法。
class Person def projects [@project1, @project2] end def projects_attributes=(attributes) # Process the attributes hash end end
请注意,实际上需要 projects_attributes= 写入器方法才能使 fields_for 正确识别 :projects 作为集合,并设置表单标记中的正确索引。
当 projects 已经是 Person 的关联时,您可以使用 accepts_nested_attributes_for 来为您定义写入器方法。
class Person < ActiveRecord::Base has_many :projects accepts_nested_attributes_for :projects end
现在可以使用嵌套的 fields_for 来使用此模型。传递给嵌套的 fields_for 调用的块将为集合中的每个实例重复。
<%= form_with model: @person do |person_form| %>
...
<%= person_form.fields_for :projects do |project_fields| %>
<% if project_fields.object.active? %>
Name: <%= project_fields.text_field :name %>
<% end %>
<% end %>
...
<% end %>
也可以指定要使用的实例。
<%= form_with model: @person do |person_form| %>
...
<% @person.projects.each do |project| %>
<% if project.active? %>
<%= person_form.fields_for :projects, project do |project_fields| %>
Name: <%= project_fields.text_field :name %>
<% end %>
<% end %>
<% end %>
...
<% end %>
或者要使用的集合。
<%= form_with model: @person do |person_form| %>
...
<%= person_form.fields_for :projects, @active_projects do |project_fields| %>
Name: <%= project_fields.text_field :name %>
<% end %>
...
<% end %>
如果您想通过表单销毁任何关联的模型,您必须首先使用 accepts_nested_attributes_for 的 :allow_destroy 选项来启用它。
class Person < ActiveRecord::Base has_many :projects accepts_nested_attributes_for :projects, allow_destroy: true end
这将允许您通过添加一个带有值评估为 true(例如 1、'1'、true 或 'true')的 _destroy 参数的表单元素来指定要销毁的模型。
<%= form_with model: @person do |person_form| %>
...
<%= person_form.fields_for :projects do |project_fields| %>
Delete: <%= project_fields.checkbox :_destroy %>
<% end %>
...
<% end %>
当使用集合时,您可能想知道数组中每个对象的索引。为此,FormBuilder 对象中提供了 index 方法。
<%= form_with model: @person do |person_form| %>
...
<%= person_form.fields_for :projects do |project_fields| %>
Project #<%= project_fields.index %>
...
<% end %>
...
<% end %>
注意,如果记录响应 persisted?,fields_for 将自动生成一个隐藏字段来存储记录的 ID。在某些情况下,此隐藏字段并非必需,您可以传递 include_id: false 以阻止 fields_for 自动渲染它。
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1028 def fields_for(record_name, record_object = nil, options = {}, &block) options = { model: record_object, allow_method_names_outside_object: false, skip_default_ids: false }.merge!(options) fields(record_name, **options, &block) end
file_field(object_name, method, options = {}) Link
返回一个文件上传输入标签,该标签经过定制,用于访问模板中指定对象(由 object 标识)的指定属性(由 method 标识)。可以通过一个包含 options 的哈希来传递输入标签的其他选项。这些选项将像示例所示那样作为 HTML 元素属性添加到 HTML 中。
在 form_with 块内使用此方法会将封闭表单的编码设置为 multipart/form-data。
选项¶ ↑
-
为标签创建标准的 HTML 属性。
-
:disabled- 如果设置为 true,用户将无法使用此输入。 -
:multiple- 如果设置为 true,*在大多数更新的浏览器中*,用户将被允许选择多个文件。 -
:include_hidden- 当multiple: true和include_hidden: true时,该字段将以一个值为<input type="hidden">的隐藏字段作为前缀,以支持提交空文件集合。 -
:accept- 如果设置为一个或多个 MIME 类型,当用户选择文件时,将建议一个过滤器。你仍然需要设置模型验证。
示例¶ ↑
file_field(:user, :avatar) # => <input type="file" id="user_avatar" name="user[avatar]" /> file_field(:article, :image, multiple: true) # => <input type="file" id="article_image" name="article[image][]" multiple="multiple" /> file_field(:article, :attached, accept: 'text/html') # => <input accept="text/html" type="file" id="article_attached" name="article[attached]" /> file_field(:article, :image, accept: 'image/png,image/gif,image/jpeg') # => <input type="file" id="article_image" name="article[image]" accept="image/png,image/gif,image/jpeg" /> file_field(:attachment, :file, class: 'file_input') # => <input type="file" id="attachment_file" name="attachment[file]" class="file_input" />
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1247 def file_field(object_name, method, options = {}) options = { include_hidden: multiple_file_field_include_hidden }.merge!(options) Tags::FileField.new(object_name, method, self, convert_direct_upload_option_to_url(options.dup)).render end
form_for(record, options = {}, &block) Link
创建一个表单,允许用户创建或更新特定模型对象的属性。
根据您希望 Rails 从模型中自动推断表单构建方式的程度,该方法可以以几种略有不同的方式使用。对于通用模型对象,可以通过将 form_for 传递一个字符串或符号来表示我们关注的对象来创建表单。
<%= form_for :person do |f| %> First name: <%= f.text_field :first_name %><br /> Last name : <%= f.text_field :last_name %><br /> Biography : <%= f.textarea :biography %><br /> Admin? : <%= f.checkbox :admin %><br /> <%= f.submit %> <% end %>
传递给块的变量 f 是一个 FormBuilder 对象,该对象结合了传递给 form_for 的 :person 所代表的模型对象的知识。在 FormBuilder 上定义的方法用于生成绑定到此模型的字段。因此,例如,
<%= f.text_field :first_name %>
将被展开为
<%= text_field :person, :first_name %>
这将生成一个 <input> 标签,其 name 属性为 person[first_name]。这意味着当表单提交时,用户输入的值将在控制器中以 params[:person][:first_name] 的形式可用。
对于使用 FormBuilder 以这种方式生成的字段,如果 :person 也恰好是实例变量 @person 的名称,那么当表单首次显示时(例如,在编辑现有记录的情况下),字段的默认值将是 @person 相应属性的值。
form_for 的最右边参数是可选的选项哈希——
-
:url- 表单要提交到的 URL。可以与传递给 url_for 或link_to的值以相同方式表示。例如,您可以使用命名路由。当模型由字符串或符号表示时,如上面的示例所示,如果未指定:url选项,则默认情况下表单将提交回当前 URL(下面我们将描述一种form_for的替代资源导向用法,其中无需显式指定 URL)。 -
:namespace- 为您的表单提供一个命名空间,以确保表单元素 ID 属性的唯一性。命名空间属性将在生成的 HTML ID 中以带下划线的前缀形式出现。 -
:method- 提交表单时使用的方法,通常是“get”或“post”。如果使用“patch”、“put”、“delete”或其他动词,则会添加一个名为_method的隐藏输入来模拟 POST 上的动词。 -
:authenticity_token- 在表单中使用的真实性令牌。仅在需要传递自定义真实性令牌字符串时使用,或完全不添加 authenticity_token 字段(通过传递false)。远程表单可以通过设置config.action_view.embed_authenticity_token_in_remote_forms = false来省略嵌入的真实性令牌。这在对表单进行片段缓存时很有用。远程表单从meta标签获取真实性令牌,因此除非支持没有 JavaScript 的浏览器,否则嵌入是不必要的。 -
:remote- 如果设置为 true,将允许不显眼的 JavaScript 驱动程序控制提交行为。 -
:enforce_utf8- 如果设置为 false,则不会输出名为 utf8 的隐藏输入。 -
:html- 表单标签的可选 HTML 属性。
另请注意,form_for 不创建独占作用域。仍然可以使用独立的 FormHelper 方法和 FormTagHelper 中的方法。例如:
<%= form_for :person do |f| %> First name: <%= f.text_field :first_name %> Last name : <%= f.text_field :last_name %> Biography : <%= textarea :person, :biography %> Admin? : <%= checkbox_tag "person[admin]", "1", @person.company.admin? %> <%= f.submit %> <% end %>
这同样适用于 FormOptionsHelper 和 DateHelper 中设计用于以对象为基础的方法,例如 FormOptionsHelper#collection_select 和 DateHelper#datetime_select。
form_for 与模型对象¶ ↑
在上面的示例中,要创建或编辑的对象由传递给 form_for 的符号表示,我们注意到也可以使用字符串。然而,也可以将模型对象本身传递给 form_for。例如,如果 @article 是您要编辑的现有记录,您可以这样创建表单:
<%= form_for @article do |f| %> ... <% end %>
这几乎与前面概述的相同,但有几个小例外。首先,用于命名表单中输入元素的名称前缀(因此是在 params 哈希中表示它们的键)实际上是从对象的 *类* 派生的,例如,如果对象的类是 Article,则为 params[:article]。但是,这可以通过 :as 选项覆盖,例如——
<%= form_for(@person, as: :client) do |f| %> ... <% end %>
将生成 params[:client]。
其次,当表单首次显示时显示的字段值将从传递给 form_for 的对象的属性中获取,而不管该对象是否是实例变量。因此,例如,如果我们有一个代表现有记录的 *局部* 变量 article,
<%= form_for article do |f| %> ... <% end %>
将生成一个表单,其字段的初始状态反映 article 属性的当前值。
资源导向风格¶ ↑
在上面显示的示例中,尽管没有明确指出,我们仍然需要使用 :url 选项来指定表单的发送目的地。然而,如果传递给 form_for 的记录是 *资源*,即它对应于一组 RESTful 路由,例如使用 config/routes.rb 中的 resources 方法定义的,则可以进一步简化。在这种情况下,Rails 将简单地从记录本身推断出适当的 URL。例如,
<%= form_for @article do |f| %> ... <% end %>
然后等同于
<%= form_for @article, as: :article, url: article_path(@article), method: :patch, html: { class: "edit_article", id: "edit_article_45" } do |f| %>
...
<% end %>
对于新记录:
<%= form_for(Article.new) do |f| %> ... <% end %>
等同于
<%= form_for @article, as: :article, url: articles_path, html: { class: "new_article", id: "new_article" } do |f| %>
...
<% end %>
但是,您仍然可以覆盖单独的约定,例如:
<%= form_for(@article, url: super_articles_path) do |f| %> ... <% end %>
您可以通过传递 url: false 来省略 action 属性。
<%= form_for(@article, url: false) do |f| %> ... <% end %>
您还可以设置响应格式,如下所示:
<%= form_for(@article, format: :json) do |f| %> ... <% end %>
对于命名空间路由,例如 admin_article_url:
<%= form_for([:admin, @article]) do |f| %> ... <% end %>
如果您的资源定义了关联,例如,您想为给定的文档添加评论,并且路由设置正确:
<%= form_for([@document, @comment]) do |f| %> ... <% end %>
其中 @document = Document.find(params[:id]) 和 @comment = Comment.new。
设置方法¶ ↑
您可以通过设置来强制表单使用完整的 HTTP 动词集:
method: (:get|:post|:patch|:put|:delete)
在选项哈希中。如果动词不是 GET 或 POST(HTML 表单原生支持),则表单将设置为 POST,并且一个名为 _method 的隐藏输入将携带预期的动词供服务器解释。
不显眼的 JavaScript¶ ↑
指定
remote: true
在选项哈希中,会创建一个允许不显眼的 JavaScript 驱动程序修改其行为的表单。表单提交将像接收方看到的常规提交一样工作(所有元素都可以在 params 中访问)。
示例
<%= form_for(@article, remote: true) do |f| %> ... <% end %>
这将生成的 HTML 是
<form action='http://www.example.com' method='post' data-remote='true'> <input name='_method' type='hidden' value='patch' /> ... </form>
设置 HTML 选项¶ ↑
您可以直接通过传递数据哈希来设置数据属性,但其他所有 HTML 选项都必须包含在 HTML 键中。例如:
<%= form_for(@article, data: { behavior: "autosave" }, html: { name: "go" }) do |f| %>
...
<% end %>
这将生成的 HTML 是
<form action='http://www.example.com' method='post' data-behavior='autosave' name='go'> <input name='_method' type='hidden' value='patch' /> ... </form>
删除隐藏的模型 ID¶ ↑
form_for 方法会自动将模型 ID 作为隐藏字段包含在表单中。这用于维护表单数据与其关联模型之间的相关性。某些 ORM 系统不对嵌套模型使用 ID,因此在这种情况下,您需要能够禁用隐藏 ID。
在以下示例中,Article 模型在 NoSQL 数据库中存储了许多 Comments,因此 Comments 没有主键。
示例
<%= form_for(@article) do |f| %>
<%= f.fields_for(:comments, include_id: false) do |cf| %>
...
<% end %>
<% end %>
自定义表单构建器¶ ↑
您也可以使用自定义的 FormBuilder 类来构建表单。子类化 FormBuilder 并覆盖或定义更多助手,然后使用您的自定义构建器。例如,假设您创建了一个自动为表单输入添加标签的助手。
<%= form_for @person, url: { action: "create" }, builder: LabellingFormBuilder do |f| %>
<%= f.text_field :first_name %>
<%= f.text_field :last_name %>
<%= f.textarea :biography %>
<%= f.checkbox :admin %>
<%= f.submit %>
<% end %>
在这种情况下,如果您使用此
<%= render f %>
渲染的模板是 people/_labelling_form,并且引用表单构建器的局部变量名为 labelling_form。
自定义 FormBuilder 类会自动与嵌套的 fields_for 调用的选项合并,除非显式设置。
在许多情况下,您会希望将上述内容包装在另一个助手函数中,这样您就可以这样做:
def labelled_form_for(record_or_name_or_array, *args, &block) options = args.extract_options! form_for(record_or_name_or_array, *(args << options.merge(builder: LabellingFormBuilder)), &block) end
如果您不需要将表单附加到模型实例,请查看 FormTagHelper#form_tag。
表单提交到外部资源¶ ↑
当您构建提交到外部资源的表单时,有时需要设置一个真实性令牌,或者只是渲染一个没有它的表单,例如当您提交数据到支付网关时,字段的数量和类型可能会受到限制。
要设置真实性令牌,您需要传递一个 :authenticity_token 参数。
<%= form_for @invoice, url: external_url, authenticity_token: 'external_token' do |f| %> ... <% end %>
如果您不想渲染真实性令牌字段,只需传递 false。
<%= form_for @invoice, url: external_url, authenticity_token: false do |f| %> ... <% end %>
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 435 def form_for(record, options = {}, &block) raise ArgumentError, "Missing block" unless block_given? case record when String, Symbol model = false object_name = record else model = record object = _object_for_form_builder(record) raise ArgumentError, "First argument in form cannot contain nil or be empty" unless object object_name = options[:as] || model_name_from_record_or_class(object).param_key apply_form_for_options!(object, options) end remote = options.delete(:remote) if remote && !embed_authenticity_token_in_remote_forms && options[:authenticity_token].blank? options[:authenticity_token] = false end options[:model] = model options[:scope] = object_name options[:local] = !remote options[:skip_default_ids] = false options[:allow_method_names_outside_object] = options.fetch(:allow_method_names_outside_object, false) form_with(**options, &block) end
form_with(model: false, scope: nil, url: nil, format: nil, **options, &block) Link
创建一个基于混合 URL、作用域或模型的表单标签。
# Using just a URL: <%= form_with url: articles_path do |form| %> <%= form.text_field :title %> <% end %> # => <form action="/articles" method="post"> <input type="text" name="title" /> </form> # With an intentionally empty URL: <%= form_with url: false do |form| %> <%= form.text_field :title %> <% end %> # => <form method="post"> <input type="text" name="title" /> </form> # Adding a scope prefixes the input field names: <%= form_with scope: :article, url: articles_path do |form| %> <%= form.text_field :title %> <% end %> # => <form action="/articles" method="post"> <input type="text" name="article[title]" /> </form> # Using a model infers both the URL and scope: <%= form_with model: Article.new do |form| %> <%= form.text_field :title %> <% end %> # => <form action="/articles" method="post"> <input type="text" name="article[title]" /> </form> # An existing model makes an update form and fills out field values: <%= form_with model: Article.first do |form| %> <%= form.text_field :title %> <% end %> # => <form action="/articles/1" method="post"> <input type="hidden" name="_method" value="patch" /> <input type="text" name="article[title]" value="<the title of the article>" /> </form> # Though the fields don't have to correspond to model attributes: <%= form_with model: Cat.new do |form| %> <%= form.text_field :cats_dont_have_gills %> <%= form.text_field :but_in_forms_they_can %> <% end %> # => <form action="/cats" method="post"> <input type="text" name="cat[cats_dont_have_gills]" /> <input type="text" name="cat[but_in_forms_they_can]" /> </form>
表单中的参数在控制器中根据它们的命名嵌套进行访问。因此,名为 title 和 article[title] 的输入分别可以访问为 params[:title] 和 params[:article][:title]。
为了方便比较,上面的示例省略了提交按钮,以及自动生成的隐藏字段,这些字段启用了 UTF-8 支持并添加了跨站请求伪造保护所需的真实性令牌。
资源导向风格¶ ↑
在上面显示的许多示例中,传递给 form_with 的 :model 是一个 *资源*。它对应于一组 RESTful 路由,最有可能通过 config/routes.rb 中的 resources 定义。
因此,在传递此类模型记录时,Rails 会推断出 URL 和方法。
<%= form_with model: @article do |form| %> ... <% end %>
然后等同于
<%= form_with scope: :article, url: article_path(@article), method: :patch do |form| %> ... <% end %>
对于新记录:
<%= form_with model: Article.new do |form| %> ... <% end %>
等同于
<%= form_with scope: :article, url: articles_path do |form| %> ... <% end %>
form_with 选项¶ ↑
-
:url- 表单提交到的 URL。类似于传递给 url_for 或link_to的值。例如,您可以使用命名路由。当传递:scope而没有:url时,表单将只提交到当前 URL。 -
:method- 提交表单时使用的方法,通常是“get”或“post”。如果使用“patch”、“put”、“delete”或其他动词,则会添加一个名为_method的隐藏输入来模拟 POST 上的动词。 -
:format- 表单提交到的路由的格式。当提交到另一种资源类型(如:json)时很有用。如果传递了:url,则会被忽略。 -
:scope- 用于为输入字段名称添加前缀的作用域,从而决定提交的参数如何在控制器中分组。 -
:namespace- 为您的表单提供一个命名空间,以确保表单元素 ID 属性的唯一性。命名空间属性将在生成的 HTML ID 中以带下划线的前缀形式出现。 -
:model- 一个模型对象,用于推断:url和:scope,以及填充输入字段的值。因此,如果一个title属性设置为“Ahoy!”,那么title输入字段的值将是“Ahoy!”。如果模型是一个新记录,则会生成一个创建表单;如果是一个现有记录,则会生成一个更新表单。传递:scope或:url来覆盖默认值。例如,将params[:article]变为params[:blog]。 -
:authenticity_token- 在表单中使用的真实性令牌。使用自定义真实性令牌进行覆盖,或传递false以完全跳过真实性令牌字段。当提交到外部资源(如支付网关)时很有用,该网关可能限制有效字段。远程表单可以通过设置config.action_view.embed_authenticity_token_in_remote_forms = false来省略嵌入的真实性令牌。这在对表单进行片段缓存时很有用。远程表单从meta标签获取真实性令牌,因此除非支持没有 JavaScript 的浏览器,否则嵌入是不必要的。 -
:local- 是否使用标准的 HTTP 表单提交。当设置为true时,表单通过标准 HTTP 提交。当设置为false时,表单作为“远程表单”提交,由 Rails UJS 作为 XHR 进行处理。如果未指定,则行为源自config.action_view.form_with_generates_remote_forms,其中配置的值实际上与local的值相反。从 Rails 6.1 开始,该配置选项默认为false(效果等同于传递local: true)。在之前的 Rails 版本中,该配置选项默认为true(等同于传递local: false)。 -
:skip_enforcing_utf8- 如果设置为 true,则不会输出名为 utf8 的隐藏输入。 -
:builder- 覆盖用于构建表单的对象。 -
:id- 可选的 HTML id 属性。 -
:class- 可选的 HTML class 属性。 -
:data- 可选的 HTML data 属性。 -
:html- 表单标签的其他可选 HTML 属性。
示例¶ ↑
当不传递块时,form_with 只会生成一个打开的表单标签。
<%= form_with(model: @article, url: super_articles_path) %> <%= form_with(model: @article, scope: :blog) %> <%= form_with(model: @article, format: :json) %> <%= form_with(model: @article, authenticity_token: false) %> # Disables the token.
对于命名空间路由,例如 admin_article_url:
<%= form_with(model: [ :admin, @article ]) do |form| %> ... <% end %>
如果您的资源定义了关联,例如,您想为给定的文档添加评论,并且路由设置正确:
<%= form_with(model: [ @document, Comment.new ]) do |form| %> ... <% end %>
其中 @document = Document.find(params[:id])。
与其他表单助手的混合使用¶ ↑
虽然 form_with 使用 FormBuilder 对象,但也可以混合使用独立的 FormHelper 方法和 FormTagHelper 中的方法。
<%= form_with scope: :person do |form| %> <%= form.text_field :first_name %> <%= form.text_field :last_name %> <%= textarea :person, :biography %> <%= checkbox_tag "person[admin]", "1", @person.company.admin? %> <%= form.submit %> <% end %>
对于 FormOptionsHelper 和 DateHelper 中设计用于以对象为基础的方法,例如 FormOptionsHelper#collection_select 和 DateHelper#datetime_select,也是如此。
设置方法¶ ↑
您可以通过设置来强制表单使用完整的 HTTP 动词集:
method: (:get|:post|:patch|:put|:delete)
在选项哈希中。如果动词不是 GET 或 POST(HTML 表单原生支持),则表单将设置为 POST,并且一个名为 _method 的隐藏输入将携带预期的动词供服务器解释。
设置 HTML 选项¶ ↑
您可以直接在 data 哈希中设置数据属性,但 id 和 class 之外的其他 HTML 选项必须包含在 html 键中。
<%= form_with(model: @article, data: { behavior: "autosave" }, html: { name: "go" }) do |form| %>
...
<% end %>
生成
<form action="/articles/123" method="post" data-behavior="autosave" name="go"> <input name="_method" type="hidden" value="patch" /> ... </form>
删除隐藏的模型 ID¶ ↑
form_with 方法会自动将模型 ID 作为隐藏字段包含在表单中。这用于维护表单数据与其关联模型之间的相关性。某些 ORM 系统不对嵌套模型使用 ID,因此在这种情况下,您需要能够禁用隐藏 ID。
在以下示例中,Article 模型在 NoSQL 数据库中存储了许多 Comments,因此 Comments 没有主键。
<%= form_with(model: @article) do |form| %>
<%= form.fields(:comments, skip_id: true) do |fields| %>
...
<% end %>
<% end %>
自定义表单构建器¶ ↑
您也可以使用自定义的 FormBuilder 类来构建表单。子类化 FormBuilder 并覆盖或定义更多助手,然后使用您的自定义构建器。例如,假设您创建了一个自动为表单输入添加标签的助手。
<%= form_with model: @person, url: { action: "create" }, builder: LabellingFormBuilder do |form| %>
<%= form.text_field :first_name %>
<%= form.text_field :last_name %>
<%= form.textarea :biography %>
<%= form.checkbox :admin %>
<%= form.submit %>
<% end %>
在这种情况下,如果您使用:
<%= render form %>
渲染的模板是 people/_labelling_form,并且引用表单构建器的局部变量名为 labelling_form。
自定义 FormBuilder 类会自动与嵌套的 fields 调用的选项合并,除非显式设置。
在许多情况下,您会希望将上述内容包装在另一个助手函数中,这样您就可以这样做:
def labelled_form_with(**options, &block) form_with(**options.merge(builder: LabellingFormBuilder), &block) end
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 755 def form_with(model: false, scope: nil, url: nil, format: nil, **options, &block) raise ArgumentError, "Passed nil to the :model argument, expect an object or false" if model.nil? options = { allow_method_names_outside_object: true, skip_default_ids: !form_with_generates_ids }.merge!(options) if model if url != false url ||= if format.nil? polymorphic_path(model, {}) else polymorphic_path(model, format: format) end end model = convert_to_model(_object_for_form_builder(model)) scope ||= model_name_from_record_or_class(model).param_key end if block_given? builder = instantiate_builder(scope, model, options) output = capture(builder, &block) options[:multipart] ||= builder.multipart? html_options = html_options_for_form_with(url, model, **options) form_tag_with_body(html_options, output) else html_options = html_options_for_form_with(url, model, **options) form_tag_html(html_options) end end
hidden_field(object_name, method, options = {}) Link
返回一个隐藏输入标签,该标签经过定制,用于访问模板中指定对象(由 object 标识)的指定属性(由 method 标识)。可以通过一个包含 options 的哈希来传递输入标签的其他选项。这些选项将像示例所示那样作为 HTML 元素属性添加到 HTML 中。
示例¶ ↑
hidden_field(:signup, :pass_confirm) # => <input type="hidden" id="signup_pass_confirm" name="signup[pass_confirm]" value="#{@signup.pass_confirm}" /> hidden_field(:article, :tag_list) # => <input type="hidden" id="article_tag_list" name="article[tag_list]" value="#{@article.tag_list}" /> hidden_field(:user, :token) # => <input type="hidden" id="user_token" name="user[token]" value="#{@user.token}" />
来源: | 在 GitHub 上
label(object_name, method, content_or_options = nil, options = nil, &block) Link
返回一个标签标签,该标签经过定制,用于为模板中指定对象(由 object 标识)的指定属性(由 method 标识)创建一个输入字段的标签。标签的文本默认为属性名,除非在当前 I18n 区域设置中找到翻译(通过 helpers.label.<modelname>.<attribute>),或者您显式指定了它。可以通过一个包含 options 的哈希来传递标签的其他选项。这些选项将像示例所示那样作为 HTML 元素属性添加到 HTML 中,但 :value 选项除外,该选项旨在定位 radio_button 标签的标签(其中 value 用于输入标签的 ID)。
示例¶ ↑
label(:article, :title) # => <label for="article_title">Title</label>
您可以根据模型和属性名称本地化您的标签。例如,您可以在您的区域设置(例如 en.yml)中定义以下内容:
helpers:
label:
article:
body: "Write your entire text here"
这将导致:
label(:article, :body) # => <label for="article_body">Write your entire text here</label>
本地化也可以纯粹基于属性名称的翻译(如果您使用的是 ActiveRecord)。
activerecord:
attributes:
article:
cost: "Total cost"
label(:article, :cost) # => <label for="article_cost">Total cost</label> label(:article, :title, "A short title") # => <label for="article_title">A short title</label> label(:article, :title, "A short title", class: "title_label") # => <label for="article_title" class="title_label">A short title</label> label(:article, :privacy, "Public Article", value: "public") # => <label for="article_privacy_public">Public Article</label> label(:article, :cost) do |translation| content_tag(:span, translation, class: "cost_label") end # => <label for="article_cost"><span class="cost_label">Total cost</span></label> label(:article, :cost) do |builder| content_tag(:span, builder.translation, class: "cost_label") end # => <label for="article_cost"><span class="cost_label">Total cost</span></label> label(:article, :terms) do raw('Accept <a href="/terms">Terms</a>.') end # => <label for="article_terms">Accept <a href="/terms">Terms</a>.</label>
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1151 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
month_field(object_name, method, options = {}) Link
返回类型为“month”的 text_field。
month_field("user", "born_on") # => <input id="user_born_on" name="user[born_on]" type="month" />
默认值是通过尝试对对象的 strftime 调用 “%Y-%m” 生成的,这使得它对于 DateTime 和 ActiveSupport::TimeWithZone 的实例来说表现符合预期。
@user.born_on = Date.new(1984, 1, 27) month_field("user", "born_on") # => <input id="user_born_on" name="user[born_on]" type="date" value="1984-01" />
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1533 def month_field(object_name, method, options = {}) Tags::MonthField.new(object_name, method, self, options).render end
number_field(object_name, method, options = {}) Link
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1577 def number_field(object_name, method, options = {}) Tags::NumberField.new(object_name, method, self, options).render end
password_field(object_name, method, options = {}) Link
返回一个“password”类型的输入标签,该标签经过定制,用于访问模板中指定对象(由 object 标识)的指定属性(由 method 标识)。可以通过一个包含 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" />
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1196 def password_field(object_name, method, options = {}) Tags::PasswordField.new(object_name, method, self, options).render end
radio_button(object_name, method, tag_value, options = {}) Link
返回一个单选按钮标签,用于访问模板中指定对象(由 object 标识)的指定属性(由 method 标识)。如果 method 的当前值为 tag_value,则单选按钮将被选中。
要强制单选按钮被选中,请在 options 哈希中传递 checked: true。您也可以在此处传递 HTML 选项。
# Let's say that @article.category returns "rails": radio_button("article", "category", "rails") radio_button("article", "category", "java") # => <input type="radio" id="article_category_rails" name="article[category]" value="rails" checked="checked" /> # <input type="radio" id="article_category_java" name="article[category]" value="java" /> # Let's say that @user.receive_newsletter returns "no": radio_button("user", "receive_newsletter", "yes") radio_button("user", "receive_newsletter", "no") # => <input type="radio" id="user_receive_newsletter_yes" name="user[receive_newsletter]" value="yes" /> # <input type="radio" id="user_receive_newsletter_no" name="user[receive_newsletter]" value="no" checked="checked" />
来源: 显示 | 在 GitHub 上
range_field(object_name, method, options = {}) Link
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1586 def range_field(object_name, method, options = {}) Tags::RangeField.new(object_name, method, self, options).render end
rich_textarea(object_name, method, options = {}, &block) Link
返回一个 trix-editor 标签,该标签实例化 Trix JavaScript 编辑器以及一个 Trix 在更改时会写入的隐藏字段,以便内容将在表单提交时发送。
选项¶ ↑
-
:class- 默认为“trix-content”,这确保应用了默认样式。 -
:value- 为 HTML 输入标签添加默认值。 -
[:data][:direct_upload_url]- 默认为rails_direct_uploads_url。 -
[:data][:blob_url_template]- 默认为rails_service_blob_url(":signed_id", ":filename")。
示例¶ ↑
rich_textarea :message, :content # <input type="hidden" name="message[content]" id="message_content_trix_input_message_1"> # <trix-editor id="content" input="message_content_trix_input_message_1" class="trix-content" ...></trix-editor> rich_textarea :message, :content, value: "<h1>Default message</h1>" # <input type="hidden" name="message[content]" id="message_content_trix_input_message_1" value="<h1>Default message</h1>"> # <trix-editor id="content" input="message_content_trix_input_message_1" class="trix-content" ...></trix-editor> rich_textarea :message, :content do "<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>
来源: 显示 | 在 GitHub 上
# File actiontext/app/helpers/action_text/tag_helper.rb, line 100 def rich_textarea(object_name, method, options = {}, &block) Tags::ActionText.new(object_name, method, self, options).render(&block) end
search_field(object_name, method, options = {}) Link
返回一个“search”类型的输入,用于访问模板中指定对象(由 object_name 标识)的指定属性(由 method 标识)。“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" />
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1400 def search_field(object_name, method, options = {}) Tags::SearchField.new(object_name, method, self, options).render end
telephone_field(object_name, method, options = {}) Link
返回类型为“tel”的 text_field。
telephone_field("user", "phone") # => <input id="user_phone" name="user[phone]" type="tel" />
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1409 def telephone_field(object_name, method, options = {}) Tags::TelField.new(object_name, method, self, options).render end
text_field(object_name, method, options = {}) Link
返回一个“text”类型的输入标签,该标签经过定制,用于访问模板中指定对象(由 object 标识)的指定属性(由 method 标识)。可以通过一个包含 options 的哈希来传递输入标签的其他选项。这些选项将像示例所示那样作为 HTML 元素属性添加到 HTML 中。
示例¶ ↑
text_field(:article, :title, size: 20) # => <input type="text" id="article_title" name="article[title]" size="20" value="#{@article.title}" /> text_field(:article, :title, class: "create_input") # => <input type="text" id="article_title" name="article[title]" value="#{@article.title}" class="create_input" /> text_field(:article, :title, maxlength: 30, class: "title_input") # => <input type="text" id="article_title" name="article[title]" maxlength="30" size="30" value="#{@article.title}" class="title_input" /> text_field(:session, :user, onchange: "if ($('#session_user').val() === 'admin') { alert('Your login cannot be admin!'); }") # => <input type="text" id="session_user" name="session[user]" value="#{@session.user}" onchange="if ($('#session_user').val() === 'admin') { alert('Your login cannot be admin!'); }"/> text_field(:snippet, :code, size: 20, class: 'code_input') # => <input type="text" id="snippet_code" name="snippet[code]" size="20" value="#{@snippet.code}" class="code_input" />
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1175 def text_field(object_name, method, options = {}) Tags::TextField.new(object_name, method, self, options).render end
textarea(object_name, method, options = {}) Link
返回一个文本区域的打开和关闭标签集,该标签集经过定制,用于访问模板中指定对象(由 object 标识)的指定属性(由 method 标识)。可以通过一个包含 options 的哈希来传递输入标签的其他选项。
示例¶ ↑
textarea(:article, :body, cols: 20, rows: 40) # => <textarea cols="20" rows="40" id="article_body" name="article[body]"> # #{@article.body} # </textarea> textarea(:comment, :text, size: "20x30") # => <textarea cols="20" rows="30" id="comment_text" name="comment[text]"> # #{@comment.text} # </textarea> textarea(:application, :notes, cols: 40, rows: 15, class: 'app_input') # => <textarea cols="40" rows="15" id="application_notes" name="application[notes]" class="app_input"> # #{@application.notes} # </textarea> textarea(:entry, :body, size: "20x20", disabled: 'disabled') # => <textarea cols="20" rows="20" id="entry_body" name="entry[body]" disabled="disabled"> # #{@entry.body} # </textarea>
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1277 def textarea(object_name, method, options = {}) Tags::TextArea.new(object_name, method, self, options).render end
time_field(object_name, method, options = {}) Link
返回类型为“time”的 text_field。
默认值是通过尝试对对象的 strftime 调用 “%T.%L” 生成的。如果传递 include_seconds: false,它将通过尝试对对象的 strftime 调用 “%H:%M” 来格式化。也可以通过传递 “value” 选项来覆盖此设置。
选项¶ ↑
支持与 FormTagHelper#time_field_tag 相同的选项。
示例¶ ↑
time_field("task", "started_at") # => <input id="task_started_at" name="task[started_at]" type="time" />
您可以通过将 Date 或 Time 的实例传递给选项哈希来创建“min”和“max”属性的值。
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 时间的 String 作为“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" />
默认情况下,提供的日期时间将包含秒。通过传递 include_seconds: false,可以只渲染小时和分钟。如果从时间戳格式中省略秒,某些浏览器将呈现更简单的 UI。
time_field("task", "started_at", value: Time.now, include_seconds: false) # => <input id="task_started_at" name="task[started_at]" type="time" value="01:00" />
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1479 def time_field(object_name, method, options = {}) Tags::TimeField.new(object_name, method, self, options).render end
url_field(object_name, method, options = {}) Link
返回类型为“url”的 text_field。
url_field("user", "homepage") # => <input id="user_homepage" name="user[homepage]" type="url" />
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1559 def url_field(object_name, method, options = {}) Tags::UrlField.new(object_name, method, self, options).render end
week_field(object_name, method, options = {}) Link
返回类型为“week”的 text_field。
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" />
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1550 def week_field(object_name, method, options = {}) Tags::WeekField.new(object_name, method, self, options).render end