Validating dynamically loaded choices in Symfony 2 Validating dynamically loaded choices in Symfony 2 symfony symfony

Validating dynamically loaded choices in Symfony 2


To do the trick you need to overwrite the sub_choice field before submitting the form:

public function buildForm(FormBuilderInterface $builder, array $options){    ...    $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {        $parentChoice = $event->getData();        $subChoices = $this->getValidChoicesFor($parentChoice);        $event->getForm()->add('sub_choice', 'choice', [            'label'   => 'Sub Choice',            'choices' => $subChoices,        ]);    });}


this accept any value

 $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {    $data = $event->getData();    if(is_array($data['tags']))$data=array_flip($data['tags']);    else $data = array();    $event->getForm()->add('tags', 'tag', [        'label'   => 'Sub Choice',        'choices' => $data,        'mapped'=>false,        'required'=>false,        'multiple'=>true,    ]);});


Adding an alternate approach for future readers since I had to do a lot of investigation to get my form working. Here is the breakdown:

  1. Adding a "New" option to a dropdown via jquery
  2. If "New" is selected display new form field "Custom Option"
  3. Submit Form
  4. Validate data
  5. Save to database

jquery code for twig:

$(function(){    $(document).ready(function() {        $("[name*='[custom_option]']").parent().parent().hide(); // hide on load        $("[name*='[options]']").append('<option value="new">New</option>'); // add "New" option        $("[name*='[options]']").trigger("chosen:updated");    });    $("[name*='[options]']").change(function() {        var companyGroup = $("[name*='[options]']").val();        if (companyGroup == 'new') { // when new option is selected display text box to enter custom option            $("[name*='[custom_option]']").parent().parent().show();        } else {            $("[name*='[custom_option]']").parent().parent().hide();        }    });});// Here's my Symfony 2.6 form code:    ->add('options', 'entity', [    'class'         => 'Acme\TestBundle\Entity\Options',    'property'      => 'display',    'empty_value'   => 'Select an Option',    'mapped'        => true,    'property_path' => 'options.optionGroup',    'required' => true,])->add('custom_option', 'text', [    'required' => false,    'mapped'   => false,])

To handle the form data we need to use the PRE_SUBMIT form event.

    $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {    $data = $event->getData();    $form = $event->getForm();    if (isset($data['options']) && $data['options'] === 'new') {        $customOption = $data['custom_option'];        // todo: handle this better on your own        if (empty($customOption)) {            $form->addError(new FormError('Please provide a custom option'));            return;        }        // Check for a duplicate option        $matches = $this->doctrine->getRepository('Acme\TestBundle\Entity\Options')->matchByName([$customOption]);        if (count($matches) > 0) {            $form->addError(new FormError('Duplicate option found'));            return;        }        // More validation can be added here        // Creates new option in DB        $newOption = $this->optionsService->createOption($customOption); // return object after persist and flush in service        $data['options'] = $newOption->getOptionId();        $event->setData($data);    }});

Let me know if ya'll have any questions or concerns. I know this might not be the best solution but it works. Thanks!