我想创建一个可以添加多个etape的表单。我创建这样的表单:
// FORM
namespace RBO\TryBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use RBO\TryBundle\Entity\Try;
class TryType extends AbstractType {
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('etapes', 'collection', array(
'type' => new EtapeType(),
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'label' => 'Etapes'
));
}
public function getName()
{
return 'try';
}
public function getDefaultOptions(array $options)
{
return array(
'data_class' => 'RBO\TryBundle\Entity\Try',
'csrf_protection' => true,
'csrf_field_name' => '_token',
// a unique key to help generate the secret token
'intention' => 'try_item',
);
}
}
// EtapeType
<?php
namespace RBO\TryBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use RBO\TryBundle\Entity\Etape;
class EtapeType extends AbstractType {
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('name', 'text');
}
public function getDefaultOptions(array $options)
{
return array(
'data_class' => 'RBO\TryBundle\Entity\Etape',
);
}
public function getName()
{
return 'etape';
}
}
//在树枝模板中显示
{{ form_row(form.etapes) }}
Entity Try有一个属性etapes,它是一个ArrayCollection(在构造函数中定义)
此代码对标签没有任何期望。我错过了什么吗?
先谢谢你
答案 0 :(得分:3)
我一直使用form_widget来渲染嵌入的表单,但我认为form_row也可以正常工作。您应该注意的重要事项是嵌入式表单容器是否具有“数据原型”属性。 然后,您必须将脚本添加到显示表单的页面。在我的例子中,我使用Mootools,但我猜你可以轻松地将这个脚本翻译成jQuery或任何其他javascript框架:
这些是我的js文件的内容(您应该将“XXX”替换为“data-prototype”属性所在元素的id:
window.addEvent( 'domready', function() {
var add = function() {
var collectionHolder = $('XXX');
var prototype = collectionHolder.getAttribute('data-prototype');
form = prototype.replace(/\$\$name\$\$/g, collectionHolder.getChildren().length);
var cont = Elements.from(form);
collectionHolder.adopt( cont );
}
var remove = function() {
var collectionHolder = $('XXX');
var child = collectionHolder.getLast();
child.dispose();
}
$$('a.add-link').addEvent('click', function(e){
e.stop();
add();
});
$$('a.remove-link').addEvent('click', function(e){
e.stop();
remove();
});
});
此脚本非常简单,只需添加新元素或删除集合中的最后一个元素即可。此外,您应该在视图中添加一些html,以便添加/删除链接:
<ul class="actions">
<li>
<a href="#" class="add-link">
Add
</a>
</li>
<li>
<a href="#" class="remove-link">
Remove last
</a>
</li>
</ul>
我希望它有所帮助,我是Symfony的新手,我还在学习,但它对我有用:)
答案 1 :(得分:1)
我会这样做:
{% for etape in form.etapes %}
{{ form_widget(etape.name) }}
{% endfor %}
我可能错了,因为我不使用twig-templates。但是这个想法在php-templates中适用于我。
答案 2 :(得分:0)
在PHP
模板中..
`<?php foreach ($form['etapes'] as $etapesField) : ?>
<?php echo $view['form']->errors($etapesField) ?>
<?php echo $view['form']->widget($etapesField) ?>
<?php endforeach; ?>`
答案 3 :(得分:0)
好的,有两件事:
1 - 在树枝模板中显示表单的常规方法:
{{ form_row(form) }}
模板系统能够级联(对于近似的英语对不起),这意味着表单中的所有子字段都将被呈现以及其封装形式。因此,无需通过调用 form.etapes 直接呈现孩子。
2 - 我相信你的问题实际上在于实现。如果您以这种方式创建表单:
$form = $this->createForm(new TryType()));
甚至那样:
$model = new Try();
$model->setEtapes(array());
$form = $this->createForm(new TryType(), $model));
然后表单没有呈现任何内容是正常的,因为它直接显示的Etape字段的数量取决于您为模型提供的Etape实例的数量。如果您提供一个空数组,则不会呈现Etape字段。在显示时,您应该做一个空的单个字段:
$model = new Try();
$model->setEtapes(array(new Etape())); // Empty Etape
$form = $this->createForm(new TryType(), $model));
因此,您可以在收藏类型中添加任意数量的字段:
$model = new Try();
$model->setEtapes(array(
new Etape('Étape 1'),
new Etape('Étape 2'),
...
));
$form = $this->createForm(new TryType(), $model));
答案 4 :(得分:0)
由于您使用的是子表单,请执行此操作;
$builder
->add(
'etapes',
'collection',
array(
'type' => new EtapeType(),
'allow_add' => true,
'allow_delete' => true,
)
)
->getForm()
;
你在树枝上展示的方式并不重要。这取决于你想要什么。 form_row,form_widget都应该正常工作。