Symfony 2 Form,字段集合不显示

发布于 2024-12-08 03:24:48 字数 1700 浏览 0 评论 0原文

我想创建一个可以添加多个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';
}

}

// Display in twig template

{{ form_row(form.etapes) }}

实体 Try 有一个属性 etapes,它是一个 ArrayCollection(在构造函数中定义)

此代码不会渲染除标签之外的任何内容。我错过了什么吗?

提前谢谢你

I would like to create a form which can add multiple etape. I create the form like this:

//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';
}

}

// Display in twig template

{{ form_row(form.etapes) }}

The Entity Try have a property etapes which is an ArrayCollection (defined in the constructor)

This code render nothing expect the label. Did I miss something?

Thank you by advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

萌辣 2024-12-15 03:24:48

我一直使用 form_widget 来渲染嵌入表单,但我认为 form_row 也可以正常工作。您应该注意的重要事情是嵌入式表单容器是否具有“数据原型”属性。
然后,您必须将脚本添加到显示表单的页面。就我而言,我使用 Mootools,但我想您可以轻松地将这个脚本转换为 jQuery 或任何其他 javascript 框架:

这些是我的 js 文件的内容(您应该将“XXX”替换为“data”所在元素的 id) -prototype”属性是:

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 的新手,我仍在学习,但它对我有用:)

I have always used form_widget to render embedded forms, but I think form_row will work fine too. The important thing you should look at is if the embedded form container has a "data-prototype" attribute.
Then, you must add a script to the page where you are displaying the form. In my case, I use Mootools, but I gues you can easily translate this script to jQuery or any other javascript framework:

These are the contents of my js file (you should replace "XXX" for the id of the element where the "data-prototype" attribute is:

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();
});

});

This script is very simple, and just adds new elements or removes the last element in the collection. Besides, you should add some html to your view in order to have add/remove links:

<ul class="actions">
<li>
    <a href="#" class="add-link">
        Add
    </a>
</li>
<li>
    <a href="#" class="remove-link">
        Remove last
    </a>
    </li>
</ul>

I hope it helps, I'm new to Symfony and I'm still learning, but it worked for me :)

浮华 2024-12-15 03:24:48

我会这样做:

{% for etape in form.etapes %}
  {{ form_widget(etape.name) }}
{% endfor %}

我可能是错的,因为我不使用树枝模板。但这个想法在 php-templates 中对我有用。

I would do it in a such way:

{% for etape in form.etapes %}
  {{ form_widget(etape.name) }}
{% endfor %}

I could be wrong, because I don't use twig-templates. But this idea worked for me in php-templates.

单身情人 2024-12-15 03:24:48

在 PHP 模板中..

    `<?php foreach ($form['etapes'] as $etapesField) : ?>
<?php echo $view['form']->errors($etapesField) ?>
<?php echo $view['form']->widget($etapesField) ?>
<?php endforeach; ?>`

In PHP Templates..

    `<?php foreach ($form['etapes'] as $etapesField) : ?>
<?php echo $view['form']->errors($etapesField) ?>
<?php echo $view['form']->widget($etapesField) ?>
<?php endforeach; ?>`
一袭白衣梦中忆 2024-12-15 03:24:48

好的,有两件事:

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));

Ok, two things:

1 - The regular way to display your form in a twig template:

    {{ form_row(form) }}

The templating system is able to cascade (sorry for the approximate english), meaning that all sub-fields in a form will be rendered as well as its encapsulating form. Thus, no need to render the children directly by calling form.etapes.

2 - I believe your problem really lies in the instanciation. If you create your form that way:

    $form = $this->createForm(new TryType()));

Or even that way:

    $model = new Try();
    $model->setEtapes(array());

    $form = $this->createForm(new TryType(), $model));

Then it is normal that your form renders nothing, because the number of Etape fields that it displays directly depends on the amount of Etape instances you feed your model with. If you provide it an empty array, no Etape fields will be rendered. What you should do to have an empty single field when displaying it is:

    $model = new Try();
    $model->setEtapes(array(new Etape())); // Empty Etape

    $form = $this->createForm(new TryType(), $model));

You can thusly add as many fields as you please in your collection type:

    $model = new Try();
    $model->setEtapes(array(
        new Etape('Étape 1'),
        new Etape('Étape 2'),
        ...
    ));

    $form = $this->createForm(new TryType(), $model));
陌路黄昏 2024-12-15 03:24:48

由于您使用的是子表单,因此请执行此操作;

$builder
    ->add(
        'etapes',
        'collection',
        array(
            'type'          => new EtapeType(),
            'allow_add'     => true,
            'allow_delete'  => true,
        )
    )
    ->getForm()
;

你如何在 Twig 中显示并不重要。这取决于你想要什么。
form_row、form_widget 都应该正常工作。

Since you are using a sub-form, do this;

$builder
    ->add(
        'etapes',
        'collection',
        array(
            'type'          => new EtapeType(),
            'allow_add'     => true,
            'allow_delete'  => true,
        )
    )
    ->getForm()
;

And how you display in twig doesn't really matter. It depends on what you want.
form_row, form_widget all should work properly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文