我正在一个小型广告网站上工作,但当我尝试动态添加输入字段时,Form Events出现此问题。
在这里,我有一个实体广告:
/**
* Ad
*
* @ORM\Table(name="ma_ad")
* @ORM\Entity(repositoryClass="MA\PlatformBundle\Repository\AdRepository")
* @ORM\HasLifecycleCallbacks()
*/
class Ad
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="title", type="string", length=255)
* @Assert\Length(min=10)
*/
private $title;
/**
* @ORM\ManyToOne(targetEntity="MA\PlatformBundle\Entity\Category")
* @ORM\JoinColumn(nullable=false)
*/
private $category;
/** @var float
*
* @ORM\Column(name="speed", type="float")
* @Assert\Valid()
* @Assert\Range(min=0)
*/
private $speed;
* @var float
*
* @ORM\Column(name="area", type="float")
* @Assert\Valid()
* @Assert\Range(min=0)
*/
private $area;
。 。 。 让我们说我有两个类别,汽车和房屋当用户选择汽车时应该出现速度输入字段,当他选择安置它的区域输入字段而不是速度时。
我尝试了documentary上的内容,因此这是我的AdType:
class AdType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
/**
* @var \Doctrine\ORM\EntityManager $em
*/
$em = $options['entity_manager'];
$builder->add('title', TextType::class)
->add('category', EntityType::class, array(
'class' => 'MAPlatformBundle:Category',
'choice_label' => 'name',
'multiple' => false,
'group_by' => 'category.name'
))
$formModifier = function(FormInterface $form, Category $category = null)
{
if( $category->getName() === "Cars" ){
$form->add('speed',TextType::class);
} else if( $category->getName() === "Houses" ){
$form->add('area',TextType::class);
}
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA, function (FormEvent $event) use ( $formModifier ) {
$form = $event->getForm();
$category = $event->getData()->getCategory();
$formModifier($form, $category);
}
);
$builder->get('category')->addEventListener(
FormEvents::PRE_SUBMIT,
function( FormEvent $event ) use ( $formModifier, $em ){
$id_category = $event->getData();
$category = $em->getRepository("MAPlatformBundle:Category")->find($id_category);
$form = $event->getForm()->getParent();
$formModifier($form, $category);
});
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'MA\PlatformBundle\Entity\Annonce',
'entity_manager' => null,
));
}
最后是树枝页面:
{{ form_start( form, { 'attr': { 'class': 'form-ad' }}) }}
{{ form_row(form.title) }}
{{ form_row(form.category) }}
<div id="dynamic">
{{ form_rest(form) }}
</div>
<div class="form-group">
<div class="well">
{{ form_widget(form.save, {'attr': {'class': 'btn btn-common', 'value': 'Add'}} ) }}
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
var $category = $('#ma_platformbundle_ad_category');
$category.change( function(){
var $form = $(this).closest('form');
var data = {
'id_category': $category.val(),
};
$.ajax({
url : "{{path('ma_platform_add')}}",
type: 'POST',
data : data,
success: function (html) {
$('#dynamic').replaceWith(
$(html).find('#dynamic')
);
}
});
});
});
因此,当我选择类别时,表格没有任何变化。 我试着让你们这么简单,所以你们可以帮助我。 提前致谢。
答案 0 :(得分:0)
我认为你错过了解某些东西,预设数据事件发生在后端,所以表单永远不会自己添加字段。你需要用JS / Jquery来处理这个问题。我会建议以下......
后端的FormType
$builder->add('title', TextType::class)
->add('category', EntityType::class, array(
'class' => 'MAPlatformBundle:Category',
'choice_label' => 'name',
'multiple' => false,
'group_by' => 'category.name'
)
->add('speed',TextType::class,[//modify attr or class options to disable and hide the field])
->add('area',TextType::class,[//modify attr or class options to disable and hide the field])
)
在前端
根据需要渲染表单并使用jquery处理该字段。
//来自你的代码
$(document).ready(function () {
var $category = $('#ma_platformbundle_ad_category');
$category.change(function () {
if ($category.val() === 'some_especific_value') {
$('#dynamic').find('some_specific_input_or_div').show()//or remove disabled/hidden
} else {//some_other_specific_value
$('#dynamic').find('some_other_specific_input_or_div').show()//or remove disabled/hidden
}
});
});
此时您可以处理一些切换选项。
在后端
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
if ($event->getData()['category'] === 'house') {
$event->getForm()->remove('speed');
}else{
$event->getForm()->remove('area');
}
});
此时,您只处理选定的数据,避免产生错误。
解决方案是使用jquery处理添加字段并正确设置数据或使用表单事件删除未使用的字段。
希望它有所帮助!