How to add an Event Listener to a dynamically added field using Symfony Forms

Chase picture Chase · Aug 18, 2014 · Viewed 9.9k times · Source

I am using event listeners to dynamically modify a form. I want to add another event listener to a field that was added dynamically. Im not sure how to accomplish this.

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('first_field','choice',array(
        'choices'=>array('1'=>'First Choice','2'=>'Second Choice')
    ));

    $builder->addEventListener(FormEvents::PRE_SET_DATA, array($this, 'preSetData'));
    $builder->get('first_field')->addEventListener(FormEvents::POST_SUBMIT, array($this, 'postSubmit'));
}

public function preSetData(FormEvent $event)
{
    $form = $event->getForm();
    $form->add('second_field','choice',array(
        'choices'=>array('1'=>'First Choice','2'=>'Second Choice')
    ));
    //Some how add an event listener to this field

}

public function postSubmit(FormEvent $event)
{
    $form = $event->getForm()->getParent();
    $form->add('second_field','choice',array(
        'choices'=>array('1'=>'First Choice','2'=>'Second Choice')
    ));
    //Some how add an event listener to this field
}

I have trie just using the $builder in the buildForm function to add the event listener to the second_field but because the field doesnt exist when the form is initially generated it throws an error.

If i try and add the new event listener inside the first event listener by doing:

$form->get('second_field')->addEventListener(...)

Then i get the error:

Call to undefined method Symfony\Component\Form\Form::addEventListener() 

Any suggestions would be welcome.

Answer

Lev Semin picture Lev Semin · Apr 19, 2015

If, is it actually.

FormInterface does't have the addEventListener method, but FormBuilderIntreface have it. If you want to add any listener, you should to create form field by form builder.

For example:

   // create builder for field
   $builder = $form->getConfig()->getFormFactory()->createNamedBuilder($name, $type, null, array(
       /** any options **/
       'auto_initialize'=>false // it's important!!!
   ));
   // now you can add listener
   $builder->addEventListener(FormEvents::POST_SUBMIT, $yourCallbackHere)

   // and only now you can add field to form  
   $form->add($builder->getForm());