Symfony2: две формы на одной странице

У меня две формы на одной странице.

Моя проблема в том, что когда я пытался отправить форму, это похоже на то, что она попыталась представить вторую форму ниже на странице.

Как следует, вы можете найти мои 2 формы:

public function createSuiviForm() { return $form = $this->createFormBuilder(null) ->add('numero', 'text', array('label' => 'N° : ', 'constraints' => array( new Assert\NotBlank(array('message' => 'XXXX')), new Assert\Length(array('min' => 19, 'max' => 19, 'exactMessage' => 'XXX {{ limit }} XXX'))))) ->add('xxxx', 'submit') ->getForm(); } public function createModificationForm() { return $form = $this->createFormBuilder(null) ->add('modification', 'submit', array('label' => 'XXXXXXXXXXXXXXXXXXXX')) ->getForm(); } 

Моя вторая форма – только кнопка отправки.

Я передал их в свой рендер и отобразил их, используя:

 <div class="well"> <form method="post" action='' {{form_enctype(form)}} > {{ form_widget(form) }} <input type="submit" class="btn btn-primary"/> </form> <div class='errors'> {{ form_errors(form) }} </div> </div> 

«form» – это имя моей переменной для первой формы и «обновление» для моей второй формы.

Когда я попытался представить свою вторую форму, мне нужно дважды щелкнуть, и, наконец, я получаю:

 "This form should not contain extra fields." And all non valid input for the remainding form. 

Я попытался добавить validation_group в false, но безрезультатно.

Я не понимаю, почему я получил эту ошибку, потому что мои формы не встроены вообще

Надеюсь, вы поймете …

Вы должны обрабатывать формы отдельно:

 if('POST' === $request->getMethod()) { if ($request->request->has('form1name')) { // handle the first form } if ($request->request->has('form2name')) { // handle the second form } } 

Это прекрасно объясняется в Symfony2 Несколько форм: разные из встроенных форм

Это сделал трюк для меня в Symfony 3 (также должен работать на Symfony 2):

 $form1 = $this->createForm( MyFirstFormType::class ); $form2 = $this->createForm( MySecondFormType::class ); if ($request->isMethod('POST')) { $form1->handleRequest($request); $form2->handleRequest($request); if ($form1->isSubmitted()) { // Handle $form1 } else if ($form2->isSubmitted()) { // Handle $form2 } } 

Проблема в том, что у вас есть две безымянные формы ( inputname имена, такие как имя inputname вместо имени formname[inputname] , и, таким образом, когда вы привязываете запрос к своей форме и его проверяете, он обнаруживает некоторые дополнительные поля (другая форма) и поэтому недействителен ,

Кратковременное решение заключается в создании именованного строителя через фабрику форм, поэтому вместо:

 $form = $this->createFormBuilder(null) 

вы должны использовать:

 $form = $this->get("form.factory")->createNamedBuilder("my_form_name") 

Долгосрочным решением будет создание ваших собственных классов форм , таким образом вы можете сохранить свой код формы отдельно от контроллера.

Эти две формы будут опубликованы.

Попробуйте использовать:

  $this->createNamedBuilder 

вместо

  $this->createFormBuilder 

Затем в вашем контроллере найдите форму по имени:

 if ($request->request->has("your form name") { $form->handleRequest($request); } 

Использование именных форм – это жизнеспособное решение для обработки нескольких форм, но оно может немного запутаться, особенно если вы генерируете формы динамически.

Другой способ, как Symfony 2.3, – проверить, какая кнопка отправки нажата.

Например, при условии, что каждая форма имеет кнопку отправки с именем 'save' :

 if ('POST' == $Request->getMethod()) { $form1->handleRequest($Request); $form2->handleRequest($Request); $form3->handleRequest($Request); if ($form1->get('save')->isClicked() and $form1->isValid()) { //Do stuff with form1 } if ($form2->get('save')->isClicked() and $form2->isValid()) { //Do stuff with form2 } if ($form3->get('save')->isClicked() and $form3->isValid()) { //Do stuff with form3 } } 

Я считаю, что у этого есть небольшое количество дополнительных накладных расходов по сравнению с методом named builder (из-за нескольких вызовов handleRequest ), но в некоторых случаях это приводит к более чистым кодам. Всегда хорошо иметь несколько решений на выбор. Некоторые дополнительные накладные расходы можно было бы облегчить с помощью вложенных операторов if / else, если это необходимо, но, если мы не говорим о десятках форм на странице, дополнительные накладные расходы в любом случае незначительны.

Вот альтернативная реализация, использующая анонимные функции, которые сводят к минимуму повторение кода:

 $form1Action = function ($form) use (&$aVar) { //Do stuff with form1 }; $form2Action = function ($form) use (&$anotherVar) { //Do stuff with form2 }; $form3Action = function ($form) use (&$yetAnotherVar) { //Do stuff with form3 }; $forms = [$form1 => $form1Action, $form2 => $form2Action, $form3 => $form3Action]; if ('POST' == $Request->getMethod()) { foreach ($forms as $form => $action) { $form->handleRequest($Request); if ($form->get('save')->isClicked() and $form->isValid()) { $action($form); } } } 

Вот как я обращаюсь с ними на моем контроллере:

 return $this->render('SgaDemandeBundle:Demande:suivi_avancement.html.twig', array('form' => $form->createView(), ........ 'update' => $formModification->createView())); 

Это html для второй формы:

 <div class="well"> <form method="post"> <div id="form"> <div> <button type="submit" id="form_modification" name="form[modification]">Modification done </button> </div> <input type="hidden" id="form__token" name="form[_token]" value="fFjgI4ecd1-W70ehmLHmGH7ZmNEHAMqXlY1WrPICtK4"> </div> </form> </div> 

Это моя веточка:

 <div class="well"> <form method="post" {{form_enctype(update)}} > {{ form_widget(update) }} </form> </div> <div class="well"> <form method="post" action='' {{form_enctype(form)}} > {{ form_widget(form) }} <input type="submit" class="btn btn-primary"/> </form> <div class='errors'> {{ form_errors(form) }} </div> </div> 

Я надеюсь, что это поможет вам.