我的构建器
有一个表单类MyClassType$builder->add('options', ChoiceType::class, [
'choices' => [
'option1',
'option2',
'option3',
'option4'
]])
// some other stuff
->add('subform1', Subform1Type::class)
->add('subform2', Subform2Type::class)
->add('subform3', Subform3Type::class);
和
的视图{{ form_start(form) }}
{{ form_label(form.options) }}
{{ form_errors(form.options) }}
{{ form_widget(form.options) }}
{{ form_label(form.subform1) }}
{{ form_errors(form.subform1) }}
{{ form_widget(form.subform1) }}
{{ form_label(form.subform2) }}
{{ form_errors(form.subform2) }}
{{ form_widget(form.subform2) }}
{{ form_label(form.subform3) }}
{{ form_errors(form.subform3) }}
{{ form_widget(form.subform3) }}
{{ form_end(form) }}
和我的控制器类功能
$myClass = new MyClass();
$form = $this->createForm(MyClassType::class, $myClass);
$form->handleRequest($request);
return $this->render('default/myClassView.html.twig',[
'form' => $form->createView()
]);
我想要做的是根据我选择的选项获得子表单。例如,option1给了我subform1,但是像option4这样的东西给了我subform2和subform3。
我想这样做是因为我将子窗体数据的ManyToOne关系转换为MyClass,但MyClass有时只有subform1等的数据。
我不确定该怎么做。这是EventListeners的用途吗? 我的意思是:在MyClassType
中$builder->addEventListener(
FormEvents::PRE_SET_DATA // or something similiar
function (FormEvent $event) {
// do some magic here
}
);
还是可以做一些JavaScript魔术?我真的不想隐藏我的子表单,因为它仍然存在
答案 0 :(得分:0)
我想我自己解决了。所以我会给你我做的。 如上所示,将EventListener添加到MyClassType
$builder->addEventListener(
FormEvents::PRE_SET_DATA
function (FormEvent $event) {
$entity = $event->getData();
$form = $event->getForm();
if($entity->getSubform1() !== null){
$form->add('subform1', Subform1Type::class);
}
}
);
作为替代方案,您可以添加EventSubscriber
$builder->addEventSubscriber(new AddFormFieldsSubscriber());
并编写一个新类
class AddUrkundenFieldsSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return array(FormEvents::PRE_SET_DATA => 'preSetData');
}
public function preSetData(FormEvent $event)
{
$entity = $event->getData();
$form = $event->getForm();
if($entity->getSubform1() !== null){
$form->add('subform1', Subform1Type::class);
}
}
}
在我的Controller类中,我使用$ _SESSION存储我的myClass,如
public function indexAction(Request $request)
{
$session = $this->get('session');
if(!$session->get('myClass')){
$myClass = new MyClass();
} else {
$myClass = $session->get('myClass')
}
// create and handle form etc
if($form->isSubmitted()) {
$myClass = $form->getData();
if($myClass->getSubform1() === null) {
$myClass->setSubform1(new Subform1());
$session->set('myClass', $myClass);
return $this->redirectToRoute('thisPage');
} else { /* redirect to another page */ }
retrun /* create form view */;
}}
我还必须在Subform1 Class
中实现以下功能public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => 'AppBundle\Entity\Subform1',
]);
}
在Twig文件中,您可以执行类似
的操作{% if form.subform1 is defined %}
{{ form_widget(form.subform1) }}
{% endif %}