Skip to content

Commit b48c500

Browse files
committed
[Form] added the "choice_filter" option
1 parent df08e97 commit b48c500

File tree

2 files changed

+85
-0
lines changed

2 files changed

+85
-0
lines changed

reference/forms/types/choice.rst

+3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ To use this field, you must specify *either* ``choices`` or ``choice_loader`` op
1414
+-------------+------------------------------------------------------------------------------+
1515
| Options | - `choices`_ |
1616
| | - `choice_attr`_ |
17+
| | - `choice_filter`_ |
1718
| | - `choice_label`_ |
1819
| | - `choice_loader`_ |
1920
| | - `choice_name`_ |
@@ -212,6 +213,8 @@ correct types will be assigned to the model.
212213

213214
.. include:: /reference/forms/types/options/choice_attr.rst.inc
214215

216+
.. include:: /reference/forms/types/options/choice_filter.rst.inc
217+
215218
.. _reference-form-choice-label:
216219

217220
.. include:: /reference/forms/types/options/choice_label.rst.inc
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
``choice_filter``
2+
~~~~~~~~~~~~~~~~~
3+
4+
**type**: ``callable``, ``string`` or :class:`Symfony\\Component\\PropertyAccess\\PropertyPath` **default**: ``null``
5+
6+
.. versionadded:: 5.1
7+
8+
The ``choice_filter`` option has been introduced in Symfony 5.1.
9+
10+
When using predefined choice types from Symfony core or vendor libraries (i.e.
11+
:doc:`CountryType </reference/forms/types/country>`) this option lets you
12+
define a callable that take each choice as only argument and must return
13+
``true`` to keep it or ``false`` to discard it::
14+
15+
// src/Form/Type/AddressType.php
16+
namespace App\Form\Type;
17+
18+
use Symfony\Component\Form\AbstractType;
19+
use Symfony\Component\Form\Extension\Core\Type\CountryType;
20+
use Symfony\Component\Form\FormBuilderInterface;
21+
use Symfony\Component\OptionsResolver\OptionsResolver;
22+
23+
class AddressType extends AbstractType
24+
{
25+
public function configureOptions(OptionsResolver $resolver)
26+
{
27+
$resolver
28+
->setDefaults([
29+
// enable this type to accept a limited set of countries
30+
'allowed_countries' => null,
31+
])
32+
;
33+
}
34+
35+
public function buildForm(FormBuilderInterface $builder, array $options)
36+
{
37+
$allowedCountries = $options['allowed_countries'];
38+
39+
$builder
40+
// ...
41+
->add('country', CountryType::class, [
42+
// if the AddressType "allowed_countries" option is passed,
43+
// use it to create a filter
44+
'choice_filter' => $allowedCountries ? function ($countryCode) use ($allowedCountries) {
45+
return in_array($countryCode, $allowedCountries, true);
46+
} : null,
47+
48+
])
49+
;
50+
}
51+
52+
The option can be a callable or a property path when choices are objects::
53+
54+
// ...
55+
$builder
56+
->add('category', ChoiceType::class, [
57+
// ...
58+
'choice_filter' => 'isSelectable',
59+
])
60+
;
61+
62+
.. tip::
63+
64+
Considering this ``AddressType`` could be an entry of a ``CollectionType``
65+
you should use the :class:`Symfony\\Component\\Form\\ChoiceList\\ChoiceList`
66+
class helper to enable caching::
67+
68+
// src/Form/Type/AddressType.php
69+
// ...
70+
use Symfony\Component\Form\ChoiceList\ChoiceList;
71+
72+
// ...
73+
'choice_filter' => $allowedCountries ? ChoiceList::filter(
74+
// pass the type as first argument
75+
$this,
76+
function ($countryCode) use ($allowedCountries) {
77+
return in_array($countryCode, $allowedCountries, true);
78+
},
79+
// pass the option that makes the filter "vary" to compute a unique hash
80+
$allowedCountries
81+
) : null,
82+
// ...

0 commit comments

Comments
 (0)