Symfony2在一个表单中具有相同类的多个实体

时间:2015-03-31 14:52:16

标签: php forms symfony doctrine-orm

我想渲染一个具有多个相同类实体的表单。 我将显示2个字段,Price(type = text)和Enabled(type = checkbox)。

我不知道我将拥有多少这些实体,因此表单必须动态获取它们。

我试过以下

public function buildForm(FormBuilderInterface $builder, array $options)
{

        $builder
            ->add('price', 'text', array(
                'label' => 'Price',
                'required' => true
            ))
            ->add('enabled','checkbox',array(
                'label'     => 'Use this currency',

            ))
        ;    
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class'        => 'Osiris\Entity\Pricing',
        'csrf_protection'   => false
    ));
}

public function getName()
{
    return 'pricingtype';
}

在我的控制器中,我创建了这样的表单:

$pricingForm = $this->createFormBuilder($prices)
               ->add('items','collection',array(
                   'required' => false,
                   'prototype' => true,
                   'type'    => new PricingType(),
               ))
                ->getForm()
            ;

在我的树枝上,我做了:

{% for price in form_pricing %}
    <h2>Price</h2>
    <div class="row">{{ form_widget(price) }}</div>
{% endfor %}

然而,只有h2价格和class = row的空div。我觉得我已经走了一半,但我不知道如何继续前进。 如果有人知道如何提交字段,我将非常感激。

2 个答案:

答案 0 :(得分:2)

我找到了解决方案

我在Controller中创建表单的方式是错误的! 我必须做以下事情:

$pricingForm = $this->createFormBuilder(array('prices'=>$prices))
                ->add('prices','collection',array(
                    'required'       => true,
                    'allow_add'      => true,
                    'type'           => new PricingType(),
               ))
                ->getForm()
            ;
使用集合时,

“allow_add =&gt; true”是必需的,否则 NOT 将任何PricingType实体集合添加到表单中。

然后,因为表单是在控制器“$this->createFormBuilder(array('prices'=>$prices))”内构建的,所以$prices数组必须作为数组传递,其数组键名与“->add('prices','collection',array(...)”中使用的数组相同,这是'prices'所以Symfony会知道绑定在哪里。 $prices是一系列定价对象array(0 => new Pricing())

在我的PricingType中,我有:

class PricingType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $builder
            ->add('price', 'text', array(
                'label' => false,
                'required' => true
            ))
            ->add('enabled','checkbox',array(
                'label'     => 'Use this currency',

            ))
        ;

    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class'        =>  'XXX\XXX\Entity\Pricing',
            'csrf_protection'   => false
        ));
    }

    public function getName()
    {
        return 'pricingtype';
    }
}

这里我需要控制label属性。我找不到它的方式(如果有人知道请发布如何)。我重写我的树枝模板如下:

在顶部,我们需要下一行代码:

    {% form_theme form_pricing _self %}

然后按如下方式覆盖行和小部件(这是调试的噩梦):

{% block _form_prices_entry_row %}
    {% spaceless %}
        {{ form_widget(form) }}
    {% endspaceless %}
{% endblock %}

{% block _form_prices_entry_widget %}
    {% spaceless %}

        {{ form_row(form.price, { 'label' : form.vars.value.getCurrency().getTitle() } ) }}
        {{ form_row(form.enabled) }}

    {% endspaceless %}
{% endblock %}

然后在体内渲染表单元素如下:

{% for price in form_pricing.prices %}
                    <div class="price-row">{{ form_row(price) }}</div>
                {% endfor %}

我真的希望这会帮助你。调试特别是twig文件是一个真正的噩梦,我做到了这要归功于我聪明的同事。

答案 1 :(得分:0)

我认为你错过了twig文件中的 for loop 检查此示例:

    {# store the prototype on the data-prototype attribute #}
    <ul id="email-fields-list" data-prototype="{{ form_widget(form.emails.vars.prototype)|e }}">
    {% for emailField in form.emails %}
        <li>
            {{ form_errors(emailField) }}
            {{ form_widget(emailField) }}
        </li>
    {% endfor %}
    </ul>

看到循环,我认为你需要添加你的twig文件。

除了循环,您还需要添加 JavaScript

检查此链接:

http://symfony.com/doc/current/reference/forms/types/collection.html#adding-and-removing-items

检查完整代码。它将帮助您使用集合字段类型从单个实体类生成多个实体表单。