Symfony2:使用 ajax 和验证更改选择

Posted

技术标签:

【中文标题】Symfony2:使用 ajax 和验证更改选择【英文标题】:Symfony2: Change choices with ajax and validation 【发布时间】:2012-10-30 13:57:20 【问题描述】:

场景:我有一个包含 2 个选择的表单。当用户从第一个选择中选择某些内容时,第二个选择会填充新值。这部分工作正常。

但是表单没有得到验证,因为它包含一些初始表单中不允许的选项。

表格:

<?php

class MyType extends AbstractType

    private $category;

    public function __construct($category = null)
    
        $this->category = $category;
    

    public function buildForm(FormBuilderInterface $builder, array $options)
    
        $builder->add('category', 'choice', array(
            'choices' => array(
                'foo' => 'foo',
                'bar' => 'bar'
            )
        );

        $builder->add('template', 'choice', array(
            'choices' => $this->loadChoices()
        );
    

    private function loadChoices()
    
        // load them from DB depending on the $this->category
    

最初的类别是foo。因此 foo 的模板被加载并设置为选项。但是如果用户选择bar,就会加载条形模板。但是表单仍然有 foo 选项并且不验证。

解决这个问题的最佳方法是什么?

我发现的一种方法是在控制器中重新启动表单:

<?php

$form = $this->createForm(new MyType());

if ($request->getMethod() === 'POST') 
    if ($request->request->has($form->getName())
        && isset($request->request->get($form->getName())['category'])) 
            $form = $this->createForm(new MyType($request->request->get($form->getName())['category']));
    

    // ...

这可行,但我无法对其进行测试,因为它在设置值时会抛出 IllegalArgumentException 并假设为默认值。有没有更好的解决方案?提前致谢!

【问题讨论】:

您是否尝试为您必须验证的每组选项设置验证组?然后,您只能在与您相关的组上调用验证器服务。 symfony.com/doc/2.0/book/forms.html#validation-groups 【参考方案1】:

我认为你必须使用事件来管理这个,这是更正确的方式

public function buildForm(FormBuilderInterface $builder, array $options)

    $builder->add('category', 'choice', array(
        'choices' => array(
            'foo' => 'foo',
            'bar' => 'bar'
        )
    ));

    $ff = $builder->getFormFactory();

    // function to add 'template' choice field dynamically 
    $func = function (FormEvent $e) use ($ff) 
        $data = $e->getData();
        $form = $e->getForm();
        if ($form->has('template')) 
            $form->remove('template');
        

        $cat = isset($data['category'])?$data['category']:null;

        // here u can populate ur choices in a manner u do it in loadChoices
        $choices = array('1' => '1', '2' => '2');
        if ($cat == 'bar') 
            $choices = array('3' => '3', '4' => '4');
        

        $form->add($ff->createNamed('template', 'choice', null, compact('choices')));
    ;

    // Register the function above as EventListener on PreSet and PreBind
    $builder->addEventListener(FormEvents::PRE_SET_DATA, $func);
    $builder->addEventListener(FormEvents::PRE_BIND, $func);

【讨论】:

抱歉这里回复晚了!我今天会检查它。 :) 我被推荐使用此链接来解决我正在尝试解决的类似问题(我一直希望将 AJAX 与 onChange 触发器一起使用)。这种方式看起来很好,虽然我想在更改所有内容之前检查:当未能提交表单时,可以刷新表单填充数据库查找的template 987654323 @下拉列表吗? span> 为什么不呢。但是如果我正确理解您的问题,您需要一个单独的 ajax 端点来重新呈现表单而无需提交逻辑等。

以上是关于Symfony2:使用 ajax 和验证更改选择的主要内容,如果未能解决你的问题,请参考以下文章

symfony2 上的 AJAX 跨域

带有 RESTful 身份验证的 Symfony2 应用程序,使用 FOSRestBundle 和 FOSUserBundle

在 ajax 提交时禁用 symfony 2 csrf 令牌保护

Symfony2 基于两个字段的表单验证

使用 ajax 和 Symfony2 上传文件

symfony2 表单验证单选按钮