如何自訂表單呈現方式
Symfony 提供多種方式來自訂表單的呈現方式。在本文中,您將學習如何對表單的一個或多個欄位進行單獨的自訂。如果您需要以相同的方式自訂所有表單,請改為建立表單主題或使用任何內建主題,例如 Symfony 表單的 Bootstrap 主題。
表單呈現函數
單次呼叫 form() Twig 函數就足以呈現整個表單,包括所有欄位和錯誤訊息
1 2 3 4
{# form is a variable passed from the controller via
$this->render('...', ['form' => $form])
or $this->render('...', ['form' => $form->createView()]) #}
{{ form(form) }}
下一步是使用 form_start()、form_end()、form_errors() 和 form_row() Twig 函數來呈現不同的表單部分,以便您可以自訂它們,加入 HTML 元素和屬性
1 2 3 4 5 6 7 8 9 10 11 12 13 14
{{ form_start(form) }}
<div class="my-custom-class-for-errors">
{{ form_errors(form) }}
</div>
<div class="row">
<div class="col">
{{ form_row(form.task) }}
</div>
<div class="col" id="some-custom-id">
{{ form_row(form.dueDate) }}
</div>
</div>
{{ form_end(form) }}
form_row()
函數輸出整個欄位內容,包括標籤、輔助訊息、HTML 元素和錯誤訊息。所有這些都可以使用其他 Twig 函數進一步自訂,如下圖所示
form_label()、form_widget() (HTML 輸入)、form_help() 和 form_errors() Twig 函數讓您可以完全控制每個表單欄位的呈現方式,因此您可以完全自訂它們
1 2 3 4 5 6 7 8 9 10
<div class="form-control">
<i class="fa fa-calendar"></i> {{ form_label(form.dueDate) }}
{{ form_widget(form.dueDate) }}
<small>{{ form_help(form.dueDate) }}</small>
<div class="form-error">
{{ form_errors(form.dueDate) }}
</div>
</div>
警告
如果您正在手動呈現每個欄位,請確保您沒有忘記自動新增以進行 CSRF 保護的 _token
欄位。
您也可以使用 {{ form_rest(form) }}
(建議使用) 來呈現任何未手動呈現的欄位。有關更多資訊,請參閱下方 form_rest() 文件。
注意
本文稍後您可以找到這些 Twig 函數的完整參考,其中包含更多使用範例。
表單欄位輔助函數
前一節中顯示的 form_*()
輔助函數呈現表單欄位的不同部分,包括其所有 HTML 元素。一些開發人員和設計師對此行為感到困擾,因為它隱藏了表單主題中的所有 HTML 元素,而這些元素並非易於自訂。
這就是 Symfony 提供其他 Twig 表單輔助函數的原因,這些函數呈現每個表單欄位部分的值,而不會在其周圍新增任何 HTML
field_name()
field_value()
field_label()
field_help()
field_errors()
field_choices()
(選擇欄位的迭代器;例如,用於<select>
)
當使用這些輔助函數時,您必須編寫所有表單欄位的所有 HTML 內容,因此您不再需要處理表單主題
1 2 3 4 5 6 7 8 9 10 11 12 13 14
<input
name="{{ field_name(form.username) }}"
value="{{ field_value(form.username) }}"
placeholder="{{ field_label(form.username) }}"
class="form-control"
>
<select name="{{ field_name(form.country) }}" class="form-control">
<option value="">{{ field_label(form.country) }}</option>
{% for label, value in field_choices(form.country) %}
<option value="{{ value }}">{{ label }}</option>
{% endfor %}
</select>
表單呈現變數
前面章節中提到的一些 Twig 函數允許傳遞變數來配置其行為。例如,form_label()
函數可讓您定義自訂標籤,以覆寫表單中定義的標籤
1
{{ form_label(form.task, 'My Custom Task Label') }}
某些表單欄位類型具有可以傳遞到 widget 的其他呈現選項。這些選項在每個類型的文件中都有說明,但一個常見的選項是 attr
,它允許您修改表單元素上的 HTML 屬性。以下程式碼會將 task_field
CSS 類別新增至呈現的輸入文字欄位
1
{{ form_widget(form.task, {'attr': {'class': 'task_field'}}) }}
注意
如果您一次呈現整個表單 (或整個嵌入式表單),則 variables
引數只會套用至表單本身,而不會套用至其子表單。換句話說,以下程式碼不會將 "foo" 類別屬性傳遞給表單中的所有子欄位
1 2
{# does **not** work - the variables are not recursive #}
{{ form_widget(form, { 'attr': {'class': 'foo'} }) }}
如果您需要「手動」呈現表單欄位,則可以使用其 vars
屬性存取欄位的個別值 (例如 id
、name
和 label
)。例如,若要取得 id
1
{{ form.task.vars.id }}
注意
本文稍後您可以找到這些 Twig 變數及其描述的完整參考。
表單主題
前面章節中顯示的 Twig 函數和變數可以協助您自訂表單的一個或多個欄位。但是,此自訂無法套用至應用程式的其餘表單。
如果您想以相同的方式自訂所有表單 (例如,為了使產生的 HTML 程式碼適應應用程式中使用的 CSS 框架),您必須建立表單主題。
表單函數與變數參考
函數
form(form_view, variables)
呈現完整表單的 HTML。
1 2
{# render the form and change the submission method #}
{{ form(form, {'method': 'GET'}) }}
您主要會在原型設計時或在使用自訂表單主題時使用此輔助函數。如果您需要更大的彈性來呈現表單,您應該使用其他輔助函數來呈現表單的個別部分
1 2 3 4 5 6 7 8
{{ form_start(form) }}
{{ form_errors(form) }}
{{ form_row(form.name) }}
{{ form_row(form.dueDate) }}
{{ form_row(form.submit, { 'label': 'Submit me' }) }}
{{ form_end(form) }}
form_start(form_view, variables)
呈現表單的開始標籤。此輔助函數負責列印表單的已配置方法和目標動作。如果表單包含上傳欄位,它也會包含正確的 enctype
屬性。
1 2
{# render the start tag and change the submission method #}
{{ form_start(form, {'method': 'GET'}) }}
form_end(form_view, variables)
呈現表單的結束標籤。
1
{{ form_end(form) }}
此輔助函數也會輸出 form_rest()
(稍後將在本文中說明),除非您將 render_rest
設定為 false
1 2
{# don't render unrendered fields #}
{{ form_end(form, {render_rest: false}) }}
form_label(form_view, label, variables)
呈現給定欄位的標籤。您可以選擇性地傳遞您要顯示的特定標籤作為第二個引數。
1 2 3 4 5 6 7 8 9
{{ form_label(form.name) }}
{# The two following syntaxes are equivalent #}
{{ form_label(form.name, 'Your Name', {'label_attr': {'class': 'foo'}}) }}
{{ form_label(form.name, null, {
'label': 'Your name',
'label_attr': {'class': 'foo'}
}) }}
請參閱「如何自訂表單呈現方式」以瞭解 variables
引數。
form_errors(form_view)
呈現給定欄位的任何錯誤。
1 2 3 4 5
{# render only the error messages related to this field #}
{{ form_errors(form.name) }}
{# render any "global" errors not associated to any form field #}
{{ form_errors(form) }}
警告
在 Bootstrap 4 表單主題中,form_errors()
已包含在 form_label()
中。請參閱 Bootstrap 4 主題文件以瞭解更多資訊。
form_widget(form_view, variables)
呈現給定欄位的 HTML widget。如果您將其套用至整個表單或欄位集合,將會呈現每個基礎表單列。
1 2
{# render a widget, but add a "foo" class to it #}
{{ form_widget(form.name, {'attr': {'class': 'foo'}}) }}
form_widget()
的第二個引數是變數陣列。最常見的變數是 attr
,它是要套用至 HTML widget 的 HTML 屬性陣列。在某些情況下,某些類型也有其他可以傳遞的範本相關選項。這些將在類型基礎上進行討論。如果您一次呈現許多欄位 (例如 form_widget(form)
),則 attributes
不會遞迴套用至子欄位。
請參閱「如何自訂表單呈現方式」以瞭解有關 variables
引數的更多資訊。
form_row(form_view, variables)
呈現給定欄位的「列」,它是欄位的標籤、錯誤、輔助和 widget 的組合。
1 2
{# render a field row, but display a label with text "foo" #}
{{ form_row(form.name, {'label': 'foo'}) }}
form_row()
的第二個引數是變數陣列。Symfony 中提供的範本僅允許覆寫標籤,如上面的範例所示。
請參閱「如何自訂表單呈現方式」以瞭解 variables
引數。
form_rest(form_view, variables)
這會呈現給定表單中尚未呈現的所有欄位。最好始終在表單中的某個位置加入此函數,因為它會為您呈現隱藏欄位,並使您忘記呈現的任何欄位更容易被發現 (因為它會為您呈現該欄位)。
1
{{ form_rest(form) }}
form_parent(form_view)
傳回父表單檢視,如果表單檢視已是根表單,則傳回 null
。使用此函數應優先於使用 form.parent
存取父表單。當子表單命名為 parent
時,後者的方式會產生不同的結果。
測試
測試可以使用 Twig 中的 is
運算子來建立條件來執行。請閱讀 Twig 文件以瞭解更多資訊。
selectedchoice(selected_value)
此測試將檢查目前選項是否等於 selected_value
,或者目前選項是否在陣列中 (當 selected_value
是陣列時)。
1
<option {% if choice is selectedchoice(value) %}selected="selected"{% endif %}>
rootform
此測試將檢查目前的 form
是否沒有父表單檢視。
1 2 3 4 5 6 7 8 9 10 11 12
{# DON'T DO THIS: this simple check can't differentiate between a form having
a parent form view and a form defining a nested form field called 'parent' #}
{% if form.parent is null %}
{{ form_errors(form) }}
{% endif %}
{# DO THIS: this check is always reliable, even if the form defines a field called 'parent' #}
{% if form is rootform %}
{{ form_errors(form) }}
{% endif %}
表單變數參考
以下變數是每個欄位類型通用的。某些欄位類型可能會定義更多變數,而此處的一些變數實際上僅適用於某些類型。若要瞭解每個類型可用的確切變數,請查看您的表單主題使用的範本程式碼。
假設您的範本中有一個 form
變數,並且您想要參考 name
欄位上的變數,則可以使用 FormView 物件上的公用 vars
屬性來完成變數存取
1 2 3 4
<label for="{{ form.name.vars.id }}"
class="{{ form.name.vars.required ? 'required' }}">
{{ form.name.vars.label }}
</label>
變數 | 用法 |
---|---|
action |
目前表單的動作。 |
attr |
將呈現為欄位上 HTML 屬性的鍵值陣列。 |
block_prefixes |
所有父類型名稱的陣列。 |
cache_key |
用於快取的唯一金鑰。 |
compound |
欄位是否實際上是子欄位群組的持有者 (例如,choice 欄位,它實際上是核取方塊群組)。 |
data |
類型的標準化資料。 |
disabled |
如果為 true ,則會將 disabled="disabled" 新增至欄位。 |
errors |
附加到此特定欄位的任何錯誤陣列 (例如 form.title.errors )。請注意,您無法使用 form.errors 來判斷表單是否有效,因為這只會傳回「全域」錯誤:某些個別欄位可能會有錯誤。請改用 valid 選項。 |
form |
目前的 FormView 執行個體。 |
full_name |
要呈現的 name HTML 屬性。 |
help |
將呈現的輔助訊息。 |
id |
要呈現的 id HTML 屬性。 |
label |
將呈現的字串標籤。 |
label_attr |
將呈現為標籤上 HTML 屬性的鍵值陣列。 |
method |
目前表單的方法 (POST、GET 等)。 |
multipart |
如果為 true ,則 form_enctype 將呈現 enctype="multipart/form-data" 。 |
name |
欄位的名稱 (例如 title ) - 但不是 name HTML 屬性,它是 full_name 。 |
required |
如果為 true ,則會將 required 屬性新增至欄位以啟動 HTML5 驗證。此外,還會將 required 類別新增至標籤。 |
submitted |
傳回 true 或 false ,具體取決於是否已提交整個表單 |
translation_domain |
此表單翻譯的網域。 |
valid |
傳回 true 或 false ,具體取決於整個表單是否有效。 |
value |
呈現時將使用的值 (通常是 value HTML 屬性)。這僅適用於根表單元素。 |
提示
在幕後,當 Form 元件在表單樹狀結構的每個「節點」上呼叫 buildView()
和 finishView()
時,這些變數會提供給表單的 FormView
物件。若要查看特定欄位有哪些「檢視」變數,請尋找表單欄位的原始碼 (及其父欄位),並查看上述兩個函數。