2013-10-07 3 views
5

У меня возникла проблема с динамической формой на symfony2. Я пытаюсь создать несколько полей для представленной формы. В других словах пользователь вводит некоторые значения, представляет форму и, согласно этим значениям, поля моей динамики добавляются в эту же форму (что, очевидно, отображается во второй раз). Чтобы сделать это, я использовал этот пример из поваренной книги: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#cookbook-form-events-submitted-dataSymfony2 недействительная динамическая форма без ошибок

Итак, вот мой FormationType класс

class FormationType extends AbstractType 
{ 

private $em; 
private $context; 

public function __construct($em, $context) { 
    $this->em = $em; 
    $this->context = $context; 
} 

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder 
     ->add('name') 
     ->add('date') 
     ->add('type', 'choice', array(
      'mapped' => false, 
      'choices' => Formationlist::getTypeTypes(false), 
      'empty_value' => false, 
     )) 
     ->add('cost') 
     ->add('travelCost') 
     ->add('maximum') 
     ->add('location') 
     ->add('schedule') 
    ; 

    $formModifier = function(FormInterface $form, $type) { 
     $formationList = $this->em->getRepository('CoreBundle:FormationList')->findBy(array("year" => 1, "type" => $type)); 

     $form->add('formationList', 'entity', array(
      'label'=> 'Titre formation', 
      'choices' => $formationList, 
      'class' => 'CoreBundle:FormationList', 
      'property' => 'title',) 
       ); 

     }; 


    $builder->addEventListener(
     FormEvents::PRE_SET_DATA, 
     function(FormEvent $event) use ($formModifier) { 

      $data = $event->getForm(); 
      $type = $data->get('type')->getData(); 

      $formModifier($event->getForm(), $type); 

     } 
    ); 

    $builder->get('type')->addEventListener(
     FormEvents::POST_SUBMIT, 
     function(FormEvent $event) use ($formModifier) { 

      $type = $event->getForm()->getData(); 
      $formModifier($event->getForm()->getParent(), $type); 
     } 
    ); 
} 

public function setDefaultOptions(OptionsResolverInterface $resolver) 
{ 
    $resolver->setDefaults(array(
     'data_class' => 'EXAMPLE\CoreBundle\Entity\Formation' 
    )); 
} 

public function getName() 
{ 
    return 'example_corebundle_formationtype'; 
} 
} 

Таким образом, две addEventListener работы довольно хорошо. В первый раз, когда отображается моя форма, поле в formModifier не загружается, как и ожидалось. Мой класс контроллера заключается в следующем:

public function createAction(Request $request) 
{ 
    $em = $this->getDoctrine()->getManager(); 
    $contextSrv = $this->get('example.service.context'); 
    $context = $contextSrv->getContext(); 

    $entity = new Formation(); 
    $form = $this->createForm(new FormationType($em, $context), $entity); 
    $form->bind($request); 

    if ($form->isValid()) { 

     $em->persist($entity); 
     $em->flush(); 

     return $this->redirect($this->generateUrl('formation_show', array('id' => $entity->getId()))); 
    } 

    return array(
     'entity' => $entity, 
     'form' => $form->createView(), 
    ); 
} 

Поскольку один из моих динамического поля не может быть нулевой, первый раз, когда форма была отправлена, она не может быть действительным. Таким образом, FormationType загружается второй раз. Это означает, что если поле «type» было заполнено, моя функция formModifier() может загружать динамическое поле (formList). Пока там, все работает очень хорошо, и я получил свое новое поле.

Но после второго «подать» на форму ... ничего не происходит. Страница просто перезагружается, и ошибки не отображаются.

Я проверил содержимое формы с

var_dump($request->request->get('example_corebundle_formationtype')); 

-> Каждые поля (в том числе динамического) заполняется допустимыми значениями.

Я также попробовать это:

foreach($form->all() as $item) { 
     echo $item->getName(); 
     var_dump($item->getErrors()); 
} 

-> Эти строки не показывают какой-либо ошибки. Но форма никогда не действует.

var_dump($form->isValid()); 

-> Он возвращает false. Таким образом, форма недействительна.

Наконец, если я удаляю всю динамическую часть, моя форма работает. Я не понимаю, что случилось. Ошибок, отображаемых формой, нет, а токен csrf кажется правильным. Я что-то пропустил ? Спасибо за вашу помощь.

+0

Просто догадайтесь, можете ли вы проверить с помощью firebug, если значение для типа одинаково, если вы удалите эту строку кода: 'choice' => $ formList, из вашей формы $ formModifier? – Cesc

+0

hm ... я не понимаю вашу точку зрения. Я удалил «choice» => $ formList, из $ formModifier, но ничего не случилось с полем «type». Ожидается, что «тип» - это выбор без динамического значения. Поле formList было и остается списком (единственное отличие -

+0

внутри должен быть действительным id (независимо от того, какой вы указали первичный ключ) для класса FormationList, если нет, $ form-> isValid() будет false. Это был мой момент, но я уверен, что список $ formList хорошо сделан, и поэтому он должен иметь правильный идентификатор. Это было просто дикое предположение. – Cesc

ответ

1

Я знаю, что это немного устарело, но в Google довольно много.

Метод getErrors() возвращает только глобальные ошибки формы, а не сообщения об ошибках для лежащих в основе полей, вам нужно либо getErrors (true), либо более сложный метод при использовании встроенных форм в форме. Пожалуйста, смотрите: https://knpuniversity.com/blog/symfony-debugging-form-errors для получения дополнительной информации.

1

Возможно, у вас возникла ошибка проверки, лежащая где-то в вашей форме.

Вместо ваших сложных звонков Форма :: getErrors() - который не является полностью рекурсивно, так как ошибки любого поля глубже, чем 2-го уровня не будет отображаться - вы должны использовать форму :: getErrorsAsString ().

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

Если ошибка не отображается, хотя это должно быть, это может быть ошибка формы. При создании настраиваемой формы темы возможно, что разработчик переопределяет или забывает отображать блок ошибок поля.

Другим возможным источником проблемы является общий вид формы. Если вы отобразите свою форму с помощью {{form_widget (form)}}, то любая ошибка, которая пузырится в верхней форме, никогда не будет отображаться.Затем убедитесь, что вы используете {{form_row (form)}}.

+0

Полезно знать, getErrorsAsString, спасибо за подсказку! К сожалению, это не показало ошибок. Только «Нет ошибок» для каждого отдельного поля ... Я также использовал row_form вместо form_widget для того же результата. И так как я не использую пользовательскую тему для этой формы ... это не должно быть причиной. Но ваш совет поможет мне узнать, что случилось! – TiPi

+0

Но это абсурдно. Если вы проверите себя базовое определение формы :: isValid(), этот метод просто рекурсивно проверяет наличие ошибок. Если Form :: getErrorsAsString() ничего не возвращает, то isValid() должно быть true, period. Используете ли вы метод isValid()? Вы абсолютно уверены, что делаете свои чеки и свалки после того, как форма привязана? – Zephyr

+0

Возможно также наличие дополнительного поля. – geoB

0

Я также столкнулся с этой проблемой несколько раз.

В моем случае я разместил данные в формате JSON, поэтому мне пришлось выполнить прослушиватель запросов с высоким приоритетом, который преобразует данные json в обычные данные POST, которые доступны в запросе $ request->.

Один из сценариев, в которых форма $ недействительна, и нет ошибок в том же случае, когда почтовые данные пусты, попробуйте сделать дамп запроса $ request-> request-> all(), чтобы увидеть, есть ли у вас данные.

Смежные вопросы