2014-05-15 3 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 для метода setProcessAfterDate(). Я не уверен, правильно ли я понимаю систему событий или если ошибка лежит где-то в другом месте.

+0

'null' в настоящее время передаются на 'setProcessAf terDate() ', когда данные не пройдены. Добавьте трансформатор данных в форму для поля 'setProcessAfterDate()', чтобы преобразовать NULL в объект 'Date' с чем-то вроде« 0000-00-00 ». http://symfony.com/doc/current/cookbook/form/data_transformers.html Это должно всегда передавать объект даты объекту независимо от того, что. – 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 way» :) – user3087048

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