2014-05-15 55 views
1

我有一個狀態選擇表單。如果選擇某個狀態並提交表單,則應重新加載並需要一個附加字段。根據提交的數據在Symfony2中添加所需的表單域

我已閱讀Dynamic generation for submitted Forms和幾乎在互聯網上的所有其他帖子和關於這個話題,並嘗試不同的事件組合(並得到不同的錯誤),但我仍然努力使這個工作正常。

這是我到目前爲止有:

FormType

private function addProcessAfterField(FormInterface $form) 
{ 
    $form->add('processAfterDate', 'date', array('required' => true)); 
} 


public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder->add('status', 'entity', array(
     'class' => 'Acme\Bundle\ApplicationBundle\Entity\LeadStatusCode', 
     'choices' => $this->allowedTypes 
    )); 

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

     $form = $event->getForm(); 
     $data = $event->getData(); 

     if ($data->getStatus()->getId() == LeadStatusCode::INTERESTED_LATER) { 
      $this->addProcessAfterField($form); 
     } 
    }); 

    $builder->get('status')->addEventListener(FormEvents::POST_SUBMIT, function(FormEvent $event){ 
     $data = $event->getData(); 
     if ($data == LeadStatusCode::INTERESTED_LATER && !$event->getForm()->getParent()->getData()->getProcessAfterDate()) { 
      $this->addProcessAfterField($event->getForm()->getParent()); 
     } 
    }); 

    $builder->add('comment', 'textarea', array('mapped' => false)); 
    $builder->add('Update', 'submit'); 
} 

錯誤:

ContextErrorException: Catchable Fatal Error: Argument 1 passed to Proxies\__CG__\Acme\Bundle\ApplicationBundle\Entity\Lead::setProcessAfterDate() must be an instance of DateTime, null given, called in /var/www/application.dev/vendor/symfony/symfony/src/Symfony/Component/PropertyAccess/PropertyAccessor.php on line 360 and defined in /var/www/application.dev/app/cache/dev/doctrine/orm/Proxies/__CG__AcmeBundleApplicationBundleEntityLead.php line 447 

如前所述我嘗試了不同的事件組合,一個幾乎被工作,但隨後的日期永遠不會持久化到實體,所以我將\ DateTime type-hint添加到setProcessAfterDate()方法中。我不確定我是否不正確地理解事件系統,或者錯誤是否在其他地方。

+0

'null'被傳遞到'setProcessAf terDate()'當沒有數據傳遞時。在'setProcessAfterDate()'字段的表單中添加一個數據轉換器,將NULL轉換爲類似「0000-00-00」的'Date'對象。 http://symfony.com/doc/current/cookbook/form/data_transformers.html 無論如何,這應該總是將一個日期對象傳遞給setter。 – Tek

回答

0

那麼,它可能不是解決這個問題的最好辦法,但要長話短說:

$form->handleRequest($request); 

if($form->isValid()) // check if the basic version of the form is ok 
{ 
    $form = $this->createForm(new XXXXForm(), $form->getData()); // you recreate the form with the data that was submitted, so you rebuild the form with new data 

    if($form->isValid()) 
    { 
      // ok 
    } 



    // not ok 
} 

然後buildForm功能裏面,你基地場的基礎上你的「必需的」屬性值想:

'required' => $this->getCheckRequired($options) 


private function getCheckRequired($options) // checks whether field should be required based on data bound to the form 
{ 
    if($options && isset($options['data']) 
    { 

    switch $options['data']->getStatus(): 
     // whatever 

    ; 
    } 

return false; 

} 

正如我所說的,這是不是最好的解決辦法,並不能解決你的做法,而是提出了一個不同的,但它的工作

+1

嗨,這可能會工作,但我想解決它的「symfony的方式」:) – user3087048