我在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標記看起來正確。我錯過了什麼 ?謝謝你的幫助。
只是猜測,你可以檢查與螢火蟲如果類型的值是相同的,當你刪除這行代碼:'選擇'=> $ formationList,從你的窗體$ formModifier嗎? – Cesc
嗯......我不明白你的觀點。我從$ formModifier中刪除了'choices'=> $ formationList,但沒有發生到字段「type」。這是因爲'類型'是一個沒有動態值的選擇。 formationList字段是,並且仍然是一個列表(
的裏面應該是一個有效ID(您指定的任何主鍵)爲類FormationList,如果沒有,$形式 - > isValid()的將是錯誤的。這是我的觀點,但我相當肯定列表$ formationList做得很好,因此它應該有正確的ID。這只是一個瘋狂的猜測。 – Cesc