经过多天试图找出Symfony到Cookbook的条目...... http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html
我终于得到了第三个例子来处理我的ProductType.php文件中的以下代码(见下文)。
当我添加游戏时,当我点击提交按钮时会出现相应的服务器和类别列表。如果我通过在其中一个字段中输入无效输入来强制显示错误,则仅显示新字段。
我有两个问题。如果$ formModifier变量中没有的所有数据都有效,则它会提交数据,但我没有看到“服务器”和“类别”选项。即使在选择游戏之前我不需要显示“服务器”和“类别”,我如何确保“服务器”和“类别”。
第二个问题是在食谱中输入它说“可能仍然缺少的一件事是在选择运动后你的表格的客户端更新。这应该通过向你的应用程序发回AJAX来处理。在该控制器中,您可以提交表单,但只需使用提交的表单呈现更新的字段,而不是处理它。“
由于我的事件修饰符处于“提交”状态,我如何提交具有所选游戏(id)的控制器条目,并仅渲染仅在选择游戏后才需要的字段?
先谢谢。
斯科特
<?php
namespace Acme\MainBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Doctrine\ORM\EntityRepository;
use Symfony\Component\Form\FormInterface;
use Acme\MainBundle\Entity\Game;
class ProductsType extends AbstractType {
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('name')
->add('price')
->add('description')
->add('game')
;
// ** Build Form Interface Based On Selected Game **//
$formModifier = function(FormInterface $form, Game $game, $game_id) {
// ** Add Servers Based On Game Id ** //
$form->add('server', 'entity', array(
'class' => 'Acme\MainBundle\Entity\GameServers',
'query_builder' => function(EntityRepository $er) use ($game_id) {
$query = $er->createQueryBuilder('i')
->select(array('i'))
->where('i.game_id = :game_id')
->setParameter('game_id', $game_id)
->orderBy('i.name', 'ASC');
return $query;
},
)
);
// ** Build Category List Based on Game Id Submitted ** //
// Refactor this so that is nothing is selected that it Doesn't Build Category List **/
$form->add('category', 'entity', array(
'class' => 'Acme\MainBundle\Entity\GameCategories',
'query_builder' => function(EntityRepository $er) use ($game_id) {
$query = $er->createQueryBuilder('i')
->select(array('i'))
->where('i.game_id = :game_id')
->setParameter('game_id', $game_id)
->orderBy('i.name', 'ASC');
return $query;
},
)
);
};
//** Checks for Games That Are Submitted and Adds Servers and Categories Based on Game Selection **//
$builder->get('game')->addEventListener(
FormEvents::POST_SUBMIT, function(FormEvent $event) use ($formModifier) {
// Get Form Data to Pass Back to Modifier
$game = $event->getForm()->getData();
// Get Game Id to pass back to Form Modifier
$game_id = $event->getForm()->getData()->getId();
$formModifier($event->getForm()->getParent(), $game, $game_id);
}
);
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array(
'data_class' => 'Acme\MainBundle\Entity\Products'
));
}
/**
* @return string
*/
public function getName() {
return 'acme_mainbundle_products';
}
}
答案 0 :(得分:1)
我找到了这个SO条目How to handle Ajax forms with collections in Symfony2.3
的ajax部分的答案这是我的实现
的javascript
$(document).ready(function () {
$('#acme_mainbundle_products_game').change(function(){
if($(this).val()){
$.ajax({
type: "POST",
url: "{{ url('productsCreateSubmit') }}",
data: $(this).serialize(),
success: function(data) {
$('#dynamic_fields').html(data);
}
});
return false;
}
});
});
/new.html.twig中的twig
{%extends':: base.html.twig'%}
{%block body - %}
<h1>Products creation</h1>
{{ form_start(form) }}
<hr />
{{ form_label(form.name) }}
{{ form_errors(form.name) }}
{{ form_widget(form.name) }}
<hr />
{{ form_label(form.price) }}
{{ form_errors(form.price) }}
{{ form_widget(form.price) }}
<hr />
{{ form_label(form.description) }}
{{ form_errors(form.description) }}
{{ form_widget(form.description) }}
<hr />
{{ form_label(form.game) }}
{{ form_errors(form.game) }}
{{ form_widget(form.game) }}
<hr />
<div id="dynamic_fields">Stuff Will Go Here</div>
{{ form_end(form) }}
serverslist.twig.html
<hr />
{{ form_label(form.server) }}
{{ form_errors(form.server) }}
{{ form_widget(form.server) }}
<hr />
<hr />
{{ form_label(form.category) }}
{{ form_errors(form.category) }}
{{ form_widget(form.category) }}
<hr />
最后是控制器条目
/**
* @Route("/products/create/submit", name="productsCreateSubmit")
*/
public function productsCreateSubmitAction(Request $request) {
$products = new Products();
$form = $this->createForm(new ProductsType(), $products);
$form->handleRequest($request);
return $this->render('AcmeMainBundle:Products:serverslist.html.twig', array(
'form' => $form->createView(),
));
}
我仍然需要完成验证,但这就是我如何使用ajax来渲染必需的字段。它似乎是正确的,它的工作原理,但如果有人有任何反馈,如何做得更好,我很乐意听到反馈。
答案 1 :(得分:0)
我认为获得$ game对象时会出现问题:
//** Checks for Games That Are Submitted and Adds Servers and Categories Based on Game Selection **//
$builder->get('game')->addEventListener(
FormEvents::POST_SUBMIT, function(FormEvent $event) use ($formModifier) {
// Get Form Data to Pass Back to Modifier
$game = $event->getForm()->getData()->getGame();
// Get Game Id to pass back to Form Modifier
$game_id = $game->getId();
$formModifier($event->getForm()->getParent(), $game, $game_id);
}
);
并且您不使用$ game对象,在$ formModifier中仅使用$ game_id。所以你可以改变你的功能:
$formModifier = function(FormInterface $form, $game_id) {
//Adding other widgets here
}