我正在尝试创建一个包含嵌套集合的窗体。我不知道如何处理JS部分来显示children集合。有人知道我该怎么做吗?
下面是我的表单代码:
class ParentFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('case', 'choice', array(
'choices' => array(
'case1' => 'case1',
'case2' => 'case2',
'case3' => 'case3',
)))
->add ('subForm1', 'collection', array (
'type' => new Sub1FormType(),
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'prototype' => true,
))
;
$builder->add('save',"submit") ;
}
public function setDefaultOptions(OptionsResolverInterface $resolver) {
}
public function getName() {
return 'formtestparenttype';
}
}
class Sub1FormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('fieldSub1',"text" )
->add ('childForm1', 'collection', array (
'type' => new Sub2FormType,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'prototype' => true,
))
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver) {
}
public function getName() {
return 'formtestsub1type';
}
}
class Sub2FormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('fieldSub2',"text" )
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver) {
}
public function getName() {
return 'formtesttype';
}
}
字符串
控制器:
$form = $this->createForm(new ParentFormType() ) ;
return $this->render('MyBundle:Test:test.html.twig', array(
'form' => $form->createView()
));
型
在这里; twig + js部分:
{% extends '::base.html.twig' %}
{% block content %}
{{ form_start(form) }}
<h3>Tags</h3>
<ul class="collectionHolder" data-prototype="{{ form_widget(form.subForm1.vars.prototype)|e }}">
{# iterate over each existing tag and render its only field: name #}
{% for subForm1 in form.subForm1 %}
<li>{{ form_row(subForm1) }} </li>
<ul class="collectionHolder" data-prototype="{{ form_widget(subForm2.vars.prototype)|e }}">
{%for subForm2 in subForm1.subForm2 %}
<li>{{ form_row(subForm2) }}</li>
{% endfor %}
{% endfor %}
</ul>
{{ form_end(form) }}
<script>
var $collectionHolder;
// setup an "add a tag" linkd
var $addTagLink = $('<a href="#" class="add_tag_link">Add</a>');
var $newLinkLi = $('<li></li>').append($addTagLink);
jQuery(document).ready(function() {
function addTagForm($collectionHolder, $newLinkLi)
{
// Get the data-prototype explained earlier
var prototype = $collectionHolder.data('prototype');
// get the new index
var index = $collectionHolder.data('index');
// Replace '__name__' in the prototype's HTML to
// instead be a number based on how many items we have
var newForm = prototype.replace(/__name__/g, index);
// increase the index with one for the next item
$collectionHolder.data('index', index + 1);
// Display the form in the page in an li, before the "Add a tag" link li
var $newFormLi = $('<li></li>').append(newForm);
$newLinkLi.before($newFormLi);
}
$collectionHolder = $('.collectionHolder');
$collectionHolder.append($newLinkLi);
// count the current form inputs we have (e.g. 2), use that as the new
// index when inserting a new item (e.g. 2)
$collectionHolder.data('index', $collectionHolder.find(':input').length);
$addTagLink.on('click', function(e) {
e.preventDefault();
addTagForm($collectionHolder, $newLinkLi);
});
});
</script>
{% endblock content %}
型
2条答案
按热度按时间polkgigr1#
你的问题是示例JavaScript并没有被写成一次处理多个集合。
我写了一个单独的JavaScript文件,在处理这些表单集合时,我总是包含它:
字符串
在所需的模板中,我只需通过id来定位集合,并添加通过id示例化FormCollection,例如:
型
wrrgggsh2#
以防其他人遇到这个问题。我经历了同样的麻烦,这里我认为**是这种行为的原因。
请随时纠正我,如果我的情况不应该是常规的Symfony行为,是由于我的错误。
我认为我的问题是在原型过程中。
为什么symfony不创造第二,第三...集合中的第n个子元素,是因为第二级集合的原型不像第一级集合那样是“空白”的。
第一级集合“空白”原型看起来像这样(对于输入部分):
someObject_collection___name___
,其中___name___
将被集合索引替换,因此在文档的JavaScript中使用replace(/__name__/g, index)
。但是对于第二级集合,原型不是“空白”的,而是用第一级集合的相关元素的索引生成的,如:
someObject_collection_1__otherCollection_1_
,而不是我以为的someObject_collection_1__otherCollection__name__
。因此,当为第二级集合调用
replace
函数时,找不到匹配项,无法用新的子索引替换___name___
。解决方案是更改第二级集合的
replace
调用,将第一级集合的元素索引替换为第二级集合的当前元素索引。这将是这样的:
newForm.replace(/collection_\d/g, 'collection_' + index);
,用于label
标记的for
属性和input
标记的id
属性。比如说:
newForm.replace(/\[ligneCPackProds\]\[\d\]/g, '[collection][' + index + ']');
,用于input
标记的name
属性。通过这样做,我能够让我所有的孩子在我的第二级收藏。