3

I have created a custom "status" form type, by extending the choice field (following the tutorial in the cookbook). The choices for the select field are auto populated from parameters that are injected via the service. However, I would like to configure this status field to use a simple or extended set of options, either a simple status list (Inactive, Live) or a more full status list (Inactive, Live, Delete, Deleted).

My code below successfully modifies the $options['choices'] based on my $options['customOptions'], but these changes have no effect on the final select field options that are rendered.

How can you modify a field's choice options from within the formBuilder?

parameters.yml

parameters:
    gutensite_component.options.status:
        0: Inactive
        1: Live
    gutensite_component.options.status_preview:
        2: "Preview Only"
        3: "Live Only (delete on sync)"
    gutensite_component.options.status_delete:
        -1: "Delete (soft)"
        -2: Deleted

services.yml

services:
    gutensite_component.form.type.status:
        class: Gutensite\ComponentBundle\Form\Type\StatusType
        arguments:
            - "%gutensite_component.options.status%"
            - "%gutensite_component.options.status_preview%"
            - "%gutensite_component.options.status_delete%"
        tags:
            - { name: form.type, alias: "status" }

Form Type

class StatusType extends AbstractType
{

    /**
     * $statusChoices are passed in from services.yml that initiates this as a global service
     * @var array
     */
    private $statusChoices;
    private $statusChoicesPreview;
    private $statusChoicesDelete;

    public function __construct(array $statusChoices, array $statusChoicesPreview,
        array $statusChoicesDelete) {
        $this->statusChoices = $statusChoices;
        $this->statusChoicesPreview = $statusChoicesPreview;
        $this->statusChoicesDelete = $statusChoicesDelete;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'customOptions' => array(),
            // By default it will use the simple choices
            'choices' => $this->statusChoices
        ));
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // Set extra choices based on customOptions
        if(!empty($options['customOptions']['showPreview'])) {
            $options['choices'] = $options['choices'] + $this->staftusChoicesPreview;
        }
        if(!empty($options['customOptions']['showDelete'])) {
            $options['choices'] = $options['choices'] + $this->statusChoicesDelete;
        }

        // The $options['choices'] ARE successfully modified and passed to the parent, but
        // have no effect on the options used in the form display

        // Include Regular Choice buildForm
        parent::buildForm($builder, $options);
    }




    public function getParent() {
        return 'choice';
    }

    public function getName() {
        return 'status';
    }

}

controller

$builder->add('status', 'status', array(
    'label'     => 'Status',
    'required'  => TRUE,
    'customOptions' => array(
        'showPreview' => true
    )
));
A.L
  • 10,259
  • 10
  • 67
  • 98
Chadwick Meyer
  • 7,041
  • 7
  • 44
  • 65
  • For people still looking for an answer and landing here use choice loaders: http://stackoverflow.com/questions/35456199/symfony-2-8-dynamic-choicetype-options – Pavel Petrov Jul 22 '16 at 13:37

1 Answers1

0

You can pass an array of choices to a form class from a controller:

In controller:

$myArray = array('0' => 'foo', '1' => 'bar', ...);
...
$form = $this->createForm(new SomeFormType($myArray), ...);

In form class:

class SomeFormType extends AbstractType
{

private $choiceArray;

public __construct($array)
{
    $this->choiceArray = $array;
}

    public function buildForm(FormBuilderInterface $builder, array $options) 
    {
        $builder
            ->add('status', 'choice', array(
                 'choices' => $this->choiceArray,
                  ...
             )
        ...
    }
...
}
geoB
  • 4,578
  • 5
  • 37
  • 70
  • That's very true. However, following the example provided by Symfony (which I followed), where it uses the config parameters and sets them in the setDefaultOptions method, how can I override those defaults? I'd like to understand the form object a bit better, to know how to modify choices dynamically. Thanks! – Chadwick Meyer Dec 15 '14 at 18:29