繁体   English   中英

基于表单选择的Symfony动态表单

[英]Symfony dynamic form based on form selection

可以说我们有一个表格,其中我们必须为客户选择会员类型。 每种类型的成员资格都有不同数量的共同成员(选择字段的实体类型),可以为该成员资格选择什么。

现在,我需要实现一个表单,其中将基于成员资格类型选择将选择字段的实体类型的数量添加到表单中。

当表单已经呈现在前面时,成员资格类型选择将变得很困难。

问题也许太笼统了,但是我应该如何实现这个FormType呢?

我看过这个coockbook条目: http ://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#cookbook-form-events-submitted-data但据我了解,此EventListener在常规表单呈现期间有效,因此在它显示在前端。 我是否应该实现AJAX hocus pocus以形成MembershipType字段,以便在选择它时再次呈现整个表单?

这种任务的一般逻辑是什么?

正如@keyboardSmasher在他的评论中提到的那样,多步表单策略可能是您的理想解决方案。 有很多方法可以实现这一点,但让我们继续探索。

首先,表单事件不仅在渲染之前有用。 您可以在很多地方截取表单呈现过程。 您可以检测到该记录是新记录,并且在这种情况下,仅显示(或不显示)特定字段。 您可以在持久保存之前更改新提交的表单数据。 您可以仅向具有适当权限的用户显示字段(使用表单工厂作为服务,为其注入安全上下文),甚至可以根据某些条件(例如,菜谱中的内容)显示供用户连接的朋友列表。 。 表单事件非常强大。 此外,您还可以创建一个自定义验证器 ,以检查是否允许选择的选项(在您的情况下),对于您所选择的成员资格,我极力建议这样做(这与表格非常分开,应与之紧密联系您的模型/文档/实体/等。)

如果我理解正确,则希望显示一个包含特定于特定成员类型选项的多重选择字段。 用户选择成员资格类型后,该选择字段(称为“ MembershipSubOptions”)将填充选项。 我希望这是正确的。 请注意,除了我快速搜索过的几个链接之外,以下内容不在我的脑海中,这已经很晚了,但它应该与您要实现的目标有些接近。

您可以从基本的ajax开始进行操作(尽管我不推荐hocus pocus,但这些东西确实很奇怪;-))。 在客户端,您可以使用Select2之类的库通过ajax减轻MembershipSubOptions的填充。 设置一条基于选择的成员资格来返回选项(json)的路由,以填充您的选择。 现在,您有一个与该成员资格类型相关的选项填充的选择,如果我理解正确,这些选项来自数据存储,因此从表单角度来看,它是一种实体类型。

我猜您希望用户从此选择字段中选择多个选项,而这些选项很可能存储为该用户的ManyToMany关系。 由于我们在这里处理实体类型,因此我们需要转换提交的数据,以便表单组件知道如何处理它。 让我们创建一个相当空的MembershipSubOptionsType表单类型。 它将类似于以下内容:

use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class MembershipSubOptionsType extends AbstractType
{
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(

            )
        );
    }

    public function getParent()
    {
        return 'hidden';
    }

    public function getName()
    {
        return 'membership_suboptions';
    }
}

在主表单中,为您的子选项选择字段添加类似以下内容的内容。 您会注意到我引用了$ this-em并将其传递给转换器。 将表单设置为由注册为服务的工厂类来管理,并注入“教义管理器”,以便获得所需的实体记录。

$membershipSubOptionsTransformer = new MembershipSubOptionsTransformer($this->em);
$builder->add($builder->create('membershipSubOptions', new \My\GreatBundle\Form\Type\MembershipSubOptionsType(), array(
                'required'      => true, // or false if they arent required
                'label'         => 'membership.suboptions.label',
                'attr'          => array(
                    'class'     => 'membershipSubOptionsSelect',
                    'data-placeholder' => 'Select some options'
                )
            ))->addModelTransformer($membershipSubOptionsTransformer))

现在,您已经准备好以某种方式实际处理MembershipSubOptions了。 在客户端的select中,它们每个都不过是字符串或整数,而在您的应用程序中,它们表示真实的记录/模型/实体。 表单知道现在将提交的数据传递给转换器,您仍然需要构建它。 要完成此操作而不要最终写小说,请查阅Data Transformer文档 实际的变压器比我想象的要清楚得多。

现在,您可以使用呈现表单时最初未提供的相关选项来动态填充某些选择字段。 有趣的是,数据转换器会双向运行,因此在编辑表单时,将设置当前设置的选项,并且在最初提交或更新它们时,会将它们“转换”为应用程序可以理解的内容。

我会将选项选择字段设置为隐藏,以获取没有成员资格的新记录,并在选择成员资格后将其设置为与js可见。 对于编辑表单,您需要使用表单事件(或类似方法)将可见性设置为可见。

我希望所有这些都有意义。 就像我说的那样,YMMV非常重要,但我希望这会让您走上正确的道路。 我确信还有许多其他方法可以完成您想做的事情,因此我也希望能阅读其他人的想法。 请让我们所有人都知道您最终的解决方案是什么样的,以便我们都更加了解情况。

暂无
暂无

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

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