ChoiceType 欄位 (選擇下拉式選單、單選按鈕和複選框)
一個多用途欄位,用於允許使用者「選擇」一個或多個選項。它可以呈現為 select
標籤、單選按鈕或複選框。
要使用此欄位,您必須指定或者 choices
或 choice_loader
選項。
呈現為 | 可以是各種標籤 (請參閱下方) |
預設無效訊息 | 選取的選項無效。 |
父類型 | FormType |
類別 | ChoiceType |
提示
此表單類型定義和繼承的完整選項列表,可透過在您的應用程式中執行此命令取得
1 2
# replace 'FooType' by the class name of your form type
$ php bin/console debug:form FooType
範例用法
使用此欄位最簡單的方式是定義 choices
選項,以指定選項為關聯陣列,其中鍵是顯示給終端使用者的標籤,而陣列值是表單欄位中使用的內部值
1 2 3 4 5 6 7 8 9 10
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
// ...
$builder->add('isAttending', ChoiceType::class, [
'choices' => [
'Maybe' => null,
'Yes' => true,
'No' => false,
],
]);
這將建立一個像這樣的 select
下拉式選單

如果使用者選擇 No
,表單將針對此欄位傳回 false
。同樣地,如果此欄位的起始資料為 true
,則 Yes
將會自動選取。換句話說,每個項目的選項是您想要在 PHP 程式碼中取得/設定的值,而鍵是將顯示給使用者的標籤。
進階範例 (使用物件!)
此欄位有許多選項,並且大多數選項控制欄位的顯示方式。在此範例中,底層資料是一些具有 getName()
方法的 Category
物件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
use App\Entity\Category;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
// ...
$builder->add('category', ChoiceType::class, [
'choices' => [
new Category('Cat1'),
new Category('Cat2'),
new Category('Cat3'),
new Category('Cat4'),
],
// "name" is a property path, meaning Symfony will look for a public
// property or a public method like "getName()" to define the input
// string value that will be submitted by the form
'choice_value' => 'name',
// a callback to return the label for a given choice
// if a placeholder is used, its empty value (null) may be passed but
// its label is defined by its own "placeholder" option
'choice_label' => function (?Category $category): string {
return $category ? strtoupper($category->getName()) : '';
},
// returns the html attributes for each option input (may be radio/checkbox)
'choice_attr' => function (?Category $category): array {
return $category ? ['class' => 'category_'.strtolower($category->getName())] : [];
},
// every option can use a string property path or any callable that get
// passed each choice as argument, but it may not be needed
'group_by' => function (): string {
// randomly assign things into 2 groups
return rand(0, 1) === 1 ? 'Group A' : 'Group B';
},
// a callback to return whether a category is preferred
'preferred_choices' => function (?Category $category): bool {
return $category && 100 < $category->getArticleCounts();
},
]);
您也可以自訂每個選項的 choice_name。您可以在以下章節中瞭解有關所有這些選項的更多資訊。
警告
placeholder 是一個特定欄位,當選項是可選的時候,列表中的第一個項目必須是空的,以便使用者可以取消選取。使用回呼時,請務必始終處理空選項 null
。
選擇標籤、複選框或單選按鈕
此欄位可以呈現為多個 HTML 欄位之一,具體取決於 expanded
和 multiple
選項
元素類型 | 展開 | 多選 |
---|---|---|
select 標籤 | false |
false |
select 標籤 (帶有 multiple 屬性) |
false |
true |
單選按鈕 | true |
false |
複選框 | true |
true |
自訂每個選項的文字 (標籤)
通常,choices
選項中每個項目的陣列鍵會用作顯示給使用者的文字。但是,可以透過 choice_label 選項完全自訂。查看它以取得更多詳細資訊。
群組選項
您可以透過傳遞多維 choices
陣列,將 <select>
的 <option>
元素分組到 <optgroup>
中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
// ...
$builder->add('stockStatus', ChoiceType::class, [
'choices' => [
'Main Statuses' => [
'Yes' => 'stock_yes',
'No' => 'stock_no',
],
'Out of Stock Statuses' => [
'Backordered' => 'stock_backordered',
'Discontinued' => 'stock_discontinued',
],
],
]);

