diff --git a/reference/forms/types/choice.rst b/reference/forms/types/choice.rst index a21c3312416..82036dc3d82 100644 --- a/reference/forms/types/choice.rst +++ b/reference/forms/types/choice.rst @@ -74,8 +74,8 @@ This will create a ``select`` drop-down like this: If the user selects ``No``, the form will return ``false`` for this field. Similarly, if the starting data for this field is ``true``, then ``Yes`` will be auto-selected. -In other words, the **value** of each item is the value you want to get/set in PHP -code, while the **key** is what will be shown to the user. +In other words, the **choice** of each item is the value you want to get/set in PHP +code, while the **key** is the **label** that will be shown to the user. Advanced Example (with Objects!) -------------------------------- @@ -95,23 +95,40 @@ method:: new Category('Cat3'), new Category('Cat4'), ], - 'choice_label' => function(Category $category, $key, $value) { - return strtoupper($category->getName()); + // "name" is a property path, meaning Symfony will look for a public + // property or a public method like "getName()" to define the input + // string value that will be submitted by the form + 'choice_value' => 'name', + // a callback to return the label for a given choice + // if a placeholder is used, its empty value (null) may be passed but + // its label is defined by its own "placeholder" option + 'choice_label' => function(?Category $category) { + return $category ? strtoupper($category->getName()) : ''; }, - 'choice_attr' => function(Category $category, $key, $value) { - return ['class' => 'category_'.strtolower($category->getName())]; + // returns the html attributes for each option input (may be radio/checkbox) + 'choice_attr' => function(?Category $category) { + return $category ? ['class' => 'category_'.strtolower($category->getName())] : []; }, - 'group_by' => function(Category $category, $key, $value) { + // every option can use a string property path or any callable that get + // passed each choice as argument, but it may not be needed + 'group_by' => function() { // randomly assign things into 2 groups return rand(0, 1) == 1 ? 'Group A' : 'Group B'; }, - 'preferred_choices' => function(Category $category, $key, $value) { - return $category->getName() == 'Cat2' || $category->getName() == 'Cat3'; + // a callback to return whether a category is preferred + 'preferred_choices' => function(?Category $category) { + return $category && 100 < $category->getArticleCounts(); }, ]); -You can also customize the `choice_name`_ and `choice_value`_ of each choice if -you need further HTML customization. +You can also customize the `choice_name`_ of each choice. You can learn more +about all of these options in the sections below. + +.. caution:: + + The *placeholder* is a specific field, when the choices are optional the + first item in the list must be empty, so the user can unselect. + Be sure to always handle the empty choice ``null`` when using callbacks. .. _forms-reference-choice-tags: @@ -151,7 +168,7 @@ by passing a multi-dimensional ``choices`` array:: .. image:: /_images/reference/form/choice-example4.png :align: center -To get fancier, use the `group_by`_ option. +To get fancier, use the `group_by`_ option instead. Field Options ------------- @@ -169,7 +186,10 @@ is the item's label and the array value is the item's value:: // ... $builder->add('inStock', ChoiceType::class, [ - 'choices' => ['In Stock' => true, 'Out of Stock' => false], + 'choices' => [ + 'In Stock' => true, + 'Out of Stock' => false, + ], ]); If there are choice values that are not scalar or the stringified diff --git a/reference/forms/types/options/choice_attr.rst.inc b/reference/forms/types/options/choice_attr.rst.inc index 4a91d6dacc8..ac149f3999d 100644 --- a/reference/forms/types/options/choice_attr.rst.inc +++ b/reference/forms/types/options/choice_attr.rst.inc @@ -1,7 +1,7 @@ ``choice_attr`` ~~~~~~~~~~~~~~~ -**type**: ``array``, ``callable`` or ``string`` **default**: ``[]`` +**type**: ``array``, ``callable``, ``string`` or :class:`Symfony\\Component\\PropertyAccess\\PropertyPath` **default**: ``[]`` Use this to add additional HTML attributes to each choice. This can be an associative array where the keys match the choice keys and the values diff --git a/reference/forms/types/options/choice_label.rst.inc b/reference/forms/types/options/choice_label.rst.inc index 49eb1c20dd7..53cd469b916 100644 --- a/reference/forms/types/options/choice_label.rst.inc +++ b/reference/forms/types/options/choice_label.rst.inc @@ -1,9 +1,9 @@ ``choice_label`` ~~~~~~~~~~~~~~~~ -**type**: ``string``, ``callable`` or ``false`` **default**: ``null`` +**type**: ``string``, ``callable``, ``false`` or :class:`Symfony\\Component\\PropertyAccess\\PropertyPath` **default**: ``null`` -Normally, the array key of each item in the ``choices`` option is used as the +By default, the array key of each item in the ``choices`` option is used as the text that's shown to the user. The ``choice_label`` option allows you to take more control:: diff --git a/reference/forms/types/options/choice_name.rst.inc b/reference/forms/types/options/choice_name.rst.inc index a9cd27e4f52..a01341b5418 100644 --- a/reference/forms/types/options/choice_name.rst.inc +++ b/reference/forms/types/options/choice_name.rst.inc @@ -1,14 +1,15 @@ ``choice_name`` ~~~~~~~~~~~~~~~ -**type**: ``callable`` or ``string`` **default**: ``null`` +**type**: ``callable``, ``string`` or :class:`Symfony\\Component\\PropertyAccess\\PropertyPath` **default**: ``null`` 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. +of the choice views in the template and is used as part o the field name +attribute. This can be a callable or a property path. See `choice_label`_ for similar usage. -If ``null`` is used, an incrementing integer is used as the name. +By default, the choice key or an incrementing integer may be used (starting at ``0``). .. caution:: diff --git a/reference/forms/types/options/choice_value.rst.inc b/reference/forms/types/options/choice_value.rst.inc index a71ba9cdd36..a37a36cf299 100644 --- a/reference/forms/types/options/choice_value.rst.inc +++ b/reference/forms/types/options/choice_value.rst.inc @@ -1,28 +1,20 @@ ``choice_value`` ~~~~~~~~~~~~~~~~ -**type**: ``callable`` or ``string`` **default**: ``null`` +**type**: ``callable``, ``string`` or :class:`Symfony\\Component\\PropertyAccess\\PropertyPath` **default**: ``null`` Returns the string "value" for each choice, which must be unique across all choices. This is used in the ``value`` attribute in HTML and submitted in the POST/PUT requests. You don't normally need to worry about this, but it might be handy when processing an API request (since you can configure the value that will be sent in the API request). -This can be a callable or a property path. If ``null`` is given, an incrementing -integer is used as the value. +This can be a callable or a property path. By default, the choices are used if they +can be casted to strings. Otherwise an incrementing integer is used (starting at ``0``). If you pass a callable, it will receive one argument: the choice itself. When using the :doc:`/reference/forms/types/entity`, the argument will be the entity object -for each choice or ``null`` in some cases, which you need to handle:: +for each choice or ``null`` in a placeholder is used, which you need to handle:: - 'choice_value' => function (MyOptionEntity $entity = null) { + 'choice_value' => function (?MyOptionEntity $entity) { return $entity ? $entity->getId() : ''; }, - -.. caution:: - - In Symfony 2.7, there was a small backwards-compatibility break with how the - ``value`` attribute of options is generated. This is not a problem unless you - rely on the option values in JavaScript. See `issue #14825`_ for details. - -.. _`issue #14825`: https://github.com/symfony/symfony/pull/14825 diff --git a/reference/forms/types/options/group_by.rst.inc b/reference/forms/types/options/group_by.rst.inc index f8ce4aea36d..b649793e9ff 100644 --- a/reference/forms/types/options/group_by.rst.inc +++ b/reference/forms/types/options/group_by.rst.inc @@ -1,7 +1,7 @@ ``group_by`` ~~~~~~~~~~~~ -**type**: ``string`` or ``callable`` **default**: ``null`` +**type**: ``string``, ``callable`` or :class:`Symfony\\Component\\PropertyAccess\\PropertyPath` **default**: ``null`` You can group the ``