@@ -70,10 +70,14 @@ This will create a ``select`` drop-down like this:
70
70
.. image :: /images/reference/form/choice-example1.png
71
71
:align: center
72
72
73
- If the user selects ``No ``, the form will return ``false `` for this field. Similarly,
74
- if the starting data for this field is ``true ``, then ``Yes `` will be auto-selected.
75
- In other words, the **value ** of each item is the value you want to get/set in PHP
76
- code, while the **key ** is what will be shown to the user.
73
+ The model data of this field, the **choice ** may be any of the ``choices `` option
74
+ values, while **keys ** are used as default label that the user will see and select.
75
+
76
+ If the starting data for this field is ``true ``, then ``Yes `` will be auto-selected.
77
+ In other words, each value of the ``choices `` option is the **choice ** data you
78
+ want to deal with in PHP code, while the **key ** is the default label that will be
79
+ shown to the user and the **value ** is the string that will be submitted to the
80
+ form and used in the template for the corresponding html attribute.
77
81
78
82
.. caution ::
79
83
@@ -83,40 +87,98 @@ code, while the **key** is what will be shown to the user.
83
87
and will be removed in 3.0. To read about the old API, read an older version of
84
88
the docs.
85
89
90
+ .. note ::
91
+
92
+ Pre selected choices will depend on the **data ** passed to the field and
93
+ the values of the ``choices `` option. However submitted choices will depend
94
+ on the **string ** matching the **choice **. In the example above, the default
95
+ values are incrementing integers because ``null `` cannot be casted to string.
96
+ You should consider it as well when dealing with ``empty_data `` option::
97
+
98
+ $builder->add('isAttending', 'choice', array(
99
+ 'choices' => array(
100
+ 'Maybe' => null,
101
+ 'Yes' => true,
102
+ 'No' => false,
103
+ ),
104
+ 'choices_as_values' => true,
105
+ 'data' => true, // pre selected choice
106
+ 'empty_data' => '1', // default submitted value
107
+ ));
108
+
109
+ When the ``multiple `` option is ``true `` the submitted data is an array of
110
+ strings, you should the set the ``empty_value `` option accordingly.
111
+ Also note that as a scalar ``false `` data as string **value ** is by default
112
+ ``"0" `` to avoid conflict with placeholder value which is always an empty
113
+ string.
114
+
86
115
Advanced Example (with Objects!)
87
116
--------------------------------
88
117
89
118
This field has a *lot * of options and most control how the field is displayed. In
90
119
this example, the underlying data is some ``Category `` object that has a ``getName() ``
91
120
method::
92
121
93
- $builder->add('category', 'choice', [
94
- 'choices' => [
122
+ $builder->add('category', 'choice', array(
123
+ 'choices' => array(
95
124
new Category('Cat1'),
96
125
new Category('Cat2'),
97
126
new Category('Cat3'),
98
127
new Category('Cat4'),
99
- ] ,
128
+ ) ,
100
129
'choices_as_values' => true,
101
- 'choice_label' => function($category, $key, $index) {
102
- /** @var Category $category */
130
+ 'choice_label' => function(Category $category, $key, $value) {
103
131
return strtoupper($category->getName());
104
132
},
105
- 'choice_attr' => function($category, $key, $index ) {
106
- return [ 'class' => 'category_'.strtolower($category->getName())] ;
133
+ 'choice_attr' => function(Category $category, $key, $value ) {
134
+ return array( 'class' => 'category_'.strtolower($category->getName())) ;
107
135
},
108
- 'group_by' => function($category, $key, $index ) {
136
+ 'group_by' => function(Category $category, $key, $value ) {
109
137
// randomly assign things into 2 groups
110
138
return rand(0, 1) == 1 ? 'Group A' : 'Group B';
111
139
},
112
- 'preferred_choices' => function($category, $key, $index ) {
113
- return $category->getName() == 'Cat2' || $category->getName() == 'Cat3' ;
140
+ 'preferred_choices' => function(Category $category, $key, $value ) {
141
+ return 'Cat2' === $category->getName() || 'Cat3' === $category->getName();
114
142
},
115
- ] );
143
+ ) );
116
144
117
145
You can also customize the `choice_name `_ and `choice_value `_ of each choice if
118
146
you need further HTML customization.
119
147
148
+ .. caution ::
149
+
150
+ When dealing with objects as choices, you should be careful about how
151
+ string values are set to use them with the `empty_data ` option.
152
+ In the example above, the default values are incrementing integers if the
153
+ ``Category `` class does not implement ``toString `` method.
154
+ To get a full control of the string values use the `choice_value `_ option::
155
+
156
+ $builder->add('category', 'choice', array(
157
+ 'choices' => array(
158
+ new Category('Cat1'),
159
+ new Category('Cat2'),
160
+ new Category('Cat3'),
161
+ new Category('Cat4'),
162
+ ),
163
+ 'choices_as_values' => true,
164
+ 'choice_value' => function(Category $category = null) {
165
+ if (null === $category) {
166
+ return '';
167
+ }
168
+
169
+ return strtolower($category->getName());
170
+ },
171
+ 'choice_label' => function(Category $category, $key, $value) {
172
+ return strtoupper($category->getName());
173
+ },
174
+ 'multiple' => true,
175
+ 'empty_data' => array('cat2'), // default submitted value
176
+ // an array because of multiple option
177
+ ));
178
+
179
+ Note that `choice_value `_ option set as a callable can get passed ``null ``
180
+ when no data is preset or submitted.
181
+
120
182
.. _forms-reference-choice-tags :
121
183
122
184
.. include :: /reference/forms/types/options/select_how_rendered.rst.inc
@@ -135,19 +197,19 @@ Grouping Options
135
197
136
198
You can easily "group" options in a select by passing a multi-dimensional choices array::
137
199
138
- $builder->add('stockStatus', 'choice', [
139
- 'choices' => [
140
- 'Main Statuses' => [
200
+ $builder->add('stockStatus', 'choice', array(
201
+ 'choices' => array(
202
+ 'Main Statuses' => array(
141
203
'Yes' => 'stock_yes',
142
204
'No' => 'stock_no',
143
- ] ,
144
- 'Out of Stock Statuses' => [
205
+ ) ,
206
+ 'Out of Stock Statuses' => array(
145
207
'Backordered' => 'stock_backordered',
146
208
'Discontinued' => 'stock_discontinued',
147
- ]
148
- ] ,
209
+ ),
210
+ ) ,
149
211
'choices_as_values' => true,
150
- );
212
+ )) ;
151
213
152
214
.. image :: /images/reference/form/choice-example4.png
153
215
:align: center
@@ -160,18 +222,25 @@ Field Options
160
222
choices
161
223
~~~~~~~
162
224
163
- **type **: ``array `` **default **: ``array() ``
225
+ **type **: ``array `` or `` \Traversable `` **default **: ``array() ``
164
226
165
227
This is the most basic way to specify the choices that should be used
166
228
by this field. The ``choices `` option is an array, where the array key
167
- is the item 's label and the array value is the item 's value ::
229
+ is the choice 's label and the array value is the choice 's data ::
168
230
169
231
$builder->add('inStock', 'choice', array(
170
- 'choices' => array('In Stock' => true, 'Out of Stock' => false),
232
+ 'choices' => array(
233
+ 'In Stock' => true,
234
+ 'Out of Stock' => false,
235
+ ),
171
236
// always include this
172
237
'choices_as_values' => true,
173
238
));
174
239
240
+ The component will try to cast the choices data to string to use it in view
241
+ format, in that case ``"0" `` and ``"1" ``, but you can customize it using the
242
+ `choice_value `_ option.
243
+
175
244
.. include :: /reference/forms/types/options/choice_attr.rst.inc
176
245
177
246
.. _reference-form-choice-label :
@@ -229,9 +298,14 @@ choice_loader
229
298
230
299
**type **: :class: `Symfony\\ Component\\ Form\\ ChoiceList\\ Loader\\ ChoiceLoaderInterface `
231
300
232
- The ``choice_loader `` can be used to only partially load the choices in cases where
233
- a fully-loaded list is not necessary. This is only needed in advanced cases and
234
- would replace the ``choices `` option.
301
+ The ``choice_loader `` can be used to load the choices form a data source with a
302
+ custom logic (e.g query language) such as database or search engine.
303
+ The list will be fully loaded to display the form, but while submission only the
304
+ submitted choices will be loaded.
305
+
306
+ Also, the :class: ``Symfony\\ Component\\ Form\\ ChoiceList\\ Factory\\ ChoiceListFactoryInterface` ` will cache the choice list
307
+ so the same :class: ``Symfony\\ Component\\ Form\\ ChoiceList\\ Loader\\ ChoiceLoaderInterface` ` can be used in different fields with more performance
308
+ (reducing N queries to 1).
235
309
236
310
.. include :: /reference/forms/types/options/choice_name.rst.inc
237
311
@@ -250,34 +324,33 @@ choices_as_values
250
324
251
325
The ``choices_as_values `` option was added to keep backward compatibility with the
252
326
*old * way of handling the ``choices `` option. When set to ``false `` (or omitted),
253
- the choice keys are used as the underlying value and the choice values are shown
254
- to the user.
327
+ the choice keys are used as the view value and the choice values are shown
328
+ to the user as label .
255
329
256
330
* Before 2.7 (and deprecated now)::
257
331
258
- $builder->add('gender ', 'choice', array(
259
- // Shows "Male " to the user, returns "m " when selected
260
- 'choices' => array('m ' => 'Male ', 'f ' => 'Female '),
332
+ $builder->add('agree ', 'choice', array(
333
+ // Shows "Yes " to the user, returns "1 " when selected
334
+ 'choices' => array('1 ' => 'Yes ', '0 ' => 'No '),
261
335
// before 2.7, this option didn't actually exist, but the
262
336
// behavior was equivalent to setting this to false in 2.7.
263
337
'choices_as_values' => false,
264
338
));
265
339
266
340
* Since 2.7::
267
341
268
- $builder->add('gender ', 'choice', array(
269
- // Shows "Male " to the user, returns "m " when selected
270
- 'choices' => array('Male ' => 'm ', 'Female ' => 'f '),
342
+ $builder->add('agree ', 'choice', array(
343
+ // Shows "Yes " to the user, returns "1 " when selected
344
+ 'choices' => array('Yes ' => '1 ', 'No ' => '0 '),
271
345
'choices_as_values' => true,
272
346
));
273
347
274
- In Symfony 3.0, the ``choices_as_values `` option doesn't exist, but the ``choice ``
275
- type behaves as if it were set to true:
348
+ As of Symfony 3.0, the ``choices_as_values `` option is ``true `` by default:
276
349
277
350
* Default for 3.0::
278
351
279
- $builder->add('gender ', 'choice ', array(
280
- 'choices' => array('Male ' => 'm ', 'Female ' => 'f '),
352
+ $builder->add('agree ', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType ', array(
353
+ 'choices' => array('Yes ' => '1 ', 'No ' => '0 '),
281
354
));
282
355
283
356
.. include :: /reference/forms/types/options/expanded.rst.inc
0 commit comments