2013-10-07 12 views
5

Mam problem z dynamiczną formą symfony2. Próbuję wygenerować pola dla przesłanego formularza. Innymi słowy, użytkownik wprowadza pewne wartości, przesyła formularz i zgodnie z tymi wartościami moje pola dynamiki są dodawane do tej samej postaci (co oczywiście jest wyświetlane po raz drugi). Aby to zrobić, użyłem tego przykładu z książki kucharskiej: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#cookbook-form-events-submitted-dataNiepoprawna dynamiczna postać Symfony2 bez błędu

Tak, tu jest moja klasa 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'; 
} 
} 

Więc praca dwóch addEventListener całkiem dobrze. Przy pierwszym wyświetleniu mojego formularza pole w module FormModifier nie jest ładowane zgodnie z oczekiwaniami. Moja klasa kontrolera jest następujący:

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(), 
    ); 
} 

Ponieważ jeden z moich dynamicznego pola nie mogą być puste, po raz pierwszy formularz jest składany, nie może być ważny. Tak więc FormationType jest ładowany po raz drugi. Oznacza to, że jeśli pole "type" zostało wypełnione, moja funkcja formModifier() może załadować dynamiczne pole (formationList). Do tego czasu wszystko działa całkiem nieźle, a ja dostałem swoją nową dziedzinę.

Ale po drugim "przesłać" na formularzu ... nic się nie dzieje. Strona jest ponownie załadowana i nie są wyświetlane żadne błędy.

Sprawdziłem zawartość formularza z

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

-> Co pola (w tym dynamicznym jeden) są wypełnione prawidłowych wartości.

Ja też spróbować:

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

-> Linie te nie wykazują żadnych błędów. Ale forma nigdy nie jest ważna.

var_dump($form->isValid()); 

-> Zwraca wartość false. Tak więc formularz jest nieważny.

Wreszcie, jeśli usunę całą część dynamiczną, mój formularz działa. Nie rozumiem, co jest nie tak. Nie ma błędów wyświetlanych przez formularz, a token csrf wydaje się być prawidłowy. Przegapiłem coś ? Dzięki za pomoc.

+0

Po prostu zgadnij, czy możesz sprawdzić firebug, czy wartość dla typu jest taka sama po usunięciu tego wiersza kodu: "choices" => $ formationList, z formularza $ formModifier? – Cesc

+0

hm ... nie rozumiem twojego punktu widzenia. Usunąłem "choices" => $ formationList, z $ formModifier, ale nic się nie stało z polem "type". Co jest oczekiwane, ponieważ "typ" jest wyborem bez wartości dynamicznej. Pole formationList było i nadal jest listą (jedyna różnica to

+0

wewnątrz powinien być prawidłowym identyfikatorem (niezależnie od podanego klucza podstawowego) dla klasy FormationList, jeśli nie, $ form-> isValid() będzie fałszywe. To był mój punkt, ale jestem całkiem pewien, że lista $ formationList jest dobrze zrobiona i dlatego powinna mieć prawidłowy identyfikator. To było tylko dzikie domysły. – Cesc

Odpowiedz

1

Wiem, że jest to nieco przestarzałe, ale pojawia się dość wysoko w Google.

Metoda getErrors() zwraca tylko globalne błędy Form, a nie komunikaty o błędach dla pól bazowych. W przypadku formularzy osadzonych w formularzu należy użyć metody getErrors (true) lub bardziej wyrafinowanej. Aby uzyskać więcej informacji, zobacz: https://knpuniversity.com/blog/symfony-debugging-form-errors.

1

Prawdopodobnie w twoim formularzu znajduje się błąd sprawdzania poprawności.

zamiast swojego skomplikowanych połączeń do Forma :: getErrors() - który nie jest w pełni rekurencyjne, jak błędy każdej dziedzinie głębszego niż 2 poziom nie zostanie wyświetlona - należy użyć Form :: getErrorsAsString ().

To jest metoda debugowania stworzona przez facetów z Symfony dla takich deweloperów, jak Ty, próbująca zrozumieć, gdzie może występować błąd weryfikacji w złożonych formach.

Jeśli błąd nie jest wyświetlany, chociaż powinien, może to być błąd związany z formą. Podczas tworzenia niestandardowego motywu formularza możliwe jest, że program rozwijający zastąpi lub zapomni wyświetlić blok błędu pola.

Innym możliwym źródłem problemu jest ogólne wyświetlanie formularza. Jeśli wyświetlasz formularz za pomocą {{form_widget (formularz)}}, wtedy błąd, który powoduje pojawienie się bąbelków w najwyższej formie, nigdy nie będzie wyświetlany.Upewnij się, że zamiast tego używasz {{form_row (form)}}.

+0

Dobrze wiedzieć, getErrorsAsString, dzięki za napiwek! Niestety nie pokazał żadnego błędu. Tylko "Brak błędów" dla każdego pola ... Użyłem również row_form zamiast form_widget dla tego samego wyniku. A ponieważ nie używam niestandardowego motywu dla tego formularza ... nie powinno to być powodem. Ale twoja rada pomoże mi dowiedzieć się, co jest nie tak! – TiPi

+0

Ale to jest absurd. Jeśli sprawdzisz sobie podstawową definicję Form :: isValid(), ta metoda tylko rekurencyjnie sprawdza istnienie błędów. Jeśli Form :: getErrorsAsString() zwraca nic, to isValid() powinno być prawdziwe, kropka. Czy używasz niestandardowej metody isValid()? Czy jesteś absolutnie pewien, że robisz kontrole i zrzuty po związaniu formularza? – Zephyr

+0

Możliwe jest również dodatkowe pole. – geoB

0

Kilka razy napotkałem ten problem.

W moim przypadku opublikowałem dane w formacie JSON, więc musiałem wykonać detektor żądań o wysokim priorytecie, który przekształca dane Json w zwykłe dane POST, które są dostępne w $ request-> request.

Jeden ze scenariuszy, w którym forma $ jest nieprawidłowa i nie występują błędy w przypadku, gdy dane wpisu są puste, spróbuj zrobić zrzut $ request-> request-> all(), aby sprawdzić, czy masz dane.