Symfony formbuilder自引用实体分组

时间:2014-01-04 11:47:21

标签: symfony doctrine-orm self-reference formbuilder

我想要一个按父类别分组的选项列表(下拉列表)(不可选)。 这甚至可能吗?

Example:
 - Vehiculs (not selectable)
 -- Car (selectable)
 -- Boat (selectable)
 - Computers (not selectable)

实体类别

    /**
     * @ORM\OneToMany(targetEntity="Category", mappedBy="parent")
     **/
    private $children;

    /**
     * @ORM\ManyToOne(targetEntity="Category", inversedBy="children")
     * @ORM\JoinColumn(name="parent_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
     **/
    private $parent;

形式:

public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title', 'text',
                [
                    'attr' => ['placeholder' => 'Titel', 'class' => 'form-control', 'autocomplete' => 'off'],
                    'label' => false
                ]
            )
            ...
            ->add('category', 'entity',
                [
                    'property' => 'name',
                    'class' => '***ArticleBundle:Category',
                ]
            )
        ;
    }

使用上面的代码我只能得到父母,他们是可选择的。 我想将这些父母的孩子(1个深度)分组,并且只为孩子选择选项。

2 个答案:

答案 0 :(得分:1)

只是张贴这个,因为这似乎是第一个谷歌打击这个问题,我不得不解决它。

你实际上可以直接告诉symfony在FormBuilder中创建一个树选择,其中有一个完全干净的小解决方法。

“实体”是“选择”的孩子的事实有很多帮助。该解决方案由三部分组成:Controller,FormType和Entity Repository 让我们从Controller

开始
$em = $this->getDoctrine()->getManager();    
$form = $this->createForm(new AcmeType(array(
            'repository' => $em->getRepository('AcmeBundle:Category'),
        )), $data, array(
            'action' => *add your route here*
            'method' => 'POST'
        ));

直接生成表单,但存储库的添加作为FormType的参数(我们需要它)

您的FormType包含以下内容

    /** @var CategoryRepository */
    protected $repository;

    public function __construct($options = array()){
        $this->repository = $options['repository'];
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            *add your other stuff here*
            ->add('category', 'entity', array(
                'empty_value' => 'Please Select...',
                'required' => true,
                'choices' => $this->repository->getCategoryData(),
                'class' => 'Acme\AcmeBundle\Entity\Category'
            ))
        ;
    }

我们创建一个实体字段类型并添加“选项”并使用“getCategoryData”的响应填充它。

在您的数据实体的存储库(在本例中为类别实体)中,您将创建以下函数

public function getCategoryOptions()
{
    $data = array();
    $categories = $this
        ->createQueryBuilder('c')
        ->select('c')
        ->getQuery()
        ->getResult();

    foreach( $categories as $category ){
        /** @var Category $category */
        if( !$category->getParent() ){
            continue;
        }
        if(!array_key_exists($category->getParent()->getName(), $data) ){
            $data[$category->getParent()->getName()] = array();
        }
        $data[$category->getParent()->getName()][$category->getId()] = $category;
    }
    return $data;
}

这个简单的函数对数据库进行简单的查询以选择你的类别,然后通过它们运行foreach并构建一个数组。如上面的FormType所示,它直接将该数组解析为Entity字段类型的'choices'参数。 symfony的Form Renderer非常聪明,可以添加带标签的标签。

Et瞧,你有一个带有不可选择的“父母”的分组下拉框。

答案 1 :(得分:0)

您无法直接告诉symfony在表单构建器中创建树选择。

首先,你必须在这里查看; http://symfony.com/doc/current/reference/forms/types/entity.html

您可以在实体字段上使用查询构建器来获取父子关系,但父母也可以选择。

所以你必须寻找另一个这样的解决方案: How to disable specific item in form choice type?