[英]Symfony 5 form builder: Entity type/Choice type with several entities
我正在构建一种会计 web 应用程序,除其他外,我有一个信用卡实体和一个银行账户实体。 该应用程序旨在记录我的开支,所以计划是输入我的所有活动并将它们链接到他们支付的账户/信用卡; 因此, Movement
实体与Account
和/或CreditCard
实体具有ManyToOne
关系。
EntityType
将允许我 select 通过写入适当的帐户和信用卡:
$form = $this->createFormBuilder($movement)
->add('Account', EntityType::class, array(
'class' => Account::class,
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u')
->where('u.user = :user_id')
->setParameter(':user_id', $this->getUser());
},
'label' => 'Account name',
'required' => true
))
->add('Credit_Card', EntityType::class, array(
'class' => CreditCard::class,
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u')
->where('u.user = :user_id')
->setParameter(':user_id', $this->getUser());
},
'label' => 'Credit card',
'required' => true
))
->add('Save', SubmitType::class)
->getForm();
这将给我 HTML 中的两个 select 表单字段。当然,这并不理想,因为移动不与帐户和信用卡两者相关联,但仅与两者之一相关联。 因此, required
的属性实际上应该是requiredIfTheOtherFieldIsEmpty
属性。 理想情况下,我会有一个分段的 select 字段,它首先显示帐户组,然后显示信用卡组,因此类似于下面的伪代码:
$form = $this->createFormBuilder($movement)
->add(array('Account', 'Credit_Card'), array(EntityType::class, CreditCard::class), array(
'Account' => array(
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u')
->where('u.user = :user_id')
->setParameter(':user_id', $this->getUser());
},
'label' => 'Account name',
),
'Credit_Card' => array(
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u')
->where('u.user = :user_id')
->setParameter(':user_id', $this->getUser());
}
),
'required' => true
))
->add('Save', SubmitType::class)
->getForm();
不幸的是,我找不到符合这些要求的表单类型。 处理这个问题的正确方法是什么?
我想ChoiceType
是一个很好的起点,因为它允许分组,但我不知道应该如何检索帐户和信用卡。
非常感谢任何帮助。 如果需要更多信息,请询问,我很乐意提供您需要的信息。
我想 ChoiceType 是一个很好的起点,因为它允许分组,但我不知道应该如何检索帐户和信用卡。
嗯, EntityType
从ChoiceType
“继承”,所以几乎所有你可以用ChoiceType
做的事情你也可以用实体类型做。 例如分组
这将给我 HTML 中的两个 select 表单字段。当然,这并不理想,因为移动不与帐户和信用卡两者相关联,但仅与两者之一相关联。
最快的解决方案是使用FormEvents尤其是POST_SUBMIT
。 您可以“手动”验证/检查您的输入。 由于您正在使用createFormBuilder()
在 cotronller-action 中创建表单,因此它看起来像这样:
首先,使两个选择“可选”,然后使用FormEvents::PRE_SUBMIT
$formBuilder = $this->createFormBuilder($movement)
->add('Account', EntityType::class, array(
// your other options...
'required' => false
))
->add('Credit_Card', EntityType::class, array((
// your other options...
'required' => false
))
->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $postSubmitFormEvent) {
/** @var App\Entity\Movement $movement */
$movement = $postSubmitFormEvent->getData(); //
$form = $postSubmitFormEvent->getForm();
// don't do anything if form-data (movement) isn't valid at this point.
// in other words: if basic validation has failed - no need to run custom
if ($form->isValid() === false) {
return;
}
// custom validation...
// check #1 - if both selects are empty
if ($movement->getAccount() === null && $movement->getCreditCard() === null) {
// create an validation-error.
$form->addError(new FormError('Please choose at least one. Either account or credit-card.'));
}
// check #2 - if both select are fille/submitted
if ($movement->getAccount() !== null && $movement->getCreditCard() !== null) {
// create an validation-error.
$form->addError(new FormError('You can\'t select both! Either account or credit-card.'));
}
})
// your other fields....
->add('Save', SubmitType::class)
->getForm();
PS 我确实建议您为这种情况创建一个表格 class 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.