marcio
marcio

Reputation: 9

Symfony2 form choice checkbox doesn't function

I am trying to make some input checkboxes for my configuration module but choice widget isn't working.

So it works only for radio buttons and menu while for multiple menu and checkboxes I have an error:

Expected argument of type "array", "string" given

The code:

$builder->add('value', 'choice', array
                    (
                        'label' => $this->item->getTitle() . ':',
                        'choices' => array('1' => 'one', '2' => 'two'),
                        'multiple' => true,
                        'expanded' => true,
                                           )
        );

This is an example.

EDIT:

So in my configuration bundle I have a lot of different types of input for describe better an configuration value, for each of this I render the proper widget. I don't have any problems with all widgets except checkbox and menu multiple for choice widget, radio and menu works fine.

This is the form class:

class ItemType extends AbstractType {

/**
 * The configuration item (one row's data)
 * @var Item
 */
private $item;


/**
 * Widget type
 * @var string
 */
private $widget;


/**
 * widget's options
 * @var array
 */
private $options = array();

/**
 * Class constructor
 * 
 * @param Item $item The configuration item (one row's data)
 * @return void
 */
public function __construct(Item $item, $widget, $options = array()) 
{
    $this->item = $item;
    $this->widget = $widget;
    $this->options = $options;
}

/**
 * Builds the form
 * 
 * @param FormBuilder $builder The form builder
 * @param array $options The options
 * @return void
 * 
 * @see Symfony\Component\Form\AbstractType::buildForm()
 */
public function buildForm(FormBuilder $builder, array $options) 
{
    $fieldOptions = array('attr' => array('class' => 'text'));

    switch($this->widget)
    {
        case 'menu':
        case 'MultipleMenu':
        case 'radio':
        case 'checkbox':
                        $choices = $this->getWidgetOptions($this->options['values'], ':');

                        if($this->widget == 'radio')
                        {
                            $fieldOptions = array('attr' => array('class' => 'configurationFormRadioButton'));
                        }

                        $builder->add('value', 'choice', array_merge(
                                                                        $fieldOptions, 
                                                                        $this->getChoiceOption($this->widget), 
                                                                        array
                                                                        (
                                                                            'label' => $this->item->getTitle() . ':',
                                                                            'choices' => $choices
                                                                        )
                                                                    )
                                    );
                        break;

        case 'text':
        case 'password':
        case 'email':
        case 'url':
        case 'number':
        case 'integer':
        case 'textarea':
                        $builder->add('value', $this->widget, array_merge($fieldOptions, array('label' => $this->item->getTitle() . ':')));
                        break;

        case 'date':
                        $builder->add('value', $this->widget, array_merge(
                                                                            array(
                                                                                    'attr' => array('class' => 'date'),
                                                                                    'label' => $this->item->getTitle() . ':',
                                                                                    'input' => 'string',
                                                                                    'widget' => 'single_text'
                                                                                ),
                                                                            $this->getWidgetOptions($this->options['options'], '=')
                                                                         )
                                    );
                        break;

        case 'datetime':
                            $builder->add('value', $this->widget, array_merge( 
                                                                                array(
                                                                                        'attr' => array('class' => 'date'),
                                                                                        'label' => $this->item->getTitle() . ':',
                                                                                        'input' => 'string',
                                                                                        'date_widget' => 'choice',
                                                                                        'time_widget' => 'choice'
                                                                                    ),
                                                                                $this->getWidgetOptions($this->options['options'], '=')
                                                                            )
                                        );
                            break;


        case 'time':
                            $builder->add('value', $this->widget, array_merge(
                                                                                array(
                                                                                        'attr' => array('class' => 'date'),
                                                                                        'label' => $this->item->getTitle() . ':',
                                                                                        'input' => 'string',
                                                                                        'widget' => 'choice'
                                                                                    ),
                                                                                $this->getWidgetOptions($this->options['options'], '=')
                                                                            )
                                        );
                            break;

        case 'datepicker':
                            $builder->add('value', 'text', array_merge(
                                                                        array(
                                                                                'attr' => array('class' => 'datepicker text'),
                                                                                'label' => $this->item->getTitle() . ':'
                                                                            ),
                                                                        $this->getWidgetOptions($this->options['options'], '=')
                                                                     )
                                        );
                            break;
    }

    $builder->setData($this->item);
}

/**
 * Returns the name of this type
 * @return string
 */
public function getName() 
{
    return 'configurationItemForm';
}


/**
 * Set widget type for field
 * @return array
 */
private function getChoiceOption($inputType)
{
    switch($inputType)
    {
        case 'menu':
                    return array('multiple' => false, 'expanded' => false);
                    break;

        case 'MultipleMenu':
                    return array('multiple' => true, 'expanded' => false);
                    break;

        case 'radio':
                    return array('multiple' => false, 'expanded' => true);
                    break;

        case 'checkbox':
                    return array('multiple' => true, 'expanded' => true);
                    break;
    }
}


/**
 * Get widget options from database
 * @return array
 */
private function getWidgetOptions($from, $explodeChar)
{
    $options = array();

    if($from != '')
    {
        $pairs = explode('|', $from);

        foreach($pairs as $pair)
        {
            $values[] = explode($explodeChar, $pair);
            foreach($values as $value)
            {   
                $options[$value[0]] = $value[1];
            }
        }
    }
    return $options;
}
}

Upvotes: 1

Views: 3060

Answers (1)

MDrollette
MDrollette

Reputation: 6927

The code you have here looks fine. The problem appears to be that your object is not returning an array value for the property mapped to the choice field.

For example, if your object was a user and had an array of roles, $user->getRoles() should return an array, but if it returns a string then it will throw an error if you try to map it to a choice field.

You should look into using form events to make your form generation cleaner and easier to debug in situations like this. You can see an example of dynamically generating forms here http://symfony.com/doc/current/cookbook/form/dynamic_form_generation.html

Upvotes: 1

Related Questions