Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to bind entity with createNamedBuilder()?

Tags:

php

symfony

I need to have two different forms (but using the same entity) on one page. To do so, I used createNamedBuilder():

$cover = $this->get('form.factory')->createNamedBuilder('cover')
    ->add('file')
    ->getForm();

$data = $this->get('form.factory')->createNamedBuilder('data')
    ->add('name','text')
    ->getForm();

My problem is, how can I bind my entity to it? When I use createFormBuilder() it goes like

$game = new Game;
$form = $this->createFormBuilder($game);

If I try to use createFormBuilder like this:

    $cover = $this->createFormBuilder($game)
        ->add('file')
        ->getForm();

    $data = $this->createFormBuilder($game)
        ->add('name')
        ->getForm();

Using the secound form results in "This form should not contain extra fields." notice.

like image 877
Tomek Buszewski Avatar asked Sep 06 '25 03:09

Tomek Buszewski


2 Answers

According to the API docs, the third parameter of createNamedBuilder can be used to pass in an entity.

Your code should look like this:

$game = new Game;

$cover = $this->get('form.factory')->createNamedBuilder('cover', 'form', $game)
    ->add('file')
    ->getForm();

$data = $this->get('form.factory')->createNamedBuilder('data', 'form', $game)
    ->add('name','text')
    ->getForm();

(Note that the position of the first and second parameters are swapped if you happen to still be using Symfony 2.0.)

like image 184
Clamburger Avatar answered Sep 09 '25 19:09

Clamburger


In Symfony 2.8/3.0 this has changed a bit and if you have a form that you want to bind other entities to then see my answer here:

Passing data to buildForm() in Symfony 2.8/3.0

In case anyone is using a createNamedBuilder or createNamed functions from form.factory service here's the snippet on how to set and save the data using it. You cannot use the data field (leave that null) and you have to set the passed data/entities as $options value.

I also incorporated @sarahg instructions about using setAllowedTypes() and setRequired() options and it seems to work fine but you first need to define field with setDefined()

Also inside the form if you need the data to be set remember to add it to data field.

In Controller I am using getBlockPrefix as getName was deprecated in 2.8/3.0

Controller

/*
* @var $builder Symfony\Component\Form\FormBuilderInterface
*/

$formTicket = $this->get('form.factory')->
              createNamed(
                  $tasksPerformedForm->getBlockPrefix(),
                  TaskAddToTicket::class,
                  null,
                  array(
                      'ticket' => $ticket
                  )
              );

Form

public function configureOptions(OptionsResolver $resolver)    {
    $resolver->setDefined('ticket');
    $resolver->setRequired('ticket');
    $resolver->addAllowedTypes('ticket', Ticket::class);

    $resolver->setDefaults(array(           
        'translation_domain'=>'AcmeForm',
        'validation_groups'=>array('validation_group_001'),
        'tasks' => null,
        'ticket' => null,
    ));
}

public function buildForm(FormBuilderInterface $builder, array $options)   {

    $this->setTicket($options['ticket']);
    //This is required to set data inside the form!
    $options['data']['ticket']=$options['ticket'];

    $builder

        ->add('ticket',  HiddenType::class, array(
                'data_class'=>'acme\TicketBundle\Entity\Ticket',
            )
        )
...
}
like image 28
Ethernal Avatar answered Sep 09 '25 17:09

Ethernal