首页 > 解决方案 > Symfony - 表单:按类型列出类别

问题描述

我有一个带有 EntityType 列的 formType

->add('categorie',        EntityType::class,
     [
                'class'                 => Category::class,
                'choice_label'          => 'title',
                'expanded'              => true,
                'multiple'              => true,
     ])

Category Entity 与 CategoryType Entity 有关系:

数据库上的 CategoryType 表:

ID | TITLE
1  | Sport
2  | policy

类别表:

ID | TITILE | ID_CATEGORY_TYPE
1  | Soccer | 1
2  |  Rugby | 1
3  |   USA  | 2
4  | Russia | 2

我想在表单 createView() 上按类别类型列出类别,如下所示

Sport
------
[] Soccer //Type Checkbox
[] Rugby  

Policy
------
[] USA
[] RUSSIA

是否有任何方法(在 FormType 上)通过在顶部添加类别类型的 TITLE 来修改显示列表?

标签: formssymfony

解决方案


是的,但您必须覆盖choice_widget_expanded 块。

文章类型:

use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use App\Entity\Category;

class ArticleType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('category', null, [
                    'expanded' => true,
                    'multiple' => true,
                    // make groups with the CategoryType entity
                    'group_by' => function(Category $category, $key, $value) {
                        return $category->getType()->getName();
                    },
                    // sort the categoryTypes alpabetical
                    'query_builder' => function (EntityRepository $er) {
                        return $er->createQueryBuilder('c')
                                ->join('c.type', 't')
                                ->orderBy('t.name', 'ASC');
                    },
                ])
        ;
    }
}

extended_form_layout.html.twig:

{% block choice_widget_expanded -%}
    {% if '-inline' in label_attr.class|default('') -%}
        <div class="control-group">
            {%- for child in form %}
                {{- form_widget(child, {
                    parent_label_class: label_attr.class|default(''),
                    translation_domain: choice_translation_domain,
                }) -}}
            {% endfor -%}
        </div>
    {%- else -%}
    <div {{ block('widget_container_attributes') }}>
        <div class="row">
        {% for group_label, choice in choices %}
            <div class="col-lg-3 col-md-4 col-sm-4 col-xs-6">
            <h4>{{ group_label }}</h4>
            {% for choice in choice.choices %}
                {{- form_widget(form[choice.value], {
                        parent_label_class: label_attr.class|default(''),
                        translation_domain: choice_translation_domain,
                    }) -}}
            {% endfor -%}
            </div>
            {% if not(loop.index % 3) %}</div><div class="row">{% endif %}
        {% endfor -%}
        </div>
    </div>
    {%- endif %}
{%- endblock choice_widget_expanded %}

更新:我最终得到了 Symfony ~4.3 的以下小部件:

{%- block choice_widget_expanded -%}
    <div {{ block('widget_container_attributes') }}>
    {% for group_label, choice in choices %}
        <h4>{{ choice_translation_domain is same as(false) ? group_label : group_label|trans({}, choice_translation_domain) }}</h4>
        {% for choice in choice.choices %}
            {{- form_widget(form[choice.value]) -}}
            {{- form_label(form[choice.value], null, {translation_domain: choice_translation_domain}) -}}
        {% endfor %}
    {% endfor %}
    </div>
{%- endblock choice_widget_expanded -%}

编辑.html.twig:

{% extends 'base.html.twig' %}
{% form_theme edit_form 'extended_form_layout.html.twig' %}

{{ form(edit_form) }}

推荐阅读