选择字段类型的Symfony2数据转换器 [英] Symfony2 Data transformer on a Choice field type

查看:197
本文介绍了选择字段类型的Symfony2数据转换器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将一步一步地使用如何使用数据转换器



问题是,如果我想用Choice类型来做到这一点?我动态地使用jQuery填充?



我测试了它们提供的示例(不创建自定义类型..),并且它与文本字段类型一起工作100%一旦我改变它的选择,并给它空的选择它不起作用,这是否与我填充页面加载后的jQuery的选择?



示例



模型 [选择模型实体加载查询构建器和实体字段类型...]

数字 [首先是空的选择,当模型更改时,我对该模型的Numbers进行AJAX请求]

如果我将Number作为文本字段并手动输入有效数字(查看数据库),但是如果将它留给jQuery和Choice类型,它将返回一个表单错误,其中包含无效值在这两种情况下,我都在处理表单之前执行print_r($ request-> request),并且在这两种情况下,它都会提交Number => 1在这个例子中它是正确的,但不知何故,当它的类型是Choice时,它不会变换数据,但是当它的Text有它时。

这就是jQuery填充数字选择框的数据:

 < option value =1> 1234ABCDEFG< / option> 

顺便说一下,我正在使用Id进行转换,这将是所选选项的值。 / p>

解决方案

好的。你需要做的是听取preSubmit表单事件,然后通过将它添加到你的选择元素来基本接受提交的值。



http://symfony.com/doc/current/cookbook/form/ dynamic_form_modification.html#cookbook-form-events-submitted-data

================== =====================================



我没有看你的贴纸箱,但这是一个似乎适用于我的例子。这是一个简单的性别选择列表,我添加了另一个选项客户端。 preSubmit监听器只是用一个包含任何提交的选项来替换默认的性别选择选项。你应该能够添加数据转换的东西,并很好的去。

 命名空间Cerad \ Bundle \ TournBundle \ Form\Type\Test; 

使用Symfony \Component\Form\AbstractType;
使用Symfony \Component\Form\FormBuilderInterface;
使用Symfony \Component\Form\FormFactoryInterface;

使用Symfony \Component\Form\FormEvent;
使用Symfony \Component\Form\FormEvents;
使用Symfony \ Component \EventDispatcher\EventSubscriberInterface;

class DynamicFormType extends AbstractType
{
public function getName(){return'cerad_tourn_test_dynamic'; }

public function buildForm(FormBuilderInterface $ builder,array $ options)
{
$ builder-> add('gender','choice',array(
'选择'=>阵列('m'=>'男','f'=>'女'),
'required'=> false,
));
$ builder-> addEventSubscriber(new DynamicFormListener($ builder-> getFormFactory()));
}
}
类DynamicFormListener实现EventSubscriberInterface
{
private $ factory;

public function __construct(FormFactoryInterface $ factory)
{
$ this-> factory = $ factory;

$ b $ public static function getSubscribedEvents()
{
return array(
FormEvents :: PRE_SUBMIT =>'preSubmit',
FormEvents :: PRE_SET_DATA =>'preSetData',
);
}
public function preSetData(FormEvent $ event)
{
//不需要
return;

public function preSubmit(FormEvent $ event)
{
$ data = $ event-> getData();
$ gender = $ data ['gender'];
if(!$ gender)return; //如果没有选择任何内容

$ form = $ event-> getForm();

/ * ======================================== =========
*我们所需要做的就是用包含$性别值的
替换它。一旦完成了$ form-> isValid()就会通过
*
*我的确尝试将选项添加到现有的性别选择
*,但无法看到如何去做。
* $ genderForm = form-> get('gender'); //返回一个Form对象
* $ genderForm-> addNewOptionToChoicesList ???
*
*可能希望查找'任何',但只有在
*才能发挥作用,如果表单验证失败并将其返回给用户
*您也可以使用客户端JavaScript用正确的值替换'whatever'
* /
$ form-> add($ this-> factory-> createNamed('gender','choice',null ,数组(
'choices'=>数组($ gender =>'whatever'),
'required'=> false,
'auto_initialize'=> false,
)));
return;
}
}


I am going step by step with the How to use Data Transformers

The problem is that what if I want to do this with a Choice type? Which I dynamically populate with jQuery?

I tested the example they provide (without creating a custom type..) and it works 100% with the text field type, but as soon as I change it to choice and give it empty choices it doesn't work, does this have to do with me populating the choices with jQuery after the page is loaded?

Example

Model [Select with the Model entity loaded with the query builder and Entity field type...]

Number [Empty choice at first, when the Model changes I make an AJAX request for the Numbers of that Model]

If I leave the Number as a text field and I manually type a valid number (looking at the database) it works, but if I leave it to jQuery and a Choice type it returns a form error with an invalid value for the Model.

In both cases I'm doing print_r($request->request) before handling the form and in both cases it submits Number => 1 which is correct in this example, but somehow it's not transforming the data when its type is Choice but when its Text it does.

This is how jQuery is populating the data for the Number select box:

<option value="1">1234ABCDEFG</option>

Btw, I'm transforming with the Id, which would be the value of the option selected.

解决方案

Ok. What you need to do is to listen to the preSubmit form event and then basically accept the submitted value by adding it to your choice element.

http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#cookbook-form-events-submitted-data

=======================================================

I didn't look at your paste bin but here is an example that seems to work for me. It's a simple gender choice list to which I add another option client side. The preSubmit listener simply replaces the default gender choice options with an option containing whatever was submitted. You should be able to add in data transform stuff and be good to go.

namespace Cerad\Bundle\TournBundle\Form\Type\Test;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormFactoryInterface;

use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class DynamicFormType extends AbstractType
{
    public function getName() { return 'cerad_tourn_test_dynamic'; }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('gender', 'choice', array(
            'choices'   => array('m' => 'Male', 'f' => 'Female'),
            'required'  => false,
        ));
        $builder->addEventSubscriber(new DynamicFormListener($builder->getFormFactory()));
    }
}
class DynamicFormListener implements EventSubscriberInterface
{
    private $factory;

    public function __construct(FormFactoryInterface $factory)
    {
        $this->factory = $factory;
    }

    public static function getSubscribedEvents()
    {
        return array(
            FormEvents::PRE_SUBMIT   => 'preSubmit',
            FormEvents::PRE_SET_DATA => 'preSetData',
        );
    }
    public function preSetData(FormEvent $event)
    {
        // Don't need
        return;
    }
    public function preSubmit(FormEvent $event)
    {
        $data = $event->getData();
        $gender = $data['gender'];
        if (!$gender) return; // If nothing was actually chosen

        $form = $event->getForm();

        /* =================================================
         * All we need to do is to replace the choice with one containing the $gender value
         * Once this is done $form->isValid() will pass
         *
         * I did attempt to just add the option to the existing gender choice 
         * but could not see how to do it.  
         * $genderForm = form->get('gender'); // Returns a Form object
         * $genderForm->addNewOptionToChoicesList ???
         * 
         * Might want to look up 'whatever' but that only comes into play
         * if the form fails validation and you paas it back to the user
         * You could also use client side javascript to replace 'whatever' with the correct value
         */
        $form->add($this->factory->createNamed('gender','choice', null, array(
            'choices'   => array($gender => 'whatever'),
            'required'  => false,
            'auto_initialize' => false,
        )));
        return;
    }
}

这篇关于选择字段类型的Symfony2数据转换器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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