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

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

问题描述

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

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.

表格:

<?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 选项并且没有验证.

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

    // ...
}

这有效,但我无法测试它,因为它在设置值时抛出 IllegalArgumentException 并且只是假定默认值.有没有更好的解决方案?提前致谢!

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!

推荐答案

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

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天全站免登陆