2013-10-07 16 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()函數可以加載動態字段(formationList)。在那之前,一切工作都很順利,我得到了新的領域。

但是,在表單上第二次「提交」之後......什麼也沒有發生。該頁面只是重新加載,並沒有顯示錯誤。

我檢查形式的內容與

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

只是猜測,你可以檢查與螢火蟲如果類型的值是相同的,當你刪除這行代碼:'選擇'=> $ formationList,從你的窗體$ formModifier嗎? – Cesc

+0

嗯......我不明白你的觀點。我從$ formModifier中刪除了'choices'=> $ formationList,但沒有發生到字段「type」。這是因爲'類型'是一個沒有動態值的選擇。 formationList字段是,並且仍然是一個列表(

+0

裏面應該是一個有效ID(您指定的任何主鍵)爲類FormationList,如果沒有,$形式 - > isValid()的將是錯誤的。這是我的觀點,但我相當肯定列表$ formationList做得很好,因此它應該有正確的ID。這只是一個瘋狂的猜測。 – Cesc

回答

1

我知道這是一個有點過時,但來了相當高的谷歌。如果在窗體中使用嵌入的表單時,getErrors()metod只返回表單的全局錯誤而不是基礎字段的錯誤消息,則需要getErrors(true)或更復雜的方法。請參閱:https://knpuniversity.com/blog/symfony-debugging-form-errors瞭解更多信息。

1

您的表單中可能存在驗證錯誤。

而不是你的複雜調用表:: getErrors()的 - 這是不完全遞歸,如超過2級更深的任何領域的錯誤將不會被顯示 - 你應該使用表:: getErrorsAsString( )

這是Symfony爲諸如你這樣的開發人員創建的調試方法,試圖瞭解驗證錯誤可能出現在複雜表單中的哪個位置。

如果沒有錯誤顯示,儘管它應該,這可能是一種形式主題錯誤。在創建自定義表單主題時,開發人員可能會覆蓋或忘記顯示字段的錯誤塊。

問題的另一個可能的根源在於窗體的一般顯示。如果您使用{{form_widget(form)}}來顯示您的表單,那麼將永遠不會顯示冒泡到頂部表單的任何錯誤。請確保您使用{{form_row(表格)}}

+0

很高興知道,getErrorsAsString,感謝您的提示!不幸的是,它沒有顯示任何錯誤。每個字段只有「沒有錯誤」...我也使用row_form而不是form_widget來獲得相同的結果。而且,由於我不使用自定義主題這種形式...這不應該是原因。 但是,您的建議將幫助我找出問題所在! – TiPi

+0

但這是荒謬的。如果您檢查自己Form :: isValid()的基本定義,則此方法只是遞歸地檢查是否存在錯誤。如果Form :: getErrorsAsString()不返回任何內容,則isValid()應該爲true,period。你在使用自定義的isValid()方法嗎?你確定你在表單綁定後做了你的支票和轉儲? – Zephyr

+0

這也有可能是一個額外的領域。 – geoB

0

我也遇到這個問題了幾次。

在我來說,我JSON格式發佈的數據,所以我不得不做請求收聽具有高優先級,其將JSON數據爲正常的POST數據,這是可以在$請求 - >請求。

其中$ form無效並且在發佈數據爲空時也沒有錯誤的情況下,嘗試使$ request-> request-> all()轉儲以查看是否有數據。