若要更精緻,請改用 group_by 選項。
欄位選項
choices
類型:array
預設值:[]
這是指定此欄位應使用之選項的最基本方法。choices
選項是一個陣列,其中陣列鍵是項目的標籤,而陣列值是項目的值
1 2 3 4 5 6 7 8 9
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
// ...
$builder->add('inStock', ChoiceType::class, [
'choices' => [
'In Stock' => true,
'Out of Stock' => false,
],
]);
如果存在非純量或字串化表示形式不唯一的選項值,Symfony 將使用遞增整數作為值。當表單提交時,具有正確類型的正確值將會被指派給模型。
choice_attr
類型:array
、callable
、string
或 PropertyPath 預設值:[]
使用此選項可為每個選項新增額外的 HTML 屬性。這可以是關聯陣列,其中鍵與選項鍵匹配,值是每個選項的屬性,也可以是可呼叫或屬性路徑 (就像 choice_label 一樣)。
如果是陣列,則必須將 choices
陣列的鍵用作鍵
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
// ...
$builder->add('fruits', ChoiceType::class, [
'choices' => [
'Apple' => 1,
'Banana' => 2,
'Durian' => 3,
],
'choice_attr' => [
'Apple' => ['data-color' => 'Red'],
'Banana' => ['data-color' => 'Yellow'],
'Durian' => ['data-color' => 'Green'],
],
]);
// or use a callable
$builder->add('attending', ChoiceType::class, [
'choices' => [
'Yes' => true,
'No' => false,
'Maybe' => null,
],
'choice_attr' => function ($choice, string $key, mixed $value) {
// adds a class like attending_yes, attending_no, etc
return ['class' => 'attending_'.strtolower($key)];
},
]);
提示
當定義自訂類型時,您應該使用 ChoiceList 類別協助程式
1 2 3 4 5 6 7 8 9
use App\Entity\Category;
use Symfony\Component\Form\ChoiceList\ChoiceList;
// ...
$builder->add('choices', ChoiceType::class, [
'choice_attr' => ChoiceList::attr($this, function (?Category $category): array {
return $category ? ['data-uuid' => $category->getUuid()] : [];
}),
]);
請參閱 「choice_loader」選項文件。
choice_filter
類型:callable
、string
或 PropertyPath 預設值:null
當使用來自 Symfony 核心或供應商程式庫的預定義選項類型 (即 CountryType) 時,此選項可讓您定義一個可呼叫物件,該物件將每個選項作為唯一引數,並且必須傳回 true
以保留選項或 false
以捨棄選項
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
// src/Form/Type/AddressType.php
namespace App\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CountryType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class AddressType extends AbstractType
{
public function configureOptions(OptionsResolver $resolver): void
{
$resolver
->setDefaults([
// enable this type to accept a limited set of countries
'allowed_countries' => null,
])
;
}
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$allowedCountries = $options['allowed_countries'];
$builder
// ...
->add('country', CountryType::class, [
// if the AddressType "allowed_countries" option is passed,
// use it to create a filter
'choice_filter' => $allowedCountries ? function ($countryCode) use ($allowedCountries): bool {
return in_array($countryCode, $allowedCountries, true);
} : null,
])
;
}
當選項是物件時,此選項可以是可呼叫物件或屬性路徑
1 2 3 4 5 6 7
// ...
$builder
->add('category', ChoiceType::class, [
// ...
'choice_filter' => 'isSelectable',
])
;
提示
考慮到這個 AddressType
可能是 CollectionType
的一個條目,您應該使用 ChoiceList 類別協助程式來啟用快取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// src/Form/Type/AddressType.php
// ...
use Symfony\Component\Form\ChoiceList\ChoiceList;
// ...
'choice_filter' => $allowedCountries ? ChoiceList::filter(
// pass the type as first argument
$this,
function (string $countryCode) use ($allowedCountries): bool {
return in_array($countryCode, $allowedCountries, true);
},
// pass the option that makes the filter "vary" to compute a unique hash
$allowedCountries
) : null,
// ...
choice_label
類型:string
、callable
、false
或 PropertyPath 預設值:null
預設情況下,choices
選項中每個項目的陣列鍵會用作顯示給使用者的文字。choice_label
選項可讓您取得更多控制權
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
// ...
$builder->add('attending', ChoiceType::class, [
'choices' => [
'yes' => true,
'no' => false,
'maybe' => null,
],
'choice_label' => function ($choice, string $key, mixed $value): TranslatableMessage|string {
if (true === $choice) {
return 'Definitely!';
}
return strtoupper($key);
// or if you want to translate some key
//return 'form.choice.'.$key;
//return new TranslatableMessage($key, false === $choice ? [] : ['%status%' => $value], 'store');
},
]);
此方法針對每個選項呼叫,從選項陣列中傳遞 $choice
和 $key
給您 (額外的 $value
與 choice_value 相關)。這將給您

如果您的選項值是物件,則 choice_label
也可以是 屬性路徑。想像一下您有一些具有 getDisplayName()
方法的 Status
類別
1 2 3 4 5 6 7 8 9 10 11
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
// ...
$builder->add('attending', ChoiceType::class, [
'choices' => [
new Status(Status::YES),
new Status(Status::NO),
new Status(Status::MAYBE),
],
'choice_label' => 'displayName',
]);
如果設定為 false
,則將為單選或複選框輸入捨棄所有標籤。您也可以從可呼叫物件傳回 false
以捨棄某些標籤。
提示
當定義自訂類型時,您應該使用 ChoiceList 類別協助程式
1 2 3 4 5 6
use Symfony\Component\Form\ChoiceList\ChoiceList;
// ...
$builder->add('choices', ChoiceType::class, [
'choice_label' => ChoiceList::label($this, 'displayName'),
]);
請參閱 「choice_loader」選項文件。
choice_loader
choice_loader
選項可以用來代替 choices
選項。它允許在僅擷取一組提交值的選項時,延遲或部分建立列表 (即查詢像 ElasticSearch
這樣的搜尋引擎可能是一個繁重的過程)。
如果您想利用延遲載入,可以使用 CallbackChoiceLoader 的實例
1 2 3 4 5 6 7 8 9 10
use App\StaticClass;
use Symfony\Component\Form\ChoiceList\Loader\CallbackChoiceLoader;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
// ...
$builder->add('loaded_choices', ChoiceType::class, [
'choice_loader' => new CallbackChoiceLoader(static function (): array {
return StaticClass::getConstants();
}),
]);
如果請求被重新導向並且沒有預設或提交的資料,這將導致不發生 StaticClass::getConstants()
的呼叫。否則,選項選項將需要被解析,從而觸發回呼。
如果內建的 CallbackChoiceLoader
不符合您的需求,您可以透過實作 ChoiceLoaderInterface 或擴充 AbstractChoiceLoader 來建立您自己的載入器。這個抽象類別透過實作介面的一些方法來為您節省一些樣板程式碼,因此您只需要實作 loadChoices() 方法即可擁有功能齊全的選項載入器。
當您定義一個可能在許多欄位 (例如集合的條目) 中重複使用或在多個表單中同時重複使用的自訂選項類型時,您應該使用 ChoiceList 靜態方法來包裝載入器,並使選項列表可快取以獲得更好的效能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
use App\Form\ChoiceList\CustomChoiceLoader;
use App\StaticClass;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\ChoiceList\ChoiceList;
use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ConstantsType extends AbstractType
{
public function getParent(): string
{
return ChoiceType::class;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
// the example below will create a CallbackChoiceLoader from the callable
'choice_loader' => ChoiceList::lazy($this, function () {
return StaticClass::getConstants();
}),
// you can pass your own loader as well, depending on other options
'some_key' => null,
'choice_loader' => function (Options $options): ChoiceLoaderInterface {
return ChoiceList::loader(
// pass the instance of the type or type extension which is
// currently configuring the choice list as first argument
$this,
// pass the other option to the loader
new CustomChoiceLoader($options['some_key']),
// ensure the type stores a loader per key
// by using the special third argument "$vary"
// an array containing anything that "changes" the loader
[$options['some_key']]
);
},
]);
}
}
choice_lazy
類型:boolean
預設值:false
7.2
choice_lazy
選項在 Symfony 7.2 中引入。
choice_lazy
選項在處理大量選項時特別有用,因為一次載入所有選項可能會導致效能問題或延遲
1 2 3 4 5 6 7
use App\Entity\User;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
$builder->add('user', EntityType::class, [
'class' => User::class,
'choice_lazy' => true,
]);
當設定為 true
並與 choice_loader
選項一起使用時,表單將僅載入和呈現預設值或提交值中預設的選項。這會延遲載入完整選項列表,有助於提高表單的效能。
警告
請記住,當使用 choice_lazy
時,您有責任為選擇選項提供使用者介面,通常透過能夠動態載入選項的 JavaScript 外掛程式。
choice_name
類型:callable
、string
或 PropertyPath 預設值:null
控制選項的內部欄位名稱。您通常不關心這個,但在某些進階情況下,您可能會關心。例如,此「名稱」會變成範本中選項檢視的索引,並用作欄位名稱屬性的一部分。
這可以是可呼叫物件或屬性路徑。有關類似用法,請參閱 choice_label。預設情況下,可以使用選項鍵或遞增整數 (從 0
開始)。
提示
當定義自訂類型時,您應該使用 ChoiceList 類別協助程式
1 2 3 4 5 6
use Symfony\Component\Form\ChoiceList\ChoiceList;
// ...
$builder->add('choices', ChoiceType::class, [
'choice_name' => ChoiceList::fieldName($this, 'name'),
]);
請參閱 「choice_loader」選項文件。
警告
設定的值必須是有效的表單名稱。使用可呼叫物件時,請確保僅傳回有效的名稱。有效的表單名稱必須由字母、數字、底線、破折號和冒號組成,並且不得以破折號或冒號開頭。
choice_translation_domain
類型:string
、boolean
或 null
預設值:true
此選項決定是否應翻譯選項值以及在哪個翻譯網域中翻譯。
choice_translation_domain
選項的值可以是 true
(重複使用目前的翻譯網域)、false
(停用翻譯)、null
(使用父翻譯網域或預設網域) 或表示要使用的確切翻譯網域的字串。
choice_translation_parameters
類型:array
、callable
、string
或 PropertyPath 預設值:[]
選項值會在顯示之前翻譯,因此它可以包含 翻譯佔位符。此選項定義用於取代這些佔位符的值。這可以是關聯陣列,其中鍵與選項鍵匹配,值是每個選項的屬性,也可以是可呼叫或屬性路徑 (就像 choice_label 一樣)。
給定此翻譯訊息
1 2 3
# translations/messages.en.yaml
form.order.yes: 'I confirm my order to the company %company%'
form.order.no: 'I cancel my order'
您可以如下指定佔位符值
1 2 3 4 5 6 7 8 9 10 11 12 13
$builder->add('id', null, [
'choices' => [
'form.order.yes' => true,
'form.order.no' => false,
],
'choice_translation_parameters' => function ($choice, string $key, mixed $value): array {
if (false === $choice) {
return [];
}
return ['%company%' => 'ACME Inc.'];
},
]);
如果是陣列,則必須將 choices
陣列的鍵用作鍵
1 2 3 4 5 6 7 8 9 10
$builder->add('id', null, [
'choices' => [
'form.order.yes' => true,
'form.order.no' => false,
],
'choice_translation_parameters' => [
'form.order.yes' => ['%company%' => 'ACME Inc.'],
'form.order.no' => [],
],
]);
子欄位的翻譯參數會與其父欄位的相同選項合併,因此子欄位可以重複使用和/或覆寫任何父佔位符。
choice_value
類型:callable
、string
或 PropertyPath 預設值:null
針對每個選項傳回字串「value」,這在所有選項中必須是唯一的。這在 HTML 中的 value
屬性中使用,並在 POST/PUT 請求中提交。您通常不需要擔心這個,但在處理 API 請求時可能會很方便 (因為您可以設定將在 API 請求中傳送的值)。
這可以是可呼叫物件或屬性路徑。預設情況下,如果選項可以轉換為字串,則會使用選項。否則,將使用遞增整數 (從 0
開始)。
如果您傳遞可呼叫物件,它將接收一個引數:選項本身。當使用 EntityType 欄位時,引數將是每個選項的實體物件,如果使用佔位符,則為 null
,您需要處理它
1 2 3
'choice_value' => function (?MyOptionEntity $entity): string {
return $entity ? $entity->getId() : '';
},
提示
當定義自訂類型時,您應該使用 ChoiceList 類別協助程式
1 2 3 4 5 6
use Symfony\Component\Form\ChoiceList\ChoiceList;
// ...
$builder->add('choices', ChoiceType::class, [
'choice_value' => ChoiceList::value($this, 'uuid'),
]);
請參閱 「choice_loader」選項文件。
duplicate_preferred_choices
類型:boolean
預設值:true
當使用 preferred_choices
選項時,這些偏好選項預設會顯示兩次:在列表的頂部和下面的完整列表中。將此選項設定為 false
,僅在列表頂部顯示偏好選項
1 2 3 4 5 6 7 8 9 10 11 12 13
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
// ...
$builder->add('language', ChoiceType::class, [
'choices' => [
'English' => 'en',
'Spanish' => 'es',
'Bork' => 'muppets',
'Pirate' => 'arr',
],
'preferred_choices' => ['muppets', 'arr'],
'duplicate_preferred_choices' => false,
]);
group_by
類型:string
、callable
或 PropertyPath 預設值:null
您可以透過將多維陣列傳遞給 choices
,將 <select>
的 <option>
元素分組到 <optgroup>
中。請參閱有關此內容的 群組選項 章節。
group_by
選項是群組選項的替代方法,它為您提供更大的彈性。
以下列範例為例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
// ...
$builder->add('publishAt', ChoiceType::class, [
'choices' => [
'now' => new \DateTime('now'),
'tomorrow' => new \DateTime('+1 day'),
'1 week' => new \DateTime('+1 week'),
'1 month' => new \DateTime('+1 month'),
],
'group_by' => function($choice, $key, $value) {
if ($choice <= new \DateTime('+3 days')) {
return 'Soon';
}
return 'Later';
},
]);
這會將 3 天內的日期分組到「Soon」中,並將所有其他日期分組到「Later」<optgroup>
中

如果您傳回 null
,則選項將不會分組。您也可以傳遞將被呼叫以取得群組的字串「屬性路徑」。有關使用屬性路徑的詳細資訊,請參閱 choice_label。
提示
當定義自訂類型時,您應該使用 ChoiceList 類別協助程式
1 2 3 4 5 6
use Symfony\Component\Form\ChoiceList\ChoiceList;
// ...
$builder->add('choices', ChoiceType::class, [
'group_by' => ChoiceList::groupBy($this, 'category'),
]);
請參閱 「choice_loader」選項文件。
multiple
類型:boolean
預設值:false
如果為 true,使用者將能夠選擇多個選項 (而不是僅選擇一個選項)。根據 expanded
選項的值,如果為 true,這將呈現 select 標籤或複選框,如果為 false,則呈現 select 標籤或單選按鈕。傳回的值將會是一個陣列。
placeholder
類型:string
或 TranslatableMessage
或 boolean
此選項決定是否在 select 小工具的頂部顯示特殊的「空」選項 (例如「選擇一個選項」)。此選項僅在 multiple
選項設定為 false 時適用。
新增一個空值,文字為「選擇一個選項」
1 2 3 4 5 6 7 8 9
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; // ... $builder->add('states', ChoiceType::class, [ 'placeholder' => 'Choose an option', // or if you want to translate the text 'placeholder' => new TranslatableMessage('form.placeholder.select_option', [], 'form'), ]);
保證不會顯示「空」值選項
1 2 3 4 5 6
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; // ... $builder->add('states', ChoiceType::class, [ 'placeholder' => false, ]);
如果您將 placeholder
選項設定為未設定,則僅當 required
選項為 false 時,才會自動新增空白 (沒有文字) 選項
1 2 3 4 5 6 7
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
// ...
// a blank (with no text) option will be added
$builder->add('states', ChoiceType::class, [
'required' => false,
]);
placeholder_attr
類型:array
預設值:[]
使用此選項可為佔位符選項新增額外的 HTML 屬性
1 2 3 4 5 6 7 8 9 10
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
// ...
$builder->add('fruits', ChoiceType::class, [
// ...
'placeholder' => '...',
'placeholder_attr' => [
['title' => 'Choose an option'],
],
]);
preferred_choices
類型:array
、callable
、string
或 PropertyPath 預設值:[]
此選項可讓您在列表頂端顯示特定選項,並在這些選項與完整選項列表之間加上視覺分隔線。如果您有一個語言表單,您可以將最常用的語言列在頂端,例如 Bork 和 Pirate。
1 2 3 4 5 6 7 8 9 10 11 12
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
// ...
$builder->add('language', ChoiceType::class, [
'choices' => [
'English' => 'en',
'Spanish' => 'es',
'Bork' => 'muppets',
'Pirate' => 'arr',
],
'preferred_choices' => ['muppets', 'arr'],
]);
此選項也可以是一個回呼函數,讓您有更大的彈性。如果您的值是物件,這可能會特別有用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
// ...
$builder->add('publishAt', ChoiceType::class, [
'choices' => [
'now' => new \DateTime('now'),
'tomorrow' => new \DateTime('+1 day'),
'1 week' => new \DateTime('+1 week'),
'1 month' => new \DateTime('+1 month'),
],
'preferred_choices' => function ($choice, $key, $value): bool {
// prefer options within 3 days
return $choice <= new \DateTime('+3 days');
},
]);
這將「偏好」僅顯示「now」和「tomorrow」選項。

最後,如果您的值是物件,您也可以在物件上指定一個屬性路徑字串,該字串將傳回 true 或 false。
偏好選項僅在呈現 select
元素時才有意義(即 expanded
為 false)。偏好選項和一般選項在視覺上以一組虛線分隔(即 -------------------
)。這可以在呈現欄位時進行自訂。
1
{{ form_widget(form.publishAt, { 'separator': '=====' }) }}
提示
當定義自訂類型時,您應該使用 ChoiceList 類別協助程式
1 2 3 4 5 6
use Symfony\Component\Form\ChoiceList\ChoiceList;
// ...
$builder->add('choices', ChoiceType::class, [
'preferred_choices' => ChoiceList::preferred($this, 'taggedAsFavorite'),
]);
請參閱 「choice_loader」選項文件。
separator
type: string
default: -------------------
此選項可讓您自訂在偏好選項之後顯示的視覺分隔線。您可以使用 HTML 元素,例如 <hr>
來顯示更現代的分隔線,但您也需要將 separator_html 選項設定為 true
。
7.1
separator
選項在 Symfony 7.1 中引入。
separator_html
類型:boolean
預設值:false
如果此選項為 true,則 separator 選項將顯示為 HTML 而不是文字。當使用 HTML 元素(例如 <hr>
)作為更現代的視覺分隔線時,這非常有用。
7.1
separator_html
選項在 Symfony 7.1 中引入。
覆寫的選項
empty_data
type: mixed
此選項的實際預設值取決於其他欄位選項。
- 如果
multiple
為false
且expanded
為false
,則為''
(空字串); - 否則為
[]
(空陣列)。
此選項決定當提交的值為空(或遺失)時,欄位將傳回的值。如果視圖中呈現表單時未提供初始值,則此選項不會設定初始值。
這表示它可以幫助您處理具有空白欄位的表單提交。例如,如果您希望在未選取任何值時,將 name
欄位明確設定為 John Doe
,您可以這樣做:
1 2 3 4
$builder->add('name', null, [
'required' => false,
'empty_data' => 'John Doe',
]);
這仍然會呈現一個空白文字方塊,但在提交時,將會設定 John Doe
值。使用 data
或 placeholder
選項在呈現的表單中顯示此初始值。
注意
如果表單是複合式,您可以將 empty_data
設定為陣列、物件或閉包。可以為整個表單類別設定此選項,請參閱如何為表單類別設定空資料文章,以取得有關這些選項的更多詳細資訊。
警告
表單資料轉換器仍將應用於 empty_data
值。這表示空字串將被轉換為 null
。如果您明確想要傳回空字串,請使用自訂資料轉換器。
invalid_message
type: string
default: This value is not valid
這是驗證錯誤訊息,當輸入到此欄位的資料沒有意義(即驗證失敗)時使用。
例如,如果使用者在 TimeType 欄位中輸入無法轉換為真實時間的無意義字串,或者如果使用者在數字欄位中輸入字串(例如 apple
),則可能會發生這種情況。
正常的(業務邏輯)驗證(例如,設定欄位的最小長度)應使用驗證規則的驗證訊息來設定(參考)。
繼承的選項
這些選項繼承自 FormType。
attr
類型:array
預設值:[]
如果您想將額外的屬性新增至 HTML 欄位表示,您可以使用 attr
選項。它是一個關聯陣列,HTML 屬性作為鍵。當您需要為某些小工具設定自訂類別時,這可能很有用。
1 2 3
$builder->add('body', TextareaType::class, [
'attr' => ['class' => 'tinymce'],
]);
另請參閱
如果您想將這些屬性新增至表單類型列元素,請使用 row_attr
選項。
by_reference
類型:boolean
預設值:true
在大多數情況下,如果您有一個 author
欄位,那麼您期望在底層物件上呼叫 setAuthor()
。但是,在某些情況下,可能不會呼叫 setAuthor()
。將 by_reference
設定為 false
可確保在所有情況下都呼叫 setter。
為了進一步解釋這一點,這是一個簡單的範例:
1 2 3 4 5 6 7 8 9 10 11 12 13
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
// ...
$builder = $this->createFormBuilder($article);
$builder
->add('title', TextType::class)
->add(
$builder->create('author', FormType::class, ['by_reference' => ?])
->add('name', TextType::class)
->add('email', EmailType::class)
)
如果 by_reference
為 true,當您在表單上呼叫 submit()
(或 handleRequest()
)時,幕後會發生以下情況:
1 2 3
$article->setTitle('...');
$article->getAuthor()->setName('...');
$article->getAuthor()->setEmail('...');
請注意,未呼叫 setAuthor()
。作者是透過引用修改的。
如果您將 by_reference
設定為 false,則提交看起來像這樣:
1 2 3 4 5
$article->setTitle('...');
$author = clone $article->getAuthor();
$author->setName('...');
$author->setEmail('...');
$article->setAuthor($author);
因此,by_reference=false
真正做的就是複製物件,這會強制框架在父物件上呼叫 setter。
同樣地,如果您正在使用 CollectionType 欄位,其中您的底層集合資料是一個物件(例如 Doctrine 的 ArrayCollection
),那麼如果您需要呼叫 adder 和 remover(例如 addAuthor()
和 removeAuthor()
),則必須將 by_reference
設定為 false
。
data
type: mixed
default: 預設為底層結構的欄位。
當您建立表單時,每個欄位最初都會顯示表單網域資料的對應屬性值(例如,如果您將物件繫結到表單)。如果您想覆寫表單或個別欄位的此初始值,您可以在 data 選項中設定它。
1 2 3 4 5 6
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
// ...
$builder->add('token', HiddenType::class, [
'data' => 'abcdef',
]);
警告
呈現時,data
選項總是會覆寫從網域資料(物件)取得的值。這表示當表單編輯已持久化的物件時,物件值也會被覆寫,導致它在提交表單時遺失其持久化的值。
error_mapping
類型:array
預設值:[]
此選項可讓您修改驗證錯誤的目標。
假設您有一個名為 matchingCityAndZipCode()
的自訂方法,用於驗證城市和郵遞區號是否匹配。不幸的是,您的表單中沒有 matchingCityAndZipCode
欄位,因此 Symfony 所能做的就是在表單頂端顯示錯誤。
透過自訂錯誤映射,您可以做得更好:將錯誤映射到城市欄位,使其顯示在其上方。
1 2 3 4 5 6 7 8
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'error_mapping' => [
'matchingCityAndZipCode' => 'city',
],
]);
}
以下是映射左右兩側的規則:
- 左側包含屬性路徑;
- 如果違規是在類別的屬性或方法上產生的,則其路徑為
propertyName
; - 如果違規是在
array
或ArrayAccess
物件的項目上產生的,則屬性路徑為[indexName]
; - 您可以透過串連屬性路徑來建構巢狀屬性路徑,並以點分隔屬性。例如:
addresses[work].matchingCityAndZipCode
; - 右側包含表單中欄位的名稱。
預設情況下,任何未映射屬性的錯誤都會冒泡到父表單。您可以使用點 (.
) 在左側將所有未映射屬性的錯誤映射到特定欄位。例如,若要將所有這些錯誤映射到 city
欄位,請使用:
1 2 3 4 5
$resolver->setDefaults([
'error_mapping' => [
'.' => 'city',
],
]);
help
type: string
或 TranslatableInterface
default: null
允許您為表單欄位定義說明訊息,預設情況下,說明訊息會呈現在欄位下方。
1 2 3 4 5 6 7 8 9 10 11 12 13
use Symfony\Component\Translation\TranslatableMessage;
$builder
->add('zipCode', null, [
'help' => 'The ZIP/Postal code for your credit card\'s billing address.',
])
// ...
->add('status', null, [
'help' => new TranslatableMessage('order.status', ['%order_id%' => $order->getId()], 'store'),
])
;
help_attr
類型:array
預設值:[]
設定用於顯示表單欄位說明訊息的元素的 HTML 屬性。其值是一個關聯陣列,HTML 屬性名稱作為鍵。這些屬性也可以在範本中設定。
1 2 3
{{ form_help(form.name, 'Your name', {
'help_attr': {'class': 'CUSTOM_LABEL_CLASS'}
}) }}
help_html
類型:boolean
預設值:false
預設情況下,在範本中呈現 help
選項的內容之前,會先對其進行跳脫。將此選項設定為 true
以不跳脫它們,當說明包含 HTML 元素時,這非常有用。
inherit_data
類型:boolean
預設值:false
此選項決定表單是否將從其父表單繼承資料。如果您有一組跨多個表單重複的欄位,這可能會很有用。請參閱 如何使用 "inherit_data" 減少程式碼重複。
警告
當欄位設定了 inherit_data
選項時,它會按原樣使用父表單的資料。這表示 資料轉換器將不會應用於該欄位。
label
type: string
或 TranslatableMessage
default: 標籤是從欄位名稱「猜測」出來的。
設定呈現欄位時將使用的標籤。設定為 false
將會抑制標籤。
1 2 3 4 5 6 7 8
use Symfony\Component\Translation\TranslatableMessage;
$builder
->add('zipCode', null, [
'label' => 'The ZIP/Postal code',
// optionally, you can use TranslatableMessage objects as the label content
'label' => new TranslatableMessage('address.zipCode', ['%country%' => $country], 'address'),
])
標籤也可以在範本中設定。
1
{{ form_label(form.name, 'Your name') }}
label_attr
類型:array
預設值:[]
設定 <label>
元素的 HTML 屬性,當呈現欄位的標籤時將會使用它。它是一個關聯陣列,HTML 屬性作為鍵。這些屬性也可以直接在範本內設定。
1 2 3
{{ form_label(form.name, 'Your name', {
'label_attr': {'class': 'CUSTOM_LABEL_CLASS'}
}) }}
label_html
類型:boolean
預設值:false
預設情況下,在範本中呈現 label
選項的內容之前,會先對其進行跳脫。將此選項設定為 true
以不跳脫它們,當標籤包含 HTML 元素時,這非常有用。
label_format
type: string
default: null
配置用作欄位標籤的字串,以防未設定 label
選項。當使用關鍵字翻譯訊息時,這非常有用。
如果您正在使用關鍵字翻譯訊息作為標籤,您通常會為同一個標籤擁有多個關鍵字訊息(例如,profile_address_street
、invoice_address_street
)。這是因為標籤是為欄位的每個「路徑」建構的。為了避免重複的關鍵字訊息,您可以將標籤格式配置為靜態值,例如:
1 2 3 4 5 6 7 8
// ...
$profileFormBuilder->add('address', AddressType::class, [
'label_format' => 'form.address.%name%',
]);
$invoiceFormBuilder->add('invoice', AddressType::class, [
'label_format' => 'form.address.%name%',
]);
此選項由子類型繼承。使用上面的程式碼,兩個表單的 street
欄位的標籤都將使用 form.address.street
關鍵字訊息。
標籤格式中有兩個變數可用:
%id%
- 欄位的唯一識別碼,包含欄位的完整路徑和欄位名稱(例如,
profile_address_street
); %name%
- 欄位名稱(例如,
street
)。
預設值 (null
) 會產生欄位名稱的 「人性化」版本。
注意
label_format
選項在表單主題中評估。如果您自訂表單主題,請確保更新您的範本。
required
類型:boolean
預設值:true
如果為 true,將會呈現 HTML5 required 屬性。對應的 label
也將以 required
類別呈現。
這是表面上的,並且獨立於驗證。在最好的情況下,如果您讓 Symfony 猜測您的欄位類型,那麼此選項的值將會從您的驗證資訊中猜測出來。
注意
required 選項也會影響每個欄位的空資料處理方式。如需更多詳細資訊,請參閱 empty_data 選項。
row_attr
類型:array
預設值:[]
新增至用於呈現表單類型列的元素的 HTML 屬性關聯陣列。
1 2 3
$builder->add('body', TextareaType::class, [
'row_attr' => ['class' => 'text-editor', 'id' => '...'],
]);
另請參閱
如果您想將這些屬性新增至表單類型小工具元素,請使用 attr
選項。
translation_domain
type: string
default: messages
如果 choice_translation_domain 設定為 true
或 null
,則這會配置將用於此欄位呈現的任何標籤或選項的確切翻譯網域。
label_translation_parameters
類型:array
預設值:[]
label 選項的內容在顯示之前會先翻譯,因此它可以包含翻譯預留位置。此選項定義用於取代這些預留位置的值。
給定此翻譯訊息
1 2
# translations/messages.en.yaml
form.order.id: 'Identifier of the order to %company%'
您可以如下指定佔位符值
1 2 3 4 5 6
$builder->add('id', null, [
'label' => 'form.order.id',
'label_translation_parameters' => [
'%company%' => 'ACME Inc.',
],
]);
子欄位的 label_translation_parameters
選項與其父欄位的相同選項合併,因此子欄位可以重複使用和/或覆寫任何父預留位置。
attr_translation_parameters
類型:array
預設值:[]
在 attr 選項中定義的 title
和 placeholder
值的內容在顯示之前會先翻譯,因此它可以包含翻譯預留位置。此選項定義用於取代這些預留位置的值。
給定此翻譯訊息
1 2 3
# translations/messages.en.yaml
form.order.id.placeholder: 'Enter unique identifier of the order to %company%'
form.order.id.title: 'This will be the reference in communications with %company%'
您可以如下指定佔位符值
1 2 3 4 5 6 7 8 9
$builder->add('id', null, [
'attr' => [
'placeholder' => 'form.order.id.placeholder',
'title' => 'form.order.id.title',
],
'attr_translation_parameters' => [
'%company%' => 'ACME Inc.',
],
]);
子欄位的 attr_translation_parameters
選項與其父欄位的相同選項合併,因此子欄位可以重複使用和/或覆寫任何父預留位置。
help_translation_parameters
類型:array
預設值:[]
help 選項的內容在顯示之前會先翻譯,因此它可以包含翻譯預留位置。此選項定義用於取代這些預留位置的值。
給定此翻譯訊息
1 2
# translations/messages.en.yaml
form.order.id.help: 'This will be the reference in communications with %company%'
您可以如下指定佔位符值
1 2 3 4 5 6
$builder->add('id', null, [
'help' => 'form.order.id.help',
'help_translation_parameters' => [
'%company%' => 'ACME Inc.',
],
]);
子欄位的 help_translation_parameters
選項與其父欄位的相同選項合併,因此子欄位可以重複使用和/或覆寫任何父預留位置。
欄位變數
變數 | 類型 | 用法 |
---|---|---|
multiple | boolean |
multiple 選項的值。 |
expanded | boolean |
expanded 選項的值。 |
preferred_choices | array |
一個巢狀陣列,包含應優先呈現給使用者的選項的 ChoiceView 物件。 |
choices | array |
一個巢狀陣列,包含剩餘選項的 ChoiceView 物件。 |
separator | string |
在選項群組之間使用的分隔符號。 |
placeholder | mixed |
如果空值尚未在列表中,則為空值,否則為 null 。 |
placeholder_attr | array |
placeholder_attr 選項的值。 |
choice_translation_domain | mixed |
boolean 、null 或 string ,以判斷是否應翻譯該值。 |
is_selected | callable |
一個可呼叫的物件,它接受一個 ChoiceView 和選取的值,並傳回選項是否在選取的值中。 |
placeholder_in_choices | boolean |
空值是否在選項列表中。 |
提示
在 Twig 範本中,與其使用 is_selected()
,不如使用 selectedchoice 測試,速度明顯更快。
存取表單選項資料
每個選項項目的 form.vars
變數都包含諸如選項是否被選取之類的資料。如果您需要取得選項資料和值的完整列表,請使用選項項目的父表單(即 ChoiceType
本身)中的 choices
變數,並搭配 form.parent.vars.choices
。
1 2 3 4 5 6 7 8
{# `true` or `false`, whether the current choice is selected as radio or checkbox #}
{{ form.vars.data }}
{# the current choice value (i.e a category name when `'choice_value' => 'name'` #}
{{ form.vars.value }}
{# a map of `ChoiceView` or `ChoiceGroupView` instances indexed by choice values or group names #}
{{ form.parent.vars.choices }}
依照與上面相同的高階範例(其中選項值是實體),Category
物件位於 form.parent.vars.choices[key].data
內部。
1 2 3 4 5 6 7 8 9 10 11
{% block _form_categories_entry_widget %}
{% set entity = form.parent.vars.choices[form.vars.value].data %}
<tr>
<td>{{ form_widget(form) }}</td>
<td>{{ form.vars.label }}</td>
<td>
{{ entity.name }} | {{ entity.group }}
</td>
</tr>
{% endblock %}