我有一个表格,上面有三个下拉选项:
FieldA FieldB FieldC
FieldB的选择依赖于fieldA的选择,FieldC的选择依赖于fieldB的选择
这些关系是:
EntityB ManyToMany EntityA
EntityC ManyToOne EntityB一切正常,说明提交表单无效,错误是“此表单不应包含额外字段”,罪魁祸首是fieldC。
我做错什么了?
下面是我的FormType代码:
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('fieldA', EntityType::class, [
'class' => EntityA::class,
'choice_label' => 'name',
'query_builder' => function(EntityARepository $a) {
return $a->createQueryBuilder('a')
->orderBy('a.name', 'ASC');
},
])
;
$builder->get('fieldA')->addEventListener(
FormEvents::POST_SUBMIT,
function(FormEvent $event) {
$form = $event->getForm();
$this->setupFieldB(
$form->getParent(),
$form->getData()
);
}
);
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function(FormEvent $event) {
$data = $event->getData();
if (!$data or !isset($data['fieldA'])) {
return;
}
$this->setupFieldB(
$event->getForm(),
$data['fieldA']
);
}
);
if ($builder->has('fieldB')) {
$builder->get('fieldB')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) {
$form = $event->getForm();
$this->setupFieldC(
$form->getParent(),
$form->getData()
);
}
);
}
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) {
$data = $event->getData();
if (!$data or !isset($data['fieldB'])) {
return;
}
$this->setupFieldC(
$event->getForm(),
$data['fieldB']
);
}
);
}
private function setupFieldB(FormInterface $form, ?string $selectedfieldA)
{
if (is_null($selectedfieldA)) {
$form->remove('fieldB');
$form->remove('fieldC');
return;
} else {
$fieldA = $this->EntityARepository->findOneBy(['name' => $selectedfieldA]);
$form
->add('fieldB', EntityType::class, [
'class' => EntityB::class,
'query_builder' => function (EntityBRepository $b) use ($fieldA) {
return $b->createQueryBuilder('b')
->andWhere(':fieldA MEMBER of b.fieldAs')
->setParameter('fieldA', $fieldA)
->orderBy('b.name', 'ASC');
},
'choice_label' => 'name',
]);
}
}
private function setupFieldC(FormInterface $form, ?string $selectedFieldB)
{
if (is_null($selectedFieldB)) {
$form->remove('fieldC');
return;
} else {
$fieldB = $this->fieldBRepository->findOneBy(['name' => $selectedFieldB]);
$form
->add('fieldC', EntityType::class, [
'class' => EntityC::class,
'query_builder' => function(EntityCRepository $c) use ($fieldB) {
return $c->getQueryBuilderWithFilter(['fieldB' => $fieldB]);
},
'choice_label' => 'name',
]);
}
}发布于 2022-04-14 08:47:28
经过进一步的研究,我找到了以下解决方案:
( a)用if ($builder->has('fieldB')) {删除该部分--因为这始终被解析为false。
( b)重写函数setupFieldB .如下所示:
private function setupFieldB(FormInterface $form, ?string $selectedfieldA)
{
if (is_null($selectedfieldA)) {
$form->remove('fieldB');
$form->remove('fieldC');
return;
} else {
$fieldA = $this->EntityARepository->findOneBy(['name' => $selectedfieldA]);
$newBuilder = $form->getConfig()->getFormFactory()->createNamedBuilder('fieldB',
EntityType::class, null, [
'class' => EntityB::class,
'query_builder' => function (EntityBRepository $b) use ($fieldA) {
return $b->createQueryBuilder('b')
->andWhere(':fieldA MEMBER of b.fieldAs')
->setParameter('fieldA', $fieldA)
->orderBy('b.name', 'ASC');
},
'choice_label' => 'name',
]);
// now we can add the listener:
$newBuilder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
$form = $event->getForm();
$this->setupFieldC(
$form->getParent(),
$form->getData()
);
});
// finally add the field to the form
$form->add($newBuilder->getForm());
}
}https://stackoverflow.com/questions/71825683
复制相似问题