Search code examples
phpsymfonysymfony-forms

How to disable specific item in form choice type?


I have a form with choice field of entities from database:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('categories', 'document', array(
        'class' => 'Acme\DemoBundle\Document\Category',
        'property' => 'name',
        'multiple' => true,
        'expanded' => true,
        'empty_value' => false
    ));
}

This form will produce the list of checkboxes and will be rendered as:

[ ] Category 1
[ ] Category 2
[ ] Category 3

I want to disable some of the items by value in this list but I don't know where I should intercept choice field items to do that.

Does anybody know an solution?


Solution

  • Just handled it with finishView and PRE_BIND event listener.

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('categories', 'document', array(
            'class' => 'Acme\DemoBundle\Document\Category',
            'property' => 'name',
            'multiple' => true,
            'expanded' => true,
            'empty_value' => false
        ));
    
        $builder->addEventListener(FormEvents::PRE_BIND, function (FormEvent $event) {
            if (!$ids = $this->getNonEmptyCategoryIds()) {
                return;
            }
    
            $data = $event->getData();
    
            if (!isset($data['categories'])) {
                $data['categories'] = $ids;
            } else {
                $data['categories'] = array_unique(array_merge($data['categories'], $ids));
            }
    
            $event->setData($data);
        });
    }
    
    ...
    
    public function finishView(FormView $view, FormInterface $form, array $options)
    {
        if (!$ids = $this->getNonEmptyCategoryIds()) {
            return;
        }
    
        foreach ($view->children['categories']->children as $category) {
            if (in_array($category->vars['value'], $ids, true)) {
                $category->vars['attr']['disabled'] = 'disabled';
                $category->vars['checked'] = true;
            }
        }
    }