(Symfony 4 表单类型)如何根据表单上的 <select> 值制作一个完整的子表单 required/not?

(Symfony 4 form types) How do you make an entire subform required/not required based on a <select> value on the form?

这是我的表单类型 class。所以我说的 < select> 字段是 'numSubscriptionTiers':

class UserProfileType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('numSubscriptionTiers', ChoiceType::class, [
                'choices' => [
                    '1' => 1,
                    '2' => 2,
                    '3' => 3
                ]
            ])
            ->add('subscriptionTier1', UserSubscriptionTierType::class, [
                'required' => false,
                'entry_type' => UserSubscriptionTierType::class
            ])
            ->add('subscriptionTier2', UserSubscriptionTierType::class, [
                'required' => false,
                'entry_type' => UserSubscriptionTierType::class
            ])
            ->add('subscriptionTier3', UserSubscriptionTierType::class, [
                'required' => false,
                'entry_type' => UserSubscriptionTierType::class
            ])

如果用户 selects 1,则只需要 subscriptionTier1 子表单,如果用户 selects 2,则只需要 subscriptionTier1 和 subscriptionTier2 子表单,依此类推。 .

我知道有 PRE_SET_DATA、POST_SUBMIT 等表单事件...但是您可以从表单类型 [=27] 中添加类似于 JavaScript 事件的内容吗=]?像 numSubscriptionTiers select 的某种 onChange 事件,并将相应的子表单的 required 属性设置为 true/false?

我已经去了这里:https://symfony.com/doc/current/form/dynamic_form_modification.html#how-to-dynamically-generate-forms-based-on-user-data 它只给出了一个如何动态填充选择列表的示例,而不是在指定选项后添加更改事件。

使用 PRE_SUBMIT 事件 modify the form dynamically 设置表单元素的后端验证。

例如,如果 numSubscriptionTiers 的发送值是 2,则删除子项 subscriptionTier1subscriptionTier2 并再次添加它们,但这次使用额外的 NotBlank约束:

// add imports

public function buildForm(FormBuilderInterface $builder, array $options)
{
    // skipped for brevity
    $builder->addEventListener(FormEvents::PRE_SUBMIT, [$this, 'conditional']);
}

public function conditional(FormEvent $event)
{
    $form = $event->getForm();
    $data = $event->getData();

    // make sure tierCount is between 1-3
    $tierCount = min(3, max(1, (int) $data['numSubscriptionTiers'] ?? 0));

    for ($i = 1; $i <= $tierCount; $i++) {
        $childName = sprintf('subscriptionTier%d', $i);

        $form
            ->remove($childName)
            ->add($childName, UserSubscriptionTierType::class, [
                'required' => false,
                'entry_type' => UserSubscriptionTierType::class,
                'constraints' => new NotBlank(),
            ]);
    }
}

恐怕必须使用 JavaScript 动态添加 HTML5 required 属性,因为 PHP 不会在客户端处理它。好吧,您可以修改动态重新添加的字段 subscriptionTier1required 属性,但是想想如果用户将 numSubscriptionTiers 更改为 2 会发生什么。由于 subscriptionTier1 元素上的 required 属性,因此无法提交表单。因此只有 JavaScript 是解决方案。