-->

Option groups in symfony2 entity form type

2019-06-04 20:15发布

问题:

Is there any way an entity field can be shown grouped in option groups in symfony2 (v.2.1), for example I have something like this in my form class:

$builder->add('account',
                    'entity',
                    array(
                        'class' => 'MyBundle\Entity\Account',
                        'query_builder' => function(EntityRepository $repo){
                            return $repo->findAllAccounts();
                        },
                        'required'  => true,
                        'empty_value' => 'Choose_an_account',
                    );

But (of course) they are displayed as the repository class reads it from the db and I would like to display them grouped in the combobox. This post mentions that featured added to the 2.2 release out of the box, but what options do we 2.1 users have?

The Grouping would be based on a field called Type, lets say I have a getter for that called getType() in my Account entity that returns a string.

Thanks.

回答1:

I did a similar thing when handling with categories.

First, when you build the form, pass the list of choices as a result from a function getAccountList() as follows:

 public function buildForm(FormBuilderInterface $builder, array $options){
        $builder        
            ->add('account', 'entity', array(
                'class' => 'MyBundle\Entity\Account',
                'choices' => $this->getAccountList(),
                'required'  => true,
                'empty_value' => 'Choose_an_account',
            ));
}  

The function should do something like follows (the content depend on the way you structure your result).

private function getAccountList(){
    $repo = $this->em->getRepository('MyBundle\Entity\Account');

    $list = array();

    //Now you have to construct the <optgroup> labels. Suppose to have 3 groups
    $list['group1'] = array();
    $list['group2'] = array();
    $list['group3'] = array(); 

    $accountsFrom1 = $repo->findFromGroup('group1'); // retrieve your accounts in group1.
    foreach($accountsFrom1 as $account){
        $list[$name][$account->getName()] = $account;
    }
    //....etc

    return $list;
} 

Of course, you can do it more dynamics! Mine is just a brief example!

You also have to pass the EntityManager to your custom form class. So, define the constructor:

class MyAccountType extends AbstractType {

    private $em;

    public function __construct(\Doctrine\ORM\EntityManager $em){
        $this->em = $em; 
    }    
} 

And pass the EntityManager when you initiate the MyAccountType object.