2

I have a form widget of type "choice" which is being displayed as a list of many checkboxes. Everything works great. So to stress it out: there is ONE widget, with MANY checkboxes (and NOT several checkbox widgets).

Now, I want to disable some of those checkboxes. The data for that is avaliable in the $options-Array.

Here is the buildForm()-function of my FooType.php

...
public function buildForm(FormBuilderInterface $builder, array $options)
{
  $builder
    ->add('foo', 'choice', array('choices'  => $options['choiceArray']['id'],
      'multiple' => true,
      'expanded' => true,
      'disabled' => $options['choiceArray']['disabled'] // does not work (needs a boolean)
      'data'     => $options['choiceArray']['checked'], // works
      'attr'     => array('class' => 'checkbox')))
  ;
}
...

My Twig-template looks like this:

{% for foo in fooForm %}

    <dd>{{ form_widget(foo) }}</dd>

{% endfor %}

I can only disable ALL the checkboxes (by setting 'disabled' => true in buildForm). And passing an array there does not work (as commented in the snippet).

How can I disable some selected checkboxed (stored in $options['choiceArray']['disabled']) of my choice widget?

Chris
  • 321
  • 1
  • 4
  • 14
  • 3
    The Symfony EventSubscriber can help you http://stackoverflow.com/questions/12642473/symfony2-checkbox-choice-field-disable-one-checkbox – Milos Cuculovic Aug 18 '13 at 14:01
  • @Milos: Thank you for your helpful comment! Using an EventSubscriber seems to be the solution, but... it is very complicated to implement. Since I am a Symfony2-novice, I would really appreciate some help. Thanks in advance for any further hints and snippets! [Symfony2 Dynamic Forms](http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html) – Chris Aug 18 '13 at 16:28
  • The EventSubscriber is only relevant if you want to determine which options to disable based on current values in your object. It's not going to help you in setting attributes on individual option elements. This is a common request with no easy solution. You need to either make your form choice object or supply your own twig template. Neither solutions are easy nor do I know of any good examples. JavaScript might be your best bet here. – Cerad Aug 18 '13 at 18:02
  • @Cerad: Thank you! And: yep, I went the JavaScript-way... and posted my solution in detail. – Chris Aug 18 '13 at 18:04
  • [This related thread](http://stackoverflow.com/questions/14344639/symfony-2form-how-to-disable-specific-item-in-form-choice-type?rq=1) actually shows exactly my problem and solves it... BUT: it does not work in Symfony 2.3 anymore! – Chris Aug 18 '13 at 20:15

2 Answers2

1

I have solved the problem using JQuery.

  • in my FooType.php I stringify the Array of fields that should be disabled.
  • I pass that string in the buildForm()-Function via a hidden field to the template
  • there I use JQuery to split the string again into IDs and process disable the checkboxes and grey out the label

Here is the PHP-Code (FooType.php):

...
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $disabledCount  = sizeof($options['choiceArray']['disabled']);
    $disabledString = '';

    for ($i = 0; $i < $disabledCount; $i++)
    {
        $disabledString .= $options['choiceArray']['disabled'][$i];

        if ($i < $disabledCount-1)
        {
            $disabledString .= '|';
        }
    }



    $builder
        ->add('foo', 'choice', array('choices'  => $options['choiceArray']['id'],
                                               'multiple' => true,
                                               'expanded' => true,
                                               'data'     => $options['choiceArray']['checked'],
                                               'attr'     => array('class' => 'checkbox')))
        ->add('foo_disabled', 'hidden', array('data' => $disabledString))
    ;
}
...

Here is the JavaScript part (Twig-template):

function disableModule()
{
    var disabledString = $('#foo_disabled').val();

    var disabledArray = disabledString.split('|');

    $.each( disabledArray, function( disKey, disVal )
    {
        // deactivate checkboxes
        $('input[id="'+idCurrent+'"]').attr("disabled", true);

        // grey out label for checkboxes
        $('label[for="'+idCurrent+'"]').attr("style", "color: gray;");
    });
}

In my Entity/Foo.php I had to add the property "foo_disabled" of type string with setter and getter methods.

Chris
  • 321
  • 1
  • 4
  • 14
0

This page is first on Goole search results for 'twig checkbox checked and disabled' To set some checkbox inputs checked or/and disabled in twig, one could use choice_attr

public function buildForm(FormBuilderInterface $builder, array $options): void
{
    $builder
        ->add('email', EmailType::class, ['label'=>'Login: '])
        ->add('roles', ChoiceType::class, [
            'label'=>'Role: ',
            'multiple'=>true,
            'expanded'=>true,
            'choices'=>['User'=>'ROLE_USER','Admin'=>'ROLE_ADMIN'],
            'choice_attr'=> [
                'User' => ['disabled'=>'disabled', 'checked'=>'checked'],
                ]
            ])
        ->add('password', PasswordType::class, ['label'=>'Password: '])
        ->add('register', SubmitType::class, ['label' => 'Register'])
    ;
}

In this example I set checked and disabled checkbox for ROLE_USER as this is default role.