0

lets say that i have a simple form like this:

class MyType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('field', 'text');

        // this is select
        $builder->add('field2', 'choice', array(
            'choices' => array(),
            'expanded' => false,
            'multiple' => false,
        ));
    }
}

now i want to update field2 options on form submit. so the flow is:

  1. visit the page with empty form
  2. fill field1 and submit the form
  3. form will 'fail validation' as it is missing value for field2, but this time it ll render the form with options for field2 based on submitted value from field1
  4. value for field2 is selected and together with field1 (filled in step 2) submitted
  5. form validation pass

What i've tried

1.

How to Dynamically Modify Forms Using Form Events

here they discuss how to add new field based on submitted form, but i need to update already existing field. so in event function something like:

$form->get('field2')->**update**('choices', array(1=>'test'));

however i could not figure out how to do this as there is no function **update**

i can re-create field2 in form event like this:

$builder->get('field2')->remove();
$builder->add('field2', 'choice', array(...));

but this doesn't seems right.

2.

getting value of field1 in controller and pass it to my MyType as custom option and based on that either set or not choices on field2 during form creation.

my problem here is, that if i do this, i have to get the value directly from $request->query->get('field1'); and this is wrong. i need to let the form to process request and than get the value via $form->getData()->getField1() so the form has a chance to process my DataTransformer attached to field1

my code in controller is standard code generated by symfony2:

$entity = new Entity();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
$value = $form->getData()->getField1();

and now its too late to pass $value to form builder as the form is already created in createCreateForm()

any idea?

1 Answer 1

0

Can you try to replace, in your first tried solution, this block :

$builder->get('field2')->remove();
$builder->add('field2', 'choice', array(...));

By this one :

$builder->remove('field2');
$builder->add('field2', 'choice', array(...));
5
  • hm i dont have a problem with that piece of code (either version yours or mine) the main question is, if this is the correct or the only solution? as it does not seems right to me
    – gondo
    Jan 13, 2014 at 13:47
  • I think it's the only way to do what you need.
    – maphe
    Jan 13, 2014 at 13:55
  • another problem with this solution is field order. if i remove the field im not able to re-add it into the same position, well not without additional bundle
    – gondo
    Jan 13, 2014 at 15:45
  • Maybe you can, using a custom field type that you always add on your root form. And adding your form event on this sub-type, which add or not the choice field. The order won't change but it adds a child level to your form.
    – maphe
    Jan 13, 2014 at 17:03
  • 1
    Does the field need to be removed? I always remember simply adding the field like normal (in buildForm) and then adding it again (with the updated data) in the event listener. "Re-adding" it actually just overrides. I could be wrong (I don't have it in front of me), but I always thought you could just overwrite the field in the listener. It's definitely true that you won't "modify" the choices, you'll add an entirely new field and overwrite the original :).
    – weaverryan
    Jan 14, 2014 at 3:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.