У меня две формы на одной странице.
Моя проблема в том, что когда я пытался отправить форму, это похоже на то, что она попыталась представить вторую форму ниже на странице.
Как следует, вы можете найти мои 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>
Я надеюсь, что это поможет вам.