Symfony2:用ajax和验证改变选择 [英] Symfony2: Change choices with ajax and validation
问题描述
但是表单没有得到验证,因为它包含了一些初始表单中不允许的选项。
$
<?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屋!