@@ -71,10 +71,14 @@ This will create a ``select`` drop-down like this:
7171.. image :: /_images/reference/form/choice-example1.png
7272 :align: center
7373
74- If the user selects ``No ``, the form will return ``false `` for this field. Similarly,
75- if the starting data for this field is ``true ``, then ``Yes `` will be auto-selected.
76- In other words, the **value ** of each item is the value you want to get/set in PHP
77- code, while the **key ** is what will be shown to the user.
74+ The model data of this field, the **choice ** may be any of the ``choices `` option
75+ values, while **keys ** are used as default label that the user will see and select.
76+
77+ If the starting data for this field is ``true ``, then ``Yes `` will be auto-selected.
78+ In other words, each value of the ``choices `` option is the **choice ** data you
79+ want to deal with in PHP code, while the **key ** is the default label that will be
80+ shown to the user and the **value ** is the string that will be submitted to the
81+ form and used in the template for the corresponding html attribute.
7882
7983.. caution ::
8084
@@ -84,41 +88,98 @@ code, while the **key** is what will be shown to the user.
8488 and will be removed in 3.0. To read about the old API, read an older version of
8589 the docs.
8690
91+ .. note ::
92+
93+ Pre selected choices will depend on the **data ** passed to the field and
94+ the values of the ``choices `` option. However submitted choices will depend
95+ on the **string ** matching the **choice **. In the example above, the default
96+ values are incrementing integers because ``null `` cannot be casted to string.
97+ You should consider it as well when dealing with ``empty_data `` option::
98+
99+ $builder->add('isAttending', 'choice', array(
100+ 'choices' => array(
101+ 'Maybe' => null,
102+ 'Yes' => true,
103+ 'No' => false,
104+ ),
105+ 'choices_as_values' => true,
106+ 'data' => true, // pre selected choice
107+ 'empty_data' => '1', // default submitted value
108+ ));
109+
110+ When the ``multiple `` option is ``true `` the submitted data is an array of
111+ strings, you should the set the ``empty_value `` option accordingly.
112+ Also note that as a scalar ``false `` data as string **value ** is by default
113+ ``"0" `` to avoid conflict with placeholder value which is always an empty
114+ string.
115+
87116Advanced Example (with Objects!)
88117--------------------------------
89118
90119This field has a *lot * of options and most control how the field is displayed. In
91120this example, the underlying data is some ``Category `` object that has a ``getName() ``
92121method::
93122
94- $builder->add('category', 'choice', [
95- 'choices' => [
123+ $builder->add('category', 'choice', array(
124+ 'choices' => array(
96125 new Category('Cat1'),
97126 new Category('Cat2'),
98127 new Category('Cat3'),
99128 new Category('Cat4'),
100- ] ,
129+ ) ,
101130 'choices_as_values' => true,
102- 'choice_label' => function($category, $key, $index) {
103- /** @var Category $category */
131+ 'choice_label' => function(Category $category, $key, $value) {
104132 return strtoupper($category->getName());
105133 },
106- 'choice_attr' => function($category, $key, $index ) {
107- return [ 'class' => 'category_'.strtolower($category->getName())] ;
134+ 'choice_attr' => function(Category $category, $key, $value ) {
135+ return array( 'class' => 'category_'.strtolower($category->getName())) ;
108136 },
109-
110- 'group_by' => function($category, $key, $index) {
137+ 'group_by' => function(Category $category, $key, $value) {
111138 // randomly assign things into 2 groups
112139 return rand(0, 1) == 1 ? 'Group A' : 'Group B';
113140 },
114- 'preferred_choices' => function($category, $key, $index ) {
115- return $category->getName() == 'Cat2' || $category->getName() == 'Cat3' ;
141+ 'preferred_choices' => function(Category $category, $key, $value ) {
142+ return 'Cat2' === $category->getName() || 'Cat3' === $category->getName();
116143 },
117- ] );
144+ ) );
118145
119146You can also customize the `choice_name `_ and `choice_value `_ of each choice if
120147you need further HTML customization.
121148
149+ .. caution ::
150+
151+ When dealing with objects as choices, you should be careful about how
152+ string values are set to use them with the `empty_data ` option.
153+ In the example above, the default values are incrementing integers if the
154+ ``Category `` class does not implement ``toString `` method.
155+ To get a full control of the string values use the `choice_value `_ option::
156+
157+ $builder->add('category', 'choice', array(
158+ 'choices' => array(
159+ new Category('Cat1'),
160+ new Category('Cat2'),
161+ new Category('Cat3'),
162+ new Category('Cat4'),
163+ ),
164+ 'choices_as_values' => true,
165+ 'choice_value' => function(Category $category = null) {
166+ if (null === $category) {
167+ return '';
168+ }
169+
170+ return strtolower($category->getName());
171+ },
172+ 'choice_label' => function(Category $category, $key, $value) {
173+ return strtoupper($category->getName());
174+ },
175+ 'multiple' => true,
176+ 'empty_data' => array('cat2'), // default submitted value
177+ // an array because of multiple option
178+ ));
179+
180+ Note that `choice_value `_ option set as a callable can get passed ``null ``
181+ when no data is preset or submitted.
182+
122183.. _forms-reference-choice-tags :
123184
124185.. include :: /reference/forms/types/options/select_how_rendered.rst.inc
@@ -162,18 +223,25 @@ Field Options
162223choices
163224~~~~~~~
164225
165- **type **: ``array `` **default **: ``array() ``
226+ **type **: ``array `` or `` \Traversable `` **default **: ``array() ``
166227
167228This is the most basic way to specify the choices that should be used
168229by this field. The ``choices `` option is an array, where the array key
169- is the item 's label and the array value is the item 's value ::
230+ is the choice 's label and the array value is the choice 's data ::
170231
171232 $builder->add('inStock', 'choice', array(
172- 'choices' => array('In Stock' => true, 'Out of Stock' => false),
233+ 'choices' => array(
234+ 'In Stock' => true,
235+ 'Out of Stock' => false,
236+ ),
173237 // always include this
174238 'choices_as_values' => true,
175239 ));
176240
241+ The component will try to cast the choices data to string to use it in view
242+ format, in that case ``"0" `` and ``"1" ``, but you can customize it using the
243+ `choice_value `_ option.
244+
177245.. include :: /reference/forms/types/options/choice_attr.rst.inc
178246
179247.. _reference-form-choice-label :
@@ -231,9 +299,14 @@ choice_loader
231299
232300**type **: :class: `Symfony\\ Component\\ Form\\ ChoiceList\\ Loader\\ ChoiceLoaderInterface `
233301
234- The ``choice_loader `` can be used to only partially load the choices in cases where
235- a fully-loaded list is not necessary. This is only needed in advanced cases and
236- would replace the ``choices `` option.
302+ The ``choice_loader `` can be used to load the choices form a data source with a
303+ custom logic (e.g query language) such as database or search engine.
304+ The list will be fully loaded to display the form, but while submission only the
305+ submitted choices will be loaded.
306+
307+ Also, the :class: ``Symfony\\ Component\\ Form\\ ChoiceList\\ Factory\\ ChoiceListFactoryInterface` ` will cache the choice list
308+ so the same :class: ``Symfony\\ Component\\ Form\\ ChoiceList\\ Loader\\ ChoiceLoaderInterface` ` can be used in different fields with more performance
309+ (reducing N queries to 1).
237310
238311.. include :: /reference/forms/types/options/choice_name.rst.inc
239312
@@ -252,8 +325,8 @@ choices_as_values
252325
253326The ``choices_as_values `` option was added to keep backward compatibility with the
254327*old * way of handling the ``choices `` option. When set to ``false `` (or omitted),
255- the choice keys are used as the underlying value and the choice values are shown
256- to the user.
328+ the choice keys are used as the view value and the choice values are shown
329+ to the user as label .
257330
258331* Before 2.7 (and deprecated now)::
259332
0 commit comments