1

我将逐步了解如何使用数据转换器

问题是,如果我想用 Choice 类型执行此操作怎么办?我用 jQuery 动态填充哪个?

我测试了他们提供的示例(没有创建自定义类型..),它与文本字段类型一起工作 100%,但是一旦我将它更改为选择并给它空选项它就不起作用,这是否必须加载页面后,我用 jQuery 填充选项吗?

例子

模型[选择加载有查询生成器和实体字段类型的模型实体...]

Number [一开始是空选项,当模型更改时,我对该模型的数字发出 AJAX 请求]

如果我将数字保留为文本字段并手动输入一个有效数字(查看数据库),它可以工作,但如果我将它留给 jQuery 和选择类型,它会返回一个表单错误,其中包含无效的模型值。

在这两种情况下,我在处理表单之前都在做 print_r($request->request) 并且在这两种情况下它都提交 Number => 1 这在这个例子中是正确的,但是当它的类型是 Choice 时它不会转换数据但是当它的文本。

这是 jQuery 为数字选择框填充数据的方式:

<option value=”1”&gt;1234ABCDEFG</option>

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

4

1 回答 1

2

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

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

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

我没有查看您的粘贴箱,但这是一个似乎对我有用的示例。这是一个简单的性别选择列表,我在其中添加了另一个选项客户端。preSubmit 监听器只是简单地将默认的性别选择选项替换为包含已提交内容的选项。您应该能够添加数据转换的东西并且一切顺利。

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;
    }
}
于 2013-08-22T18:44:46.317 回答