From 9fc18e7d3c0e603ff43bcd0d06484712a7a808c4 Mon Sep 17 00:00:00 2001 From: Jules Pietri Date: Tue, 18 Feb 2020 20:35:09 +0100 Subject: [PATCH] [Form] added the new `ChoiceList` class to configure `ChoiceType` options --- reference/forms/types/choice.rst | 31 ++------ .../forms/types/options/choice_attr.rst.inc | 17 +++++ .../forms/types/options/choice_label.rst.inc | 14 ++++ .../forms/types/options/choice_loader.rst.inc | 75 +++++++++++++++++++ .../forms/types/options/choice_name.rst.inc | 16 +++- .../forms/types/options/choice_value.rst.inc | 14 ++++ .../forms/types/options/group_by.rst.inc | 14 ++++ .../types/options/preferred_choices.rst.inc | 14 ++++ 8 files changed, 170 insertions(+), 25 deletions(-) create mode 100644 reference/forms/types/options/choice_loader.rst.inc diff --git a/reference/forms/types/choice.rst b/reference/forms/types/choice.rst index d90173eb2e6..3b4f6bbe7b5 100644 --- a/reference/forms/types/choice.rst +++ b/reference/forms/types/choice.rst @@ -181,6 +181,11 @@ To get fancier, use the `group_by`_ option instead. Field Options ------------- +.. versionadded:: 5.1 + + The :class:`Symfony\\Component\\Form\\ChoiceList\\ChoiceList` class has + been introduced in Symfony 5.1, to help configuring choices options. + choices ~~~~~~~ @@ -211,31 +216,9 @@ correct types will be assigned to the model. .. include:: /reference/forms/types/options/choice_label.rst.inc -choice_loader -~~~~~~~~~~~~~ - -**type**: :class:`Symfony\\Component\\Form\\ChoiceList\\Loader\\ChoiceLoaderInterface` - -The ``choice_loader`` can be used to only partially load the choices in cases where -a fully-loaded list is not necessary. This is only needed in advanced cases and -would replace the ``choices`` option. - -You can use an instance of :class:`Symfony\\Component\\Form\\ChoiceList\\Loader\\CallbackChoiceLoader` -if you want to take advantage of lazy loading:: - - use Symfony\Component\Form\ChoiceList\Loader\CallbackChoiceLoader; - use Symfony\Component\Form\Extension\Core\Type\ChoiceType; - // ... - - $builder->add('constants', ChoiceType::class, [ - 'choice_loader' => new CallbackChoiceLoader(function() { - return StaticClass::getConstants(); - }), - ]); +.. _reference-form-choice-loader: -This will cause the call of ``StaticClass::getConstants()`` to not happen if the -request is redirected and if there is no pre set or submitted data. Otherwise -the choice options would need to be resolved thus triggering the callback. +.. include:: /reference/forms/types/options/choice_loader.rst.inc .. include:: /reference/forms/types/options/choice_name.rst.inc diff --git a/reference/forms/types/options/choice_attr.rst.inc b/reference/forms/types/options/choice_attr.rst.inc index ac149f3999d..1c9f5138d66 100644 --- a/reference/forms/types/options/choice_attr.rst.inc +++ b/reference/forms/types/options/choice_attr.rst.inc @@ -24,3 +24,20 @@ If an array, the keys of the ``choices`` array must be used as keys:: return ['class' => 'attending_'.strtolower($key)]; }, ]); + +.. tip:: + + When defining a custom type, you should use the + :class:`Symfony\\Component\\Form\\ChoiceList\\ChoiceList` class helper:: + + use App\Entity\Category; + use Symfony\Component\Form\ChoiceList\ChoiceList; + + // ... + $builder->add('choices', ChoiceType::class, [ + 'choice_label' => ChoiceList::attr($this, function (?Category $category) { + return $category ? ['data-uuid' => $category->getUuid()] : []; + }), + ]); + + See the :ref:`"choice_loader" option documentation `. diff --git a/reference/forms/types/options/choice_label.rst.inc b/reference/forms/types/options/choice_label.rst.inc index 53cd469b916..6cfac9323ae 100644 --- a/reference/forms/types/options/choice_label.rst.inc +++ b/reference/forms/types/options/choice_label.rst.inc @@ -53,3 +53,17 @@ If your choice values are objects, then ``choice_label`` can also be a If set to ``false``, all the tag labels will be discarded for radio or checkbox inputs. You can also return ``false`` from the callable to discard certain labels. + +.. tip:: + + When defining a custom type, you should use the + :class:`Symfony\\Component\\Form\\ChoiceList\\ChoiceList` class helper:: + + use Symfony\Component\Form\ChoiceList\ChoiceList; + + // ... + $builder->add('choices', ChoiceType::class, [ + 'choice_label' => ChoiceList::label($this, 'displayName'), + ]); + + See the :ref:`"choice_loader" option documentation `. diff --git a/reference/forms/types/options/choice_loader.rst.inc b/reference/forms/types/options/choice_loader.rst.inc new file mode 100644 index 00000000000..35a9e86cd81 --- /dev/null +++ b/reference/forms/types/options/choice_loader.rst.inc @@ -0,0 +1,75 @@ +choice_loader +~~~~~~~~~~~~~ + +**type**: :class:`Symfony\\Component\\Form\\ChoiceList\\Loader\\ChoiceLoaderInterface` + +The ``choice_loader`` can be used instead of ``choices`` option. It allows to +create a list lazily or partially when fetching only the choices for a set of +submitted values (i.e. querying a search engine like ``ElasticSearch`` can be +a heavy process). + +You can use an instance of :class:`Symfony\\Component\\Form\\ChoiceList\\Loader\\CallbackChoiceLoader` +if you want to take advantage of lazy loading:: + + 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(function() { + return StaticClass::getConstants(); + }), + ]); + +This will cause the call of ``StaticClass::getConstants()`` to not happen if the +request is redirected and if there is no pre set or submitted data. Otherwise +the choice options would need to be resolved thus triggering the callback. + +When you're defining a custom choice type that may be reused in many fields +(like entries of a collection) or reused in multiple forms at once, you +should use the :class:`Symfony\\Component\\Form\\ChoiceList\\ChoiceList` +static methods to wrap the loader and make the choice list cacheable for +better performance:: + + use App\Form\ChoiceList\CustomChoiceLoader; + use App\StaticClass; + use Symfony\Component\Form\AbstractType; + use Symfony\Component\Form\ChoiceList\ChoiceList; + use Symfony\Component\Form\Extension\Core\Type\ChoiceType; + use Symfony\Component\OptionsResolver\Options; + use Symfony\Component\OptionsResolver\OptionsResolver; + + class ConstantsType extends AbstractType + { + public static function getExtendedTypes(): iterable + { + return [ChoiceType::class]; + } + + public function configureOptions(OptionsResolver $resolver) + { + $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) { + 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']] + ); + }, + ]); + } + } diff --git a/reference/forms/types/options/choice_name.rst.inc b/reference/forms/types/options/choice_name.rst.inc index a01341b5418..4ec8abb6ffe 100644 --- a/reference/forms/types/options/choice_name.rst.inc +++ b/reference/forms/types/options/choice_name.rst.inc @@ -5,12 +5,26 @@ Controls the internal field name of the choice. You normally don't care about this, but in some advanced cases, you might. For example, this "name" becomes the index -of the choice views in the template and is used as part o the field name +of the choice views in the template and is used as part of the field name attribute. This can be a callable or a property path. See `choice_label`_ for similar usage. By default, the choice key or an incrementing integer may be used (starting at ``0``). +.. tip:: + + When defining a custom type, you should use the + :class:`Symfony\\Component\\Form\\ChoiceList\\ChoiceList` class helper:: + + use Symfony\Component\Form\ChoiceList\ChoiceList; + + // ... + $builder->add('choices', ChoiceType::class, [ + 'choice_name' => ChoiceList::fieldName($this, 'name'), + ]); + + See the :ref:`"choice_loader" option documentation `. + .. caution:: The configured value must be a valid form name. Make sure to only return diff --git a/reference/forms/types/options/choice_value.rst.inc b/reference/forms/types/options/choice_value.rst.inc index a37a36cf299..13bc324cd2a 100644 --- a/reference/forms/types/options/choice_value.rst.inc +++ b/reference/forms/types/options/choice_value.rst.inc @@ -18,3 +18,17 @@ for each choice or ``null`` in a placeholder is used, which you need to handle:: 'choice_value' => function (?MyOptionEntity $entity) { return $entity ? $entity->getId() : ''; }, + +.. tip:: + + When defining a custom type, you should use the + :class:`Symfony\\Component\\Form\\ChoiceList\\ChoiceList` class helper:: + + use Symfony\Component\Form\ChoiceList\ChoiceList; + + // ... + $builder->add('choices', ChoiceType::class, [ + 'choice_value' => ChoiceList::value($this, 'uuid'), + ]); + + See the :ref:`"choice_loader" option documentation `. diff --git a/reference/forms/types/options/group_by.rst.inc b/reference/forms/types/options/group_by.rst.inc index b649793e9ff..ca747683662 100644 --- a/reference/forms/types/options/group_by.rst.inc +++ b/reference/forms/types/options/group_by.rst.inc @@ -40,3 +40,17 @@ a "Later" ````: If you return ``null``, the option won't be grouped. You can also pass a string "property path" that will be called to get the group. See the `choice_label`_ for details about using a property path. + +.. tip:: + + When defining a custom type, you should use the + :class:`Symfony\\Component\\Form\\ChoiceList\\ChoiceList` class helper:: + + use Symfony\Component\Form\ChoiceList\ChoiceList; + + // ... + $builder->add('choices', ChoiceType::class, [ + 'group_by' => ChoiceList::groupBy($this, 'category'), + ]); + + See the :ref:`"choice_loader" option documentation `. diff --git a/reference/forms/types/options/preferred_choices.rst.inc b/reference/forms/types/options/preferred_choices.rst.inc index 36a800c1c9b..bffb021f864 100644 --- a/reference/forms/types/options/preferred_choices.rst.inc +++ b/reference/forms/types/options/preferred_choices.rst.inc @@ -63,3 +63,17 @@ when rendering the field: widget($form['publishAt'], [ 'separator' => '=====', ]) ?> + +.. tip:: + + When defining a custom type, you should use the + :class:`Symfony\\Component\\Form\\ChoiceList\\ChoiceList` class helper:: + + use Symfony\Component\Form\ChoiceList\ChoiceList; + + // ... + $builder->add('choices', ChoiceType::class, [ + 'preferred_choices' => ChoiceList::preferred($this, 'taggedAsFavorite'), + ]); + + See the :ref:`"choice_loader" option documentation `. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy