繁体   English   中英

Symfony 5 表单生成器:实体类型/具有多个实体的选择类型

[英]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 是一个很好的起点,因为它允许分组,但我不知道应该如何检索帐户和信用卡。

嗯, EntityTypeChoiceType “继承”,所以几乎所有你可以用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM