动态表单修改

Posted

技术标签:

【中文标题】动态表单修改【英文标题】:Dynamic Form Modification 【发布时间】:2021-11-10 14:23:31 【问题描述】:

我正在尝试创建一个包含两个动态表单元素的动态表单。

我已经按照https://symfony.com/doc/current/form/dynamic_form_modification.html#dynamic-generation-for-submitted-forms中的示例进行操作

我可以在选择并提交运动后创建一个显示新表单元素位置的表单。

但是让我们说,在选择了一个职位并提交后,他们必须选择一种颜色,你会怎么做呢?

我尝试为位置添加一个新的事件侦听器,但它从未被调用。

         $builder->get('position')->addEventListener(
            FormEvents::POST_SUBMIT,
            function (FormEvent $event) use ($formModifier) 
                // It's important here to fetch $event->getForm()->getData(), as
                // $event->getData() will get you the client data (that is, the ID)
                $position = $event->getForm()->getData();
                dump($position);

                $event->getForm()->add('colour', EntityType::class, [
                    'class' => Colour::class,
                    'placeholder' => '',
                    'choices' => ['red','green','blue'],
                ]);

            
        );

例如在这个测试数据中,运动是足球,位置是前锋,允许的颜色是红色和绿色,对于位置守门员,颜色可能是黄色和黑色。

【问题讨论】:

【参考方案1】:

您正在尝试将 colour 字段添加到错误的表单中。 使用$event->getForm(),您正在检索“位置”表单,而不是您要修改的主表单。

我已经评论了你的代码以更好地解释这一点。

/* Here you're correctly registering an event listener to the "position" field, POST_SUBMIT event */
$builder->get('position')->addEventListener(
    FormEvents::POST_SUBMIT,
    function (FormEvent $event) use ($formModifier) 
        // $event->getForm() here will return the "position" field form
        $position = $event->getForm()->getData();
        dump($position);

        // In the documentation example here the $formModifier closure is used
        // with $event->getForm()->getParent() as first argument

        // What you missed here is the getParent() call
        $event->getForm()
            ->getParent() // <- This will return the main form, the one you built with $builder
            ->add('colour', EntityType::class, [
                'class' => Colour::class,
                'placeholder' => '',
                'choices' => ['red','green','blue'],
            ]);
    
);

您在事件侦听器中错过的是在 add 调用之前的 getParent() 调用。

【讨论】:

我尝试了类似的方法,但是当你有 $builder-&gt;get('position')-&gt;addEventListener(FormEvents::POST_SUBMIT,...$builder-&gt;get('sport')-&gt;addEventListener(FormEvents::POST_SUBMIT,... 时,只有运动会被调用。 如果不知道你在 sport 事件监听器中做了什么,就不可能知道哪里出了问题。我只能假设您正在用一个新字段覆盖 position 表单字段,从而删除附加了侦听器的旧字段。 我正在测试的代码是来自 symfony 文档 symfony.com/doc/current/form/… 的复制和粘贴,get('sport') 监听器的代码与此相同。 正如我所想,formModifier 闭包中的$form-&gt;add('position', … 删除了您从构建器获取的字段并添加了一个没有附加侦听器的新字段

以上是关于动态表单修改的主要内容,如果未能解决你的问题,请参考以下文章

Antd表单控件的defaultValue 无法动态修改

layui动态修改表单form内容

动态生成表单

vue动态修改rules的message值

vue项目动态添加表单和校验

jquery.form插件中动态修改表单数据