Symfony 2表单实体字段类型分组

8
我正在使用Symfony2渲染一个表单,数据类映射到“Reservation”实体,并且该表单具有实体字段类型,类为“Service”。 “Reservation”和“Service”类之间的关系是多对多。然后,服务有一个“ServiceType”,这是另一个类,从“Service”类映射为多对一。
我想做的是在预订表单中按服务类型分组显示所有服务复选框。到目前为止,我可以像这样一起显示所有服务(代码来自“ReservationType”类):
$builder->add('services','entity', array(
         'class' => 'MyBundle:Service',
         'multiple' => true,
         'expanded'  => true
 ));

并以默认方式显示表单:

<form action="{{ path('reservations', {'step': 2}) }}" method="post" {{    form_enctype(form) }}>
   {{ form_widget(form) }}

   <input type="submit" />
</form> 

结果大致如下:
 □ servicetype1 option
 □ servicetype1 another option
 □ servicetype2 option
 □ servicetype2 another option

我希望实现的目标是:

servicetype1:
   option
   another option
servicetype2:
   option
   another option

我正在尝试使用query_builder选项来指定服务的子集,例如:

    $builder->add('services','entity', array(
            'class' => 'MyBundle:Service',
            'multiple' => true,
            'expanded' => true,
            'query_builder' => function (\My\Bundle\Entity\ServiceRepository $repository)
                {return $repository->createQueryBuilder('s')->where('s.serviceType = ?1')->setParameter(1, 1);} ));
    $builder->add('services','entity', array(
            'class' => 'MyBundle:Service',
            'multiple' => true,
            'expanded' => true,
            'query_builder' => function (\My\Bundle\Entity\ServiceRepository $repository)
                {return $repository->createQueryBuilder('s')->where('s.serviceType = ?1')->setParameter(1, 2);} ));

这是错误的,因为:

  1. 我必须指定ServiceType id
  2. 'services'两次添加到构建器中将覆盖第一次添加的内容(这是合乎逻辑的,但不能通过更改实体来解决)

如何处理这种表单的最佳选项是什么?目前只有2个ServiceType-s,但我希望它保持动态和可重用。


我遇到了类似的问题 - kuboslav
我有类似的问题。这是我的问题链接。当您完成此任务时,您能写一些示例吗? - rtyshyk
2个回答

9

我想唯一的方法就是在模板中覆盖渲染。你应该将MyBundle:Service实体传递给你的模板,并像这样进行渲染:

{% for service in services %}    
    <b>{{ service.name }}</b><br>
    {% for option in service.options %}                    
        <label>
            <input type="checkbox" name="form_type_name[options][{{ option.id }}]" value="{{ option.id }}" {% if option in user.services.options %}checked="checked"{% endif %}>
            {{ option.name }}
        </label>
    {% endfor %}
{% endfor %}

1
是的,您的意思是将其从控制器传递到模板,避免在表单的这一部分使用FormType吗?这不会使可重用性降低一些吗? - Teo.sk
最终还是使用了这个解决方案。谢谢/Díky :) - Teo.sk

2
这可以通过使用group_by选项来解决:
$builder->add('services','entity', array(
    'class' => 'MyBundle:Service',
    'group_by' => 'serviceType',
    'multiple' => true,
    'expanded'  => true
));

太好了,很高兴看到他们添加了这个选项。重新接受它,因为它更简单。 - Teo.sk
4
在这种情况下,选项 expanded => true 不起作用。文档中指出:“它仅在呈现为选择标记时起作用”。 - jkucharovic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接