Action View 表單輔助工具
與使用純 HTML 相比,表單輔助工具旨在讓使用資源變得更容易。
通常,用於建立或更新資源的表單會以多種方式反映資源的身分:(i) 表單送出的網址(表單元素的 action
屬性)應導致將要求路由到適當的控制器動作(在現有資源的情況下,使用適當的 :id
參數),(ii) 輸入欄位應以這樣的方式命名,讓控制器中的值出現在 params
hash 中的適當位置,以及 (iii) 對於現有記錄,當表單最初顯示時,對應於資源屬性的輸入欄位應顯示這些屬性的目前值。
在 Rails 中,這通常是透過使用 form_for
和許多相關輔助方法來建立表單來達成。form_for
會產生適當的 form
標籤,並產生一個表單建立器物件,該物件知道表單的模型。透過呼叫表單建立器上定義的方法來建立輸入欄位,這表示它們能夠產生對應於模型屬性的適當名稱和預設值,以及方便的 ID 等。產生欄位名稱中的慣例允許控制器在 params
中接收結構良好的表單資料,而您無需費力。
例如,若要建立新的人員,您通常會在 PeopleController#new
動作中設定 Person
的新執行個體 @person
,並在檢視範本中將該物件傳遞給 form_for
<%= form_for @person do |f| %>
<%= f.label :first_name %>:
<%= f.text_field :first_name %><br />
<%= f.label :last_name %>:
<%= f.text_field :last_name %><br />
<%= f.submit %>
<% end %>
為此產生的 HTML 會是(模數格式)
<form action="/people" class="new_person" id="new_person" method="post">
<input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" />
<label for="person_first_name">First name</label>:
<input id="person_first_name" name="person[first_name]" type="text" /><br />
<label for="person_last_name">Last name</label>:
<input id="person_last_name" name="person[last_name]" type="text" /><br />
<input name="commit" type="submit" value="Create Person" />
</form>
正如您所見,HTML 在多個地方反映了關於資源的知識,例如表單應提交到的路徑,或輸入欄位的名稱。
特別是,由於遵循已產生欄位名稱的慣例,控制器會取得一個嵌套雜湊 params[:person]
,其中包含表單中設定的個人屬性。該雜湊已準備好傳遞給 Person.new
@person = Person.new(params[:person])
if @person.save
# success
else
# error handling
end
有趣的是,先前範例中完全相同的檢視程式碼可以用於編輯人員。如果 @person
是現有記錄,名稱為「John Smith」,ID 為 256,則上述程式碼會產生
<form action="/people/256" class="edit_person" id="edit_person_256" method="post">
<input name="_method" type="hidden" value="patch" />
<input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" />
<label for="person_first_name">First name</label>:
<input id="person_first_name" name="person[first_name]" type="text" value="John" /><br />
<label for="person_last_name">Last name</label>:
<input id="person_last_name" name="person[last_name]" type="text" value="Smith" /><br />
<input name="commit" type="submit" value="Update Person" />
</form>
請注意,端點、預設值和提交按鈕標籤都針對 @person
量身打造。這會這樣運作,因為相關輔助程式知道資源是新記錄還是不是,並據此產生 HTML。
控制器會在 params[:person]
中再次接收表單資料,已準備好傳遞給 Person#update
if @person.update(params[:person])
# success
else
# error handling
end
這就是您通常處理資源的方式。
- 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") 連結
傳回一個核取方塊標籤,專門用於存取指派給範本 (由 object
識別) 的物件上指定屬性 (由 method
識別)。這個物件必須是執行個體物件 (@object),而不是區域物件。預期 method
會傳回一個整數,如果該整數大於零,則核取方塊會被勾選。輸入標籤上的其他選項可以透過雜湊以 options
傳遞。checked_value
預設為 1,而預設 unchecked_value
設定為 0,這對於布林值來說很方便。
選項
-
可以傳入標籤的任何標準 HTML 屬性,例如
:class
。 -
:checked
-true
或false
強制核取方塊的狀態為勾選或不勾選。 -
:include_hidden
- 如果設為 false,將不會產生以下所述的輔助隱藏欄位。
Gotcha
HTML 規範指出未勾選的核取方塊不會成功,因此網路瀏覽器不會傳送它們。不幸的是,這會引發一個 gotcha:如果 Invoice
模型有一個 paid
旗標,而在編輯已付發票的表單中,使用者取消勾選其核取方塊,則不會傳送 paid
參數。因此,任何像這樣的群組指派慣用語
@invoice.update(params[:invoice])
不會更新旗標。
為了防止這種情況,輔助程式會在每個核取方塊之前產生一個輔助隱藏欄位。隱藏欄位具有相同的名稱,其屬性會模擬未勾選的核取方塊。
這樣,客戶端會只傳送隱藏欄位(表示核取方塊未勾選),或兩個欄位。由於 HTML 規範指出金鑰/值對必須按照它們在表單中出現的順序傳送,而參數萃取會取得查詢字串中任何重複金鑰的最後一個出現,因此這適用於一般表單。
不幸的是,當核取方塊位於陣列式參數中時,這個解決方法不起作用,就像
<%= fields_for "project[invoice_attributes][]", invoice, index: nil do |form| %>
<%= form.check_box :paid %>
...
<% end %>
因為參數名稱重複正是 Rails 用來區分陣列元素的方式。對於每個具有勾選核取方塊的項目,您會取得一個只具有該屬性的額外幽靈項目,指定為「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" />
來源:顯示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1343 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
color_field(object_name, method, options = {}) 連結
傳回類型為「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 1373 def color_field(object_name, method, options = {}) Tags::ColorField.new(object_name, method, self, options).render end
date_field(object_name, method, options = {}) 連結
傳回類型為「date」的 text_field
。
date_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="date" />
預設值是透過嘗試使用「%Y-%m-%d」對物件的值呼叫 strftime
來產生,這會讓它對 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 1437 def date_field(object_name, method, options = {}) Tags::DateField.new(object_name, method, self, options).render end
datetime_field(object_name, method, options = {}) 連結
傳回一個類型為「datetime-local」的 text_field
。
datetime_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="datetime-local" />
預設值是嘗試使用「%Y-%m-%dT%T」對物件的值呼叫 strftime
而產生,這會讓它對 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 1510 def datetime_field(object_name, method, options = {}) Tags::DatetimeLocalField.new(object_name, method, self, options).render end
email_field(object_name, method, options = {}) 連結
傳回一個類型為「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 1564 def email_field(object_name, method, options = {}) Tags::EmailField.new(object_name, method, self, options).render end
fields(scope = nil, model: nil, **options, &block) 連結
使用明確的範圍或模型來設定輸入欄位範圍。就像 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
。
來源:顯示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1077 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) 連結
建立一個範圍,圍繞一個特定模型物件,例如 form_for
,但不會建立表單標籤本身。這使得 fields_for
適合在同一個表單中指定其他模型物件。
儘管 fields_for
的用法和目的與 form_for
類似,但其方法簽章略有不同。與 form_for
一樣,它會對與特定模型物件關聯的 FormBuilder
物件產生一個區塊,並在區塊內允許呼叫建構函式上的方法以產生與模型物件關聯的欄位。欄位可以用兩種方式反映模型物件 - 它們的命名方式(因此提交的值出現在控制器中 params
hash 中的方式)以及當欄位出現的表單第一次顯示時顯示的預設值。為了獨立指定這兩個功能,物件名稱(由符號或字串表示)和物件本身可以分別傳遞給方法 -
<%= 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 %>
在這種情況下,核取方塊欄位將由具有 name
屬性 permission[admin]
的 HTML input
標籤表示,而提交的值將在控制器中顯示為 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
如果你想透過表單銷毀關聯的模型,你必須先使用 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_for @person do |person_form| %>
...
<%= person_form.fields_for :address do |address_fields| %>
...
Delete: <%= address_fields.check_box :_destroy %>
<% end %>
...
<% end %>
一對多
考慮一個 Person 類別,它從 projects
讀取器方法傳回專案實例的陣列,並回應 projects_attributes=
寫入器方法
class Person
def projects
[@project1, @project2]
end
def projects_attributes=(attributes)
# Process the attributes hash
end
end
請注意,fields_for
實際上需要 projects_attributes=
寫入器方法,才能正確地將 :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 %>
如果您想要透過表單摧毀任何關聯的模型,您必須先使用 accepts_nested_attributes_for
的 :allow_destroy
選項來啟用它
class Person < ActiveRecord::Base
has_many :projects
accepts_nested_attributes_for :projects, allow_destroy: true
end
這將允許您透過新增 _destroy
參數的表單元素(其值評估為 true
,例如 1、‘1’、true 或 ‘true’)來指定要在屬性雜湊中摧毀哪些模型
<%= form_for @person do |person_form| %>
...
<%= person_form.fields_for :projects do |project_fields| %>
Delete: <%= project_fields.check_box :_destroy %>
<% end %>
...
<% end %>
當使用集合時,您可能想要知道陣列中每個物件的索引。為此目的,FormBuilder
物件中提供了 index
方法。
<%= form_for @person do |person_form| %>
...
<%= person_form.fields_for :projects do |project_fields| %>
Project #<%= project_fields.index %>
...
<% end %>
...
<% end %>
請注意,fields_for
會自動產生一個隱藏欄位來儲存記錄的 ID,如果它回應 persisted?
。在某些情況下不需要這個隱藏欄位,您可以傳遞 include_id: false
來防止 fields_for
自動呈現它。
來源:顯示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1026 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 = {}) 連結
傳回一個檔案上傳輸入標籤,專門用於存取指定屬性(由 method
識別)在指定給範本的物件上(由 object
識別)。可以將輸入標籤上的其他選項傳遞為雜湊,其中包含 options
。這些選項會標記到 HTML 中,作為 HTML 元素屬性,如下所示範例所示。
在 form_for
區塊內使用此方法會將封裝表單的編碼設定為 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(: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" />
來源:顯示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1245 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) 連結
建立一個表單,使用戶可以建立或更新特定模型物件的屬性。
此方法可以以幾種略有不同的方式使用,這取決於您希望 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
物件,它包含了傳遞給 form_for
的 :person
所表示的模型物件的知識。在 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
- 要在表單中使用的真實性令牌。只有在您需要傳遞自訂真實性令牌字串,或根本不新增真實性令牌欄位(傳遞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
hash 中表示它們的鍵) 實際上是從物件的類別衍生而來,例如,如果物件的類別是 Post
,則為 params[: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 路由 (例如使用 config/routes.rb
中的 resources
方法定義),就可以進一步簡化。在這種情況下,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 %>
您可以透過傳遞 url: false
來省略 action
屬性
<%= form_for(@post, url: false) 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
。
設定方法
您可以透過設定
method: (:get|:post|:patch|:put|:delete)
在選項雜湊中,強制表單使用完整的 HTTP 動詞陣列。如果動詞不是 HTML 表單原生支援的 GET 或 POST,表單將設定為 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>
移除隱藏的模型 ID
form_for
方法會自動將模型 ID 包含在表單中,作為一個隱藏欄位。這用於維持表單資料與其關聯模型之間的關聯性。有些 ORM 系統不會在巢狀模型上使用 ID,因此在這種情況下,您希望能夠停用隱藏 ID。
在以下範例中,Post 模型在 NoSQL 資料庫中儲存了許多 Comment,因此註解沒有主鍵。
範例
<%= 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 %>
來源:顯示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 434 def form_for(record, options = {}, &block) raise ArgumentError, "Missing block" unless block_given? case record when String, Symbol model = nil 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: nil, scope: nil, url: nil, format: nil, **options, &block) 連結
根據混合的 URL、範圍或模型建立表單標籤。
# Using just a URL:
<%= form_with url: posts_path do |form| %>
<%= form.text_field :title %>
<% end %>
# =>
<form action="/posts" 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: :post, url: posts_path do |form| %>
<%= form.text_field :title %>
<% end %>
# =>
<form action="/posts" method="post">
<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">
<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">
<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">
<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 支援並新增了跨網站請求偽造保護所需的真實性令牌。
以資源為導向的樣式
在許多剛剛顯示的範例中,傳遞給 form_with
的 :model
是資源。它對應於一組 RESTful 路由,很可能透過 config/routes.rb
中的 resources
定義。
因此,當傳遞此類模型記錄時,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 %>
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[:post]
變成params[:article]
。 -
:authenticity_token
- 表單中使用的真實性標記。使用自訂真實性標記覆寫,或傳遞false
以完全略過真實性標記欄位。在提交到外部資源(例如可能會限制有效欄位的付款閘道)時很有用。遠端表單可以透過設定config.action_view.embed_authenticity_token_in_remote_forms = false
來省略嵌入式真實性標記。當對表單進行片段快取時,這很有用。遠端表單從meta
標記取得真實性標記,因此除非支援沒有 JavaScript 的瀏覽器,否則不需要嵌入。 -
:local
- 是否使用標準 HTTP 表單提交。設定為true
時,表單透過標準 HTTP 提交。設定為false
時,表單以「遠端表單」提交,由 Rails UJS 以 XHR 處理。未指定時,行為會從config.action_view.form_with_generates_remote_forms
衍生,其中設定檔的值實際上是local
值的反向。從 Rails 6.1 開始,該設定檔選項預設為false
(具有傳遞local: true
的相同效果)。在先前版本的 Rails 中,該設定檔選項預設為true
(等於傳遞local: false
)。 -
:skip_enforcing_utf8
- 如果設定為 true,則不會輸出名稱為 utf8 的隱藏輸入。 -
:builder
- 覆寫用於建立表單的物件。 -
:id
- 選擇性 HTML id 屬性。 -
:class
- 選擇性 HTML class 屬性。 -
:data
- 選擇性 HTML 資料屬性。 -
:html
- 表單標記的其他選擇性 HTML 屬性。
範例
未傳遞區塊時,form_with
僅產生一個開啟表單標記。
<%= form_with(model: @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
。
設定方法
您可以透過設定
method: (:get|:post|:patch|:put|:delete)
在選項雜湊中,強制表單使用完整的 HTTP 動詞陣列。如果動詞不是 HTML 表單原生支援的 GET 或 POST,表單將設定為 POST,而稱為 _method 的隱藏輸入將傳遞伺服器要詮釋的預期動詞。
設定 HTML 選項
您可以在資料雜湊中直接設定資料屬性,但 id 和 class 以外的 HTML 選項必須包覆在 HTML 鍵中
<%= form_with(model: @post, data: { behavior: "autosave" }, html: { name: "go" }) do |form| %>
...
<% end %>
產生
<form action="/posts/123" method="post" data-behavior="autosave" name="go">
<input name="_method" type="hidden" value="patch" />
...
</form>
移除隱藏的模型 ID
form_with
方法會自動將模型 id 作為隱藏欄位包含在表單中。這用於維持表單資料與其關聯模型之間的關聯性。有些 ORM 系統不會在巢狀模型上使用 ID,因此在這種情況下,您希望能夠停用隱藏 id。
在以下範例中,Post 模型在 NoSQL 資料庫中儲存了許多 Comment,因此註解沒有主鍵。
<%= 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
來源:顯示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 755 def form_with(model: nil, scope: nil, url: nil, format: nil, **options, &block) 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 = {}) 連結
傳回一個隱藏的輸入標籤,用於存取指定屬性(由 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}" />
來源:在 GitHub 上
|label(object_name, method, content_or_options = nil, options = nil, &block) 連結
傳回一個標籤標籤,用於標記輸入欄位,該欄位用於指定屬性(由 method
識別),該屬性在指派給範本的物件上(由 object
識別)。標籤的文字預設為屬性名稱,除非在目前的 I18n 地區設定中找到翻譯(透過 helpers.label.<modelname>.<attribute>
),或您明確指定。標籤標籤上的其他選項可以用雜湊與 options
傳遞。這些選項會標記到 HTML 上,作為 HTML 元素屬性,如所示範例,但 :value
選項除外,該選項用於標記 radio_button
標籤(其中值用於輸入標籤的 ID)。
範例
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>
來源:顯示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1149 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 = {}) 連結
傳回類型為「month」的 text_field
。
month_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="month" />
預設值是嘗試使用「%Y-%m」對物件的值呼叫 strftime
產生,這使得它對 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 1529 def month_field(object_name, method, options = {}) Tags::MonthField.new(object_name, method, self, options).render end
number_field(object_name, method, options = {}) 連結
來源:顯示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1573 def number_field(object_name, method, options = {}) Tags::NumberField.new(object_name, method, self, options).render end
password_field(object_name, method, options = {}) 連結
傳回一個「密碼」類型的輸入標籤,專門用於存取指定屬性(由 method
識別),該屬性是在範本中指定物件(由 object
識別)上。輸入標籤上的其他選項可以傳遞為雜湊,其中包含 options
。這些選項會標記到 HTML 上,作為 HTML 元素屬性,如顯示範例所示。基於安全性考量,此欄位預設為空白;如果不需要,請透過 options
傳遞值。
範例
password_field(:login, :pass, size: 20)
# => <input type="password" id="login_pass" name="login[pass]" size="20" />
password_field(:account, :secret, class: "form_input", value: @account.secret)
# => <input type="password" id="account_secret" name="account[secret]" value="#{@account.secret}" class="form_input" />
password_field(:user, :password, onchange: "if ($('#user_password').val().length > 30) { alert('Your password needs to be shorter!'); }")
# => <input type="password" id="user_password" name="user[password]" onchange="if ($('#user_password').val().length > 30) { alert('Your password needs to be shorter!'); }"/>
password_field(:account, :pin, size: 20, class: 'form_input')
# => <input type="password" id="account_pin" name="account[pin]" size="20" class="form_input" />
來源:顯示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1194 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 = {}) 連結
傳回一個無線按鈕標籤,用於存取指定屬性(由 method
識別),該屬性是在範本中指定物件(由 object
識別)上。如果 method
的目前值為 tag_value
,無線按鈕會被勾選。
若要強制勾選無線按鈕,請在 options
雜湊中傳遞 checked: true
。您也可以在那裡傳遞 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" />
來源:顯示 | 在 GitHub 上
range_field(object_name, method, options = {}) 連結
來源:顯示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1582 def range_field(object_name, method, options = {}) Tags::RangeField.new(object_name, method, self, options).render end
rich_text_area(object_name, method, options = {}) 連結
傳回一個 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_text_area :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_text_area :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>
來源:顯示 | 在 GitHub 上
# File actiontext/app/helpers/action_text/tag_helper.rb, line 76 def rich_text_area(object_name, method, options = {}) Tags::ActionText.new(object_name, method, self, options).render end
search_field(object_name, method, options = {}) 連結
傳回類型為 “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" />
來源:顯示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1396 def search_field(object_name, method, options = {}) Tags::SearchField.new(object_name, method, self, options).render end
telephone_field(object_name, method, options = {}) 連結
傳回類型為 “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 1405 def telephone_field(object_name, method, options = {}) Tags::TelField.new(object_name, method, self, options).render end
text_area(object_name, method, options = {}) 連結
傳回一個 textarea 開頭和結尾標籤組,用於存取指定屬性(由 method
識別)在指定到範本的物件(由 object
識別)。輸入標籤上的其他選項可以用雜湊傳遞,並使用 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>
來源:顯示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1275 def text_area(object_name, method, options = {}) Tags::TextArea.new(object_name, method, self, options).render end
text_field(object_name, method, options = {}) 連結
傳回一個「文字」類型的輸入標籤,用於存取指定屬性(由 method
識別)在指定到範本的物件(由 object
識別)。輸入標籤上的其他選項可以用雜湊傳遞,並使用 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" />
來源:顯示 | 在 GitHub 上
# File actionview/lib/action_view/helpers/form_helper.rb, line 1173 def text_field(object_name, method, options = {}) Tags::TextField.new(object_name, method, self, options).render end
time_field(object_name, method, options = {}) 連結
傳回一個「時間」類型的 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 時間的 字串
作為「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 1475 def time_field(object_name, method, options = {}) Tags::TimeField.new(object_name, method, self, options).render end
url_field(object_name, method, options = {}) 連結
傳回一個「網址」類型的 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 1555 def url_field(object_name, method, options = {}) Tags::UrlField.new(object_name, method, self, options).render end
week_field(object_name, method, options = {}) 連結
傳回「week」類型的 text_field
。
week_field("user", "born_on")
# => <input id="user_born_on" name="user[born_on]" type="week" />
預設值是嘗試在物件的值上呼叫「%Y-W%W」的 strftime
,這會讓它在 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 1546 def week_field(object_name, method, options = {}) Tags::WeekField.new(object_name, method, self, options).render end