8

I would like as for help. I have a form with dropdown list and I need to modify choices based on external input. I guess it should work well with eventListener

$builder->addEventListener(
            FormEvents::PRE_SET_DATA,
            function(FormEvent $event) use($input){
                $form = $event->getForm();

                // get existin form child
                // modify list of choices

            }

All samples I have seen are using FormEvents only to add new field, but I need to modify existing field but I don't know how to access it.

thanks for help

1
  • jros: in what way are you trying to modify it? Do you want to replace it with a different type or just change one of its attributes, or something different? Commented Apr 12, 2013 at 9:28

3 Answers 3

26

While the original question is rather old, let me leave this here in case someone else comes across the need of altering a specific option of a field without having to replicate all options again:

<?php

$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
    $form = $event->getForm();

    // Get configuration & options of specific field
    $config = $form->get('field_to_update')->getConfig();
    $options = $config->getOptions();

    $form->add(
        // Replace original field... 
        'field_to_update',
        $config->getType()->getName(),
        // while keeping the original options... 
        array_replace(
            $options, 
            [
                // replacing specific ones
                'required' => false,
            ]
        )
    );
});

Source: https://github.com/symfony/symfony/issues/8513#issuecomment-21868035

Sign up to request clarification or add additional context in comments.

3 Comments

I had the same issue but with Symfony 3. Instead of $config->getType->getName() use get_class($config->getType()->getInnerType()). This is because Symfony 3 requires the type be the fully qualified class name.
You've just saved my day... Both of you !
Please note this solution does not work if you have a modelTransformer on the field.
3

What you can do is override the original child.

$builder->addEventListener(
        FormEvents::PRE_SET_DATA,
        function(FormEvent $event) use($input){
            $form = $event->getForm();

            $form->add($this->factory->createNamed('name_to_override', 'choice', null,
                 array("choices" => array("choice"=>"value"))
                ));

        }

It worked for me.

NOTE: this will only work in PHP 5.4, as $this in a Closure is not available in PHP 5.3.

1 Comment

In 5.3, put $that = $this; before the callback, use ($that), and change $this->factory to $that->factory.
0

There is a blog post here that works through an entire dynamic form for an entity relationship: http://aulatic.16mb.com/wordpress/2011/08/symfony2-dynamic-forms-an-event-driven-approach/

The Symfony site has this mostly documented too, you just need to write the ajax code and corresponding controller method which is done in the blog post above: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.