Symfony Choice type with disabled options

Flo Schild picture Flo Schild · Jul 21, 2015 · Viewed 16.2k times · Source

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 ?

Answer

Jacer Omri picture Jacer Omri · Dec 30, 2015

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'] : [];
    },
...