1

I would like to update multiple entities and with the update I would like to add a field called "comment". This field is not related to the entity; I will save the comment in a separate table.

This is what I've tried (Controller code below) - this is just a sample of the code, but should give an idea of what I am trying to do:

$form = $this->createFormBuilder();

foreach (array(1,2,3) as $id) {
    $subform = $this->createFormBuilder()
        ->add('story', 'entity', array(
            'class' => 'AcmeDemoBundle:Story',
            'query_builder' => function($em) use ($id) {
                 $qb = $em->createQueryBuilder('s')
                 $qb->select(array('j'))
                     ->add('from', 'AcmeDemoBundle:Story')
                     ->addWhere('j.id = :id')
                     ->setParameter('id', $id);
                 return $qb;
            },
            'property' => 'id',
            'required' => true, 'expanded' => true, 'multiple' => true
        )
        ->add('comment', 'textarea');
}
$form->add($subform, '', array('label' => '');

...
// then I send the form to the template with $form->createView()

What I expected to see was a form with each entity (1,2,3) as a checkbox and next to that a comment block. Instead what happens is I only get one checkbox and one comment and always for the last entity in the array (in the above case, entity number 3). It seems that the form builder ignores all the subforms that I add and only takes the last one - this is also the case when looking at the SQL that goes to the DB, there is only a select for # 3 and no selects for 1 and 2.

Given that the html produced supports what I am trying to do, I expect the above to work:

<input type="checkbox" id="form_form_story_0" name="form[form][story][]" value="3">
<textarea id="form_form_comment"  name="form[form][comment] />

I've also tried giving the fields unique names - for example ->add('story_' . $id) etc, but that didn't do anything. I also tried giving each querybuilder a unique name $em->createQueryBuilder('s'.$id) but that didn't work either.

Also, it doesn't work if I remove the query_builder (and just use the class)

Update: it doesn't seem to have anything to do with the entity, even if I try and create subforms with plain text fields it doesn't work...

Update 2 if the sub form has a different name using:

$subForm = $this->get('form.factory')->createNamedBuilder("form$id"), 'form', array())

then it works. Unfortunately this means that I can't loop through the subforms inside twig.

2 Answers 2

0

It can't work as stated/asked above.

->add

overwrites a previous copy of that child, as seen here:

Symfony\Component\Form
...
public function add(FormInterface $child)
...
$this->children[$child->getName()] = $child;

To "solve" the problem I discarded the idea of sub forms and named each item separately like this:

$form
...
->add("comment_$id", 'textarea')

made an array of the entities and in twig render the comment field for that entity like this:

{% for entity in entities %}
...
{% set child = "comment_" ~ entity.id %}{{ form_widget(form.children[child]) }}
...
Sign up to request clarification or add additional context in comments.

Comments

0
  1. Your example code contains error: you adding $subform after cycle, so you explicitly adding only last generated $subform object.

  2. Noted line $this->children[$child->getName()] = $child; prevents from "simple" way to add subform builders, but there is a workaround:

Instead of calling $this->createFormBuilder() helper for subform (this will give it name "form"), you can create biulder with $this->container->get('form.factory')->createNamedBuilder('sub_form_1') with explicit name.

1 Comment

BTW, when calling add with FormBuilder instance, it ignores all other arguments, kinda overloading php-way.

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.