简体   繁体   English

(Symfony 4表单类型)如何基于 <select>价值形式?

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

Here is my form type class. 这是我的表单类型类。 So the < select> field I am talking about is the 'numSubscriptionTiers': 因此,我正在谈论的< 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
            ])

If the user selects 1, then only make the subscriptionTier1 subform required, if the user selects 2, then only make the subscriptionTier1 and subscriptionTier2 subforms required, and so on... 如果用户选择1,则仅使subscribeTier1子窗体成为必需,如果用户选择2,则仅使subscriptionTier1和subscriptionTier2子窗体成为必需,依此类推...

I know there are form events like PRE_SET_DATA, POST_SUBMIT, etc... but can you add something similar to a JavaScript event from within the form type class? 我知道有诸如PRE_SET_DATA,POST_SUBMIT之类的表单事件,但是您可以在表单类型类中添加类似于JavaScript事件的内容吗? Like some kind of onChange event to the numSubscriptionTiers select, and set the corresponding subforms' required attribute to true/false? 就像对numSubscriptionTiers选择某种onChange事件,然后将相应子窗体的required属性设置为true / false一样?

I have already gone here: https://symfony.com/doc/current/form/dynamic_form_modification.html#how-to-dynamically-generate-forms-based-on-user-data and it only gives an example of how to dynamically populate a choice list, not add a change event after it's options are specified. 我已经去过这里了: https : //symfony.com/doc/current/form/dynamic_form_modification.html#how-to-dynamically-generate-forms-based-on-user-data ,它仅提供了一个示例动态填充选择列表,而不在指定选项后添加更改事件。

Use the PRE_SUBMIT event to modify the form dynamically to set the backend validation on your form elements. 使用PRE_SUBMIT事件可以动态修改表单,以在表单元素上设置后端验证。

Eg, if the sent value of the numSubscriptionTiers is 2 , then remove children subscriptionTier1 and subscriptionTier2 and add them again, but this time with additional NotBlank constraint: 例如,如果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(),
            ]);
    }
}

I'm afraid the HTML5 required attribute has to be added dynamically using JavaScript, because PHP won't handle that on the client side. 恐怕HTML5 required使用JavaScript动态添加HTML5 required属性,因为PHP不会在客户端处理该属性。 Well you could modify the required property of the dynamically readded field subscriptionTier1 , but think what would happen if the user would change the numSubscriptionTiers to 2 . 好了,您可以修改动态读取的字段subscriptionTier1required属性,但请考虑一下,如果用户将numSubscriptionTiers更改为2将会发生什么。 It would be impossible to submit the form, because of the required property on the subscriptionTier1 element. 由于subscriptionTier1元素具有required属性,因此无法提交表单。 Thus only JavaScript is a solution to that. 因此,只有JavaScript是解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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