4

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.

j0k
  • 22,600
  • 28
  • 79
  • 90
Tomek Buszewski
  • 7,659
  • 14
  • 67
  • 112
  • What is the purpose of each form? – Squazic Jan 10 '13 at 18:56
  • 1
    It can be used in a lot of situations, especially when you want to ommit too much "click here to" links, eg. you can eithr log in or register on one page. Here, I want to use image uploading and inserting in database separately, so the user would see the image BEFORE the whole thing would go in to the DB. – Tomek Buszewski Jan 10 '13 at 19:47
  • For using `createFormBuilder`, are you trying to bind the form when no data is passed to it? Can you post more of your controller code? – Squazic Jan 10 '13 at 20:45
  • Actually have you tried multi-step forms? [This bundle](https://github.com/craue/CraueFormFlowBundle/) seems to do what you want pretty well. – Squazic Jan 10 '13 at 21:10
  • I'll propably have to do something on my own. Squazic's bundle is a little too much for my purposes right now. – Tomek Buszewski Jan 11 '13 at 10:05

2 Answers2

2

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.)

Clamburger
  • 617
  • 6
  • 24
2

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',
            )
        )
...
}
Community
  • 1
  • 1
Ethernal
  • 172
  • 1
  • 12
  • 1
    While this may answer the question, [it would be preferable](http://meta.stackoverflow.com/q/8259) to include the essential parts of the answer here, and provide the link for reference. – IKavanagh Dec 10 '15 at 15:01
  • @IKavanagh I added the whole answer below the link. But it's not DRY to do that that's why I posted a link only. – Ethernal Dec 11 '15 at 07:25