我想要呈现一个具有同一类的多个实体的表单。我将显示两个字段,价格(类型=文本)和启用(类型=复选框)。
我不知道我会有多少这样的实体,所以表单必须动态地获取它们。
我试着做了以下
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' => 'OsirisEntityPricing',
'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。我觉得我已经走了一半,但我不知道如何继续前进。如果有人知道如何在提交时获得字段,我将非常感激。
我找到了解决方案,
我在Controller中创建表单的方式是错误的!我不得不做以下事情:
$pricingForm = $this->createFormBuilder(array('prices'=>$prices))
->add('prices','collection',array(
'required' => true,
'allow_add' => true,
'type' => new PricingType(),
))
->getForm()
;
"allow_add=>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' => 'XXXXXXEntityPricing',
'csrf_protection' => false
));
}
public function getName()
{
return 'pricingtype';
}
}
这里我需要控制标签属性。我找不到它的路(如果有人知道请张贴如何)。我覆盖我的小树枝模板如下:
在顶部,我们需要下一行代码:
{% 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 %}
我真的希望这对你们有帮助。调试真是一场噩梦,尤其是调试trick文件,多亏了我聪明的同事,我才做到了。
我认为您在Twitch文件中错过了一个for循环检查此示例:
{# 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>
看到这个循环,我认为你需要添加到你的小树枝文件中。
除了循环,您还需要添加JavaScript。
检查此链接:
http://symfony.com/doc/current/reference/forms/types/collection.html#adding-和删除项目
检查完整的代码。它将帮助您使用集合字段类型从单个实体类生成多个实体窗体。