Question

I want a choice list (dropdown) grouped by parent categories (not selectable). Is this even possible?

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

Entity Category

    /**
     * @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;

Form:

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',
                ]
            )
        ;
    }

With the code above i only get the parents and they are selectable. I would like to group the children of those parents (1 depth) and make only the children selectable options.

Était-ce utile?

La solution 2

You can not directly tell symfony to create a tree select in form builder.

First, you have to check here; http://symfony.com/doc/current/reference/forms/types/entity.html

You can use query builder on your entity field to get parent - child relation but parents also would be selectable.

So you have to look another solutions like this: How to disable specific item in form choice type?

Autres conseils

Just posting this because this seems to be the first google hit for this problem and I had to solve it.

You in fact can directly tell symfony to create a tree select in FormBuilder with a small workaround which is totally clean.

The fact that the "Entity" is a child of "Choice" helps there a lot. The solution consists of three parts: Controller, FormType and Entity Repository Let's start with the 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'
        ));

Straight forward form generation, except the adition of the repository as a parameter for your FormType (which we need there)

Your FormType includes the following

    /** @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'
            ))
        ;
    }

We create an Entity field type and add the "choices" and fill it with the response from the "getCategoryData".

In your Repository of your Data Entity (in this case Category Entity) you create the following function

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;
}

This simple function does a simple query to the Database to select your Categories and then runs a foreach through them and builds an array. As seen in the FormType above it parses that array directly to the 'choices' parameter of your Entity field type. The Form Renderer of symfony is smart enough to add tags with labels.

Et voila, you have a grouped dropdown box with non-selectable "Parents".

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top