ReynierPM
ReynierPM

Reputation: 18690

How do I send "extra" data to a Symfony 3.2.x form using FormBuilder?

I have the following method in a Symfony 3.2.7 controller:

public function updateAction(Request $request)
{
    $em        = $this->getDoctrine()->getManager();
    // this is the original entity without modified values
    $entity    = $em->getRepository('QuoteBundle:Quote')->find($request->query->get('id'));

    // the entity passed to the form has the values modified coming from the request    
    $form = $this->createForm(CFProgramLevelQuoteType::class, $entity);
    ...
}

And this is the form:

class CFProgramLevelQuoteType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('CFProgramLevel', EntityType::class, [
                'class'         => 'QuoteBundle:CFProgramLevel',
                'choice_label'  => 'description',
                'placeholder'   => 'Please select a program',
            ]);
    }
    ...
}

I will use a Query Builder to filter some values from QuoteBundle:CFProgramLevel so I need to get the unmodified ID from the $entity and send it to the form. This is the solution I have in mind so far:

public function updateAction(Request $request)
{
    $em        = $this->getDoctrine()->getManager();
    $entity    = $em->getRepository('QuoteBundle:Quote')->find($request->query->get('id'));
    $entity_id = $entity->getCfProgramLevel()->getcfProgramLevelId();   
    $form = $this->createForm(CFProgramLevelQuoteType::class, $entity);
    ...
}

But how I can pass that entity_id to the form and used it there? If there is a better way to achieve this I am open to hear ideas. I couldn't find anything helpful in Google so any help is appreciated.

Update

Trying the solution provided in the answer below I couldn't get it to work either:

// controller
$form = $this->createForm(CFProgramLevelQuoteType::class, $entity, ['entity_id' => $entity_id]);

// form
public function buildForm(FormBuilderInterface $builder, array $options)
{
    dump($options);
    die();
    ...
}

public function setDefaultOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(['data_class' => Quote::class, 'entity_id' => null]);
    $resolver->setRequired('entity_id');
}

The option "entity_id" does not exist. Defined options are: "action", "allow_extra_fields", "attr", "auto_initialize", "block_name", "by_reference", "compound", "constraints", "csrf_field_name", "csrf_message", "csrf_protection", "csrf_token_id", "csrf_token_manager", "data", "data_class", "disabled", "empty_data", "error_bubbling", "error_mapping", "extra_fields_message", "inherit_data", "invalid_message", "invalid_message_parameters", "label", "label_attr", "label_format", "mapped", "method", "post_max_size_message", "property_path", "required", "translation_domain", "trim", "upload_max_size_message", "validation_groups".

Upvotes: 0

Views: 3684

Answers (3)

xong
xong

Reputation: 350

To pass extra data to a form you can use OptionsResolver::setDefined.

// App\Form\SomeFormType
public function configureOptions(OptionsResolver $resolver): void
{
    $resolver->setDefined('foo');
}

You can pass data in the Controller like this:

// Controller
$this->createForm(SomeFormType::class, $entity, ['foo' => $data]);

To use the passed data just access the defined key:

// App\Form\SomeFormType
public function buildForm(FormBuilderInterface $builder, array $options): void
{
    // $options['foo']
}

Upvotes: 0

Starspire
Starspire

Reputation: 272

This is fully working example (very similar to @striker also). Please check carefully if you haven't got any misspellings. Otherwise try php bin/console cache:clear

controller action:

public function testAction(Request $request)
{
    $form = $this->createForm(TestType::class, null, [
        'option1' => 6
    ]);
    return $this->render('default/test.html.twig',[
        'form' => $form->createView()
    ]);
}

TestType.php:

class TestType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('test', IntegerType::class, [
            'data' => $options['option1']
        ]);
    }

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setRequired('option1');
    }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'appbundle_test';
    }
}

Upvotes: 1

striker
striker

Reputation: 1263

You can create your own custom options for form type like described on http://symfony.com/doc/current/form/create_custom_field_type.html#defining-the-field-type

class CFProgramLevelQuoteType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        //$options['entity_id'] contains your id
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setRequired('entity_id');
    }
}

Pass entity_id:

$form = $this->createForm(CFProgramLevelQuoteType::class, $entity, [
    'entity_id' => $entity_id
]);

Upvotes: 3

Related Questions