Symfony 2表单,字段集合不显示

时间:2011-10-04 20:57:24

标签: forms collections symfony

我想创建一个可以添加多个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(在构造函数中定义)

此代码对标签没有任何期望。我错过了什么吗?

先谢谢你

5 个答案:

答案 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都应该正常工作。