14

Is there any way with Symfony to render a <select> form type with disabled options, based on the truthyness of the given choices options ?

I saw this thread (thanks to DonCallisto) about disabling choice expanded options ; However I do not want to have an expanded choice. I would like to keep a select element, with disabled options.

$builder->add('list', 'choice', array(
    'choices' => array(
        array(
            'value' => 1,
            'label' => '1',
            'disabled' => false
        ),
        array(
            'value' => 2,
            'label' => '2',
            'disabled' => false
        ),
        array(
            'value' => 3,
            'label' => '3',
            'disabled' => true
        )
    ),
    // Instead of
    // 'choices' => array(
    //     1 => 'Option 1',
    //     2 => 'Option 2',
    //     3 => 'Option 3'
    // )
);

# Which would render to the following element
<select [...]>
    <option value='1'>1</value>
    <option value='2'>2</value>
    <option value='3' disabled='disabled'>3</value>
</select>

I just can't find the way... Is it necessary to build its own field type ?

aynber
  • 22,380
  • 8
  • 50
  • 63
Flo Schild
  • 5,104
  • 4
  • 40
  • 55
  • 1
    possible duplicate of [How to disable specific item in form choice type?](http://stackoverflow.com/questions/14344639/how-to-disable-specific-item-in-form-choice-type) – DonCallisto Jul 21 '15 at 12:14
  • Definitely missed this one, thanks ! I'll read it right know to see if it's the solution I'm looking for :) – Flo Schild Jul 21 '15 at 12:35
  • Finally not a duplicate. the ````expanded```` option create a totally different behaviour between ````checkboxes```` and ````select```` elements. But I'm afraid to understand that the Symfony core currently does not allow this kind of operations. – Flo Schild Jul 21 '15 at 14:17

3 Answers3

40

Since version 2.7, Symfony has introduced a way to set choice attributes using a callable, this is just what you need.

this code is taken from official Symfony documentation

$builder->add('attending', ChoiceType::class, array(
    'choices' => array(
        'Yes' => true,
        'No' => false,
        'Maybe' => null,
    ),
    'choices_as_values' => true,
    'choice_attr' => function($val, $key, $index) {
        // adds a class like attending_yes, attending_no, etc
        return ['class' => 'attending_'.strtolower($key)];
    },
));

you can use the 'choice_attr' and pass a function that will decide wether to add a disabled attribute or not depending on the value, key or index of the choice.

...
    'choice_attr' => function($key, $val, $index) {
        $disabled = false;

        // set disabled to true based on the value, key or index of the choice...

        return $disabled ? ['disabled' => 'disabled'] : [];
    },
...
stollr
  • 6,534
  • 4
  • 43
  • 59
Jacer Omri
  • 1,723
  • 22
  • 37
2

According to the forms layout :

https://github.com/symfony/symfony/blob/2.7/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig

and the choice_widget_collapsed and choice_widget_options,i don't think it's possible directly with the default Choice form of Symfony.

You can try :

  • to build your own Choice form (by extending the existing one and adding parameters to option list, i think it's the best way)
  • to use javascript/jquery to modify the options parameters at load time with the existing Symfony's Choice from
Cedric
  • 535
  • 5
  • 15
  • Hey, thanks a lot, apparently the ChoiceView do not seems to allow an option to be selected... https://github.com/symfony/symfony/blob/2.7/src/Symfony/Component/Form/ChoiceList/View/ChoiceView.php However I would not even understand how to extend a choice type if all the core behing do not allow what I am trying to do :/ Any idea? – Flo Schild Jul 21 '15 at 14:21
  • Extend it as a new form, allow new extra parameters to be held by your form, and create a new layout extending the existing form_div_layout to overwrite the "options" block. See official doc : [http://symfony.com/doc/current/cookbook/form/create_custom_field_type.html](http://symfony.com/doc/current/cookbook/form/create_custom_field_type.html) and [http://symfony.com/doc/current/cookbook/form/form_customization.html](http://symfony.com/doc/current/cookbook/form/form_customization.html) – Cedric Jul 21 '15 at 16:34
0

This is another way to load options from Entity. You can create a new Entity Attending and use it with EntityType.

->add('attending', EntityType::class, [
'class' => Attending::class,
'choice_attr' => function($key, $val, $index) {
    if ($key->getId() == StaticVal) {
      return ['disabled' => 'disabled'];
    }
    return [];
}]

Here StaticVal can be any value that you want to disable it. $key will give you an object value $val will give you a value starting from 0 if you are using the placeholder option.

Bhavin Nakrani
  • 442
  • 3
  • 12