Symfony2:用ajax和验证改变选择 [英] Symfony2: Change choices with ajax and validation

查看:115
本文介绍了Symfony2:用ajax和验证改变选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

场景:我有一个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()
);
}

私有函数loadChoices()
{
//根据$ this->类别从$ DB加载它们
}
}

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

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

一我找到的方法是在控制器中重新创建表单:

 <?php 

$ form = $ this-> createForm(new MyType()); $
$ b 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 ,并且只是假定为默认值。有没有更好的解决方案?提前致谢!

解决方案

我认为你必须使用Events来管理这个,这是更正确的方法。 b
$ b $ $ $ p $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ,'choice',array(
'choices'=> array(
'foo'=>'foo',
'bar'=>'bar'

));

$ ff = $ builder-> getFormFactory();

//函数动态添加'template'选择字段
$ func = function(FormEvent $ e)use($ ff){
$ data = $ e->的getData();
$ form = $ e-> getForm();
if($ form-> has('template')){
$ form-> remove('template');

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

//在这里你可以用一种方式填充你的选择u在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')));
};

//在PreSet和PreBind上注册上面的EventListener函数
uilder-> addEventListener(FormEvents :: PRE_SET_DATA,$ func);
$ builder-> addEventListener(FormEvents :: PRE_BIND,$ func);
}


Scenario: I have a form with 2 selects. When user selects something from the first select, the second select gets populated with new values. This part works fine.

But the form does not get validated since it contains some choices that are not allowed in the initial form.

Form:

<?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
    }
}

Initially the category is foo. So the templates for foo get loaded and set as choices. But if the user selects bar, the bar templates get loaded. But the form still has the foo choices and does not validate.

What is the best way to solve this?

One way I found was to just reinitiate the form in the controller:

<?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']));
    }

    // ...
}

This works, but I cannot test it because it throws IllegalArgumentException when setting the value and just assumes default. Is there any better solution to this? Thanks in advance!

解决方案

I think u have to use Events to manage this, which is more correct way

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);
}

这篇关于Symfony2:用ajax和验证改变选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