Skip to content

Commit 96d8e4e

Browse files
committed
feature #5876 Symfony 2.7 Form choice option update (aivus, althaus, weaverryan)
This PR was submitted for the 2.8 branch but it was merged into the 2.7 branch instead (closes #5876). Discussion ---------- Symfony 2.7 Form choice option update Hi guys! This replaces #5755 #5847 and should close #5179 (or at least covers most things). | Q | A | ------------- | --- | Doc fix? | yes | New docs? | yes | Applies to | 2.7+ | Fixed tickets | #5179 This is a big change, and I rewrote a lot. If you have time to review, I think it's best to read the published version up platform.sh and check the code for validity. You can see the code in a project that inspired all the examples here: https://github.com/weaverryan/form_choices/tree/finished. Commits ------- b55d170 typo! 70f5e85 tweaks thanks to comments 0ad7b18 fixing wrong image name 69fc3c3 removing scaling on images a2ad990 fixing bad reference 7aa4106 Completely re-working all the choice docs, including screenshots - for 2.7 changes 79c905c changing option order - choice_name and choice_value seem like edge cases 68725e8 Fixed preferred choices example e2dea88 Fixed linebreaking 889f123 Added choices_as_values description [amend] e1f583b Added choices_as_values description d3cf004 Added choice_loader basics 3763f71 Added basic choice type changes fd35e21 Fix docs related with choice form type refactor
2 parents 6b9ade3 + b55d170 commit 96d8e4e

14 files changed

+434
-109
lines changed
28.3 KB
Loading
29.8 KB
Loading
33 KB
Loading
50.5 KB
Loading
39.2 KB
Loading

reference/forms/types/choice.rst

Lines changed: 181 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,30 @@
11
.. index::
22
single: Forms; Fields; choice
33

4-
choice Field Type
5-
=================
4+
choice Field Type (select drop-downs, radio buttons & checkboxes)
5+
=================================================================
66

77
A multi-purpose field used to allow the user to "choose" one or more options.
88
It can be rendered as a ``select`` tag, radio buttons, or checkboxes.
99

10-
To use this field, you must specify *either* the ``choice_list`` or ``choices``
11-
option.
10+
To use this field, you must specify *either* ``choices`` or ``choice_loader`` option.
1211

1312
+-------------+------------------------------------------------------------------------------+
1413
| Rendered as | can be various tags (see below) |
1514
+-------------+------------------------------------------------------------------------------+
1615
| Options | - `choices`_ |
17-
| | - `choice_list`_ |
16+
| | - `choices_as_values`_ |
17+
| | - `choice_loader`_ |
18+
| | - `choice_label`_ |
19+
| | - `choice_attr`_ |
1820
| | - `placeholder`_ |
1921
| | - `expanded`_ |
2022
| | - `multiple`_ |
2123
| | - `preferred_choices`_ |
24+
| | - `group_by`_ |
25+
| | - `choice_value`_ |
26+
| | - `choice_name`_ |
27+
| | - `choice_list`_ (deprecated) |
2228
+-------------+------------------------------------------------------------------------------+
2329
| Overridden | - `compound`_ |
2430
| options | - `empty_data`_ |
@@ -44,37 +50,108 @@ Example Usage
4450
-------------
4551

4652
The easiest way to use this field is to specify the choices directly via
47-
the ``choices`` option. The key of the array becomes the value that's actually
48-
set on your underlying object (e.g. ``m``), while the value is what the
49-
user sees on the form (e.g. ``Male``).
53+
the ``choices`` option::
5054

51-
.. code-block:: php
52-
53-
$builder->add('gender', 'choice', array(
54-
'choices' => array('m' => 'Male', 'f' => 'Female'),
55-
'required' => false,
55+
$builder->add('isAttending', 'choice', array(
56+
'choices' => array(
57+
'Maybe' => null,
58+
'Yes' => true,
59+
'No' => false,
60+
),
61+
// *this line is important*
62+
'choices_as_values' => true,
5663
));
5764

58-
By setting ``multiple`` to true, you can allow the user to choose multiple
59-
values. The widget will be rendered as a multiple ``select`` tag or a series
60-
of checkboxes depending on the ``expanded`` option::
65+
This will create a ``select`` drop-down like this:
6166

62-
$builder->add('availability', 'choice', array(
63-
'choices' => array(
64-
'morning' => 'Morning',
65-
'afternoon' => 'Afternoon',
66-
'evening' => 'Evening',
67-
),
68-
'multiple' => true,
69-
));
67+
.. image:: /images/reference/form/choice-example1.png
68+
:align: center
69+
70+
If the user selects ``No``, the form will return ``false`` for this field. Similarly,
71+
if the starting data for this field is ``true``, then ``Yes`` will be auto-selected.
72+
In other words, the **value** of each item is the value you want to get/set in PHP
73+
code, while the **key** is what will be shown to the user.
74+
75+
.. caution::
7076

71-
You can also use the ``choice_list`` option, which takes an object that
72-
can specify the choices for your widget.
77+
The ``choices_as_values`` *must* be set to ``true`` in all cases. This activates
78+
the "new" choice type API, which was introduced in Symfony 2.7. If you omit this
79+
option (or set it to ``false``), you'll activate the old API, which is deprecated
80+
and will be removed in 3.0. To read about the old API, read an older version of
81+
the docs.
82+
83+
Advanced Example (with Objects!)
84+
--------------------------------
85+
86+
This field has a *lot* of options and most control how the field is displayed. In
87+
this example, the underlying data is some ``Category`` object that has a ``getName()``
88+
method::
89+
90+
$builder
91+
->add('category', 'choice', [
92+
'choices' => [
93+
new Category('Cat1'),
94+
new Category('Cat2'),
95+
new Category('Cat3'),
96+
new Category('Cat4'),
97+
],
98+
'choices_as_values' => true,
99+
'choice_label' => function($val, $key, $index) {
100+
/** @var Category $val */
101+
return strtoupper($val->getName());
102+
},
103+
'choice_attr' => function($val, $key, $index) {
104+
return ['class' => 'category_'.strtolower($val->getName())];
105+
},
106+
'group_by' => function($val, $key, $index) {
107+
// randomly assign things into 2 groups
108+
return rand(0, 1) == 1 ? 'Group A' : 'Group B'
109+
},
110+
'preferred_choices' => function($val, $key, $index) {
111+
return $val->getName() == 'Cat2' || $val->getName() == 'Cat3';
112+
},
113+
]);
114+
115+
You can also customize the `choice_name`_ and `choice_value`_ of each choice if
116+
you need further HTML customization.
73117

74118
.. _forms-reference-choice-tags:
75119

76120
.. include:: /reference/forms/types/options/select_how_rendered.rst.inc
77121

122+
Customizing each Option's Text (Label)
123+
--------------------------------------
124+
125+
Normally, the array key of each item in the ``choices`` option is used as the
126+
text that's shown to the user. But that can be completely customized via the
127+
`choice_label`_ option. Check it out for more details.
128+
129+
.. _form-choices-simple-grouping:
130+
131+
Grouping Options
132+
----------------
133+
134+
You can easily "group" options in a select by passing a multi-dimensional choices array::
135+
136+
$builder->add('stockStatus', 'choice', [
137+
'choices' => [
138+
'Main Statuses' => [
139+
'Yes' => 'stock_yes',
140+
'No' => 'stock_no',
141+
],
142+
'Out of Stock Statuses' => [
143+
'Backordered' => 'stock_backordered',
144+
'Discontinued' => 'stock_discontinued',
145+
]
146+
],
147+
'choices_as_values' => true,
148+
);
149+
150+
.. image:: /images/reference/form/choice-example4.png
151+
:align: center
152+
153+
To get fancier, use the `group_by`_ option.
154+
78155
Field Options
79156
-------------
80157

@@ -85,27 +162,96 @@ choices
85162

86163
This is the most basic way to specify the choices that should be used
87164
by this field. The ``choices`` option is an array, where the array key
88-
is the item value and the array value is the item's label::
165+
is the item's label and the array value is the item's value::
166+
167+
$builder->add('inStock', 'choice', array(
168+
'choices' => array('In Stock' => true, 'Out of Stock' => false),
169+
// always include this
170+
'choices_as_values' => true,
171+
));
172+
173+
choices_as_values
174+
~~~~~~~~~~~~~~~~~
175+
176+
**type**: ``boolean`` **default**: false
177+
178+
.. versionadded:: 2.7
179+
180+
The ``choices_as_values`` option was introduced in Symfony 2.7.
181+
182+
The ``choices_as_values`` option was added to keep backward compatibility with the
183+
*old* way of handling the ``choices`` option. When set to ``false`` (or omitted),
184+
the choice keys are used as the underlying value and the choice values are shown
185+
to the user.
186+
187+
* Before 2.7 (and deprecated now)::
89188

90189
$builder->add('gender', 'choice', array(
91-
'choices' => array('m' => 'Male', 'f' => 'Female'),
190+
// Shows "Male" to the user, returns "m" when selected
191+
'choices' => array('m' => 'Male', 'f' => 'Female'),
192+
// before 2.7, this options didn't actually exist, but the
193+
// behavior was equivalent to setting this to false in 2.7.
194+
'choices_as_values' => false,
92195
));
93196

94-
.. tip::
197+
* Since 2.7::
198+
199+
$builder->add('gender', 'choice', array(
200+
// Shows "Male" to the user, returns "m" when selected
201+
'choices' => array('Male' => 'm', 'Female' => 'f'),
202+
'choices_as_values' => true,
203+
));
204+
205+
In Symfony 3.0, the ``choices_as_values`` option doesn't exist, but the ``choice``
206+
type behaves as if it were set to true:
207+
208+
* Default for 3.0::
209+
210+
$builder->add('gender', 'choice', array(
211+
'choices' => array('Male' => 'm', 'Female' => 'f'),
212+
));
213+
214+
choice_loader
215+
~~~~~~~~~~~~~
216+
217+
.. versionadded:: 2.7
218+
219+
The ``choice_loader`` option was added in Symfony 2.7.
220+
221+
**type**: :class:`Symfony\\Component\\Form\\ChoiceList\\Loader\\ChoiceLoaderInterface`
222+
223+
The ``choice_loader`` can be used to only partially load the choices in cases where
224+
a fully-loaded list is not necessary. This is only needed in advanced cases and
225+
would replace the ``choices`` option.
226+
227+
.. _reference-form-choice-label:
228+
229+
.. include:: /reference/forms/types/options/choice_label.rst.inc
230+
231+
.. include:: /reference/forms/types/options/choice_attr.rst.inc
232+
233+
.. include:: /reference/forms/types/options/placeholder.rst.inc
234+
235+
.. include:: /reference/forms/types/options/expanded.rst.inc
236+
237+
.. include:: /reference/forms/types/options/multiple.rst.inc
238+
239+
.. include:: /reference/forms/types/options/preferred_choices.rst.inc
240+
241+
.. include:: /reference/forms/types/options/group_by.rst.inc
242+
243+
.. include:: /reference/forms/types/options/choice_value.rst.inc
244+
245+
.. include:: /reference/forms/types/options/choice_name.rst.inc
95246

96-
When the values to choose from are not integers or strings (but e.g.
97-
floats or booleans), you should use the `choice_list`_ option instead.
98-
With this option you are able to keep the original data format which
99-
is important to ensure that the user input is validated properly and
100-
useless database updates caused by a data type mismatch are avoided.
101247

102248
choice_list
103249
~~~~~~~~~~~
104250

105251
.. caution::
106252

107253
The ``choice_list`` option of ChoiceType was deprecated in Symfony 2.7.
108-
You should use ``choices`` or ``choice_loader`` now.
254+
You should use `choices`_ or `choice_loader`_ now.
109255

110256
**type**: :class:`Symfony\\Component\\Form\\Extension\\Core\\ChoiceList\\ChoiceListInterface`
111257

@@ -141,14 +287,6 @@ But don't be confused! If ``Full`` is selected (value ``0`` in HTML), ``1``
141287
will be returned in your form. If ``Almost empty`` is selected (value ``2``
142288
in HTML), ``0.1`` will be returned.
143289

144-
.. include:: /reference/forms/types/options/placeholder.rst.inc
145-
146-
.. include:: /reference/forms/types/options/expanded.rst.inc
147-
148-
.. include:: /reference/forms/types/options/multiple.rst.inc
149-
150-
.. include:: /reference/forms/types/options/preferred_choices.rst.inc
151-
152290
Overridden Options
153291
------------------
154292

0 commit comments

Comments
 (0)