Symfony2 - 为实体字段设置选定的值

时间:2022-10-16 18:35:06

I'm trying to set a selected value inside an entity field. In accordance with many discussions I've seen about this topic, I tried to set the data option but this doesn't select any of the values by default:

我正在尝试在实体字段中设置选定的值。根据我在这个主题上看到的许多讨论,我尝试设置数据选项,但默认情况下不会选择任何值:

class EventType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('place', 'entity', array(
                'class' => 'RoyalMovePhotoBundle:Place',
                'property' => 'name',
                'empty_value' => "Choisissez un club",
                'mapped' => false,
                'property_path' => false,
                'data' => 2
            ))
            ->add('begin')
            ->add('end')
            ->add('title')
            ->add('description')
        ;
    }

    // ...
}

By looking for more I've found that some people had to deactivate the form mapping to the entity. That seems logical so I tried to add 'mapped' => false to the options, without success...

通过寻找更多,我发现有些人不得不停用映射到实体的表单。这似乎合乎逻辑,所以我试图在选项中添加'mapped'=> false,但没有成功......

If it can help, here's my controller:

如果它可以帮助,这是我的控制器:

class EventController extends Controller
{
    // ...

    public function addAction()
    {
        $request = $this->getRequest();
        $em = $this->getDoctrine()->getManager();

        $event = new Event();
        $form = $this->createForm(new EventType(), $event);

        $formHandler = new EventHandler($form, $request, $em);

        if($formHandler->process()) {
            $this->get('session')->getFlashBag()->add('success', "L'évènement a bien été ajouté.");
            return $this->redirect($this->generateUrl('photo_event_list'));
        }

        return $this->render('RoyalMovePhotoBundle:Event:add.html.twig', array(
            'form' => $form->createView()
        ));
    }
}

And the EventHandler class:

和EventHandler类:

class EventHandler extends AbstractHandler
{
    public function process()
    {
        $form = $this->form;
        $request = $this->request;

        if($request->isMethod('POST')) {
            $form->bind($request);

            if($form->isValid()) {
                $this->onSuccess($form->getData());
                return true;
            }
        }

        return false;
    }

    public function onSuccess($entity)
    {
        $em = $this->em;

        $em->persist($entity);
        $em->flush();
    }
}

I'm a bit stuck right now, is there anyone who got an idea?

我现在有点卡住,有没有人有想法?

4 个解决方案

#1


24  

You only need set the data of your field:

您只需要设置字段的数据:

    
    class EventController extends Controller
    {
        // ...

        public function addAction()
        {
           $request = $this->getRequest();
            $em = $this->getDoctrine()->getManager();

            $event = new Event();
            $form = $this->createForm(new EventType(), $event);

            // -------------------------------------------
            // Suppose you have a place entity..
            $form->get('place')->setData($place);
            // That's all..
            // -------------------------------------------

            $formHandler = new EventHandler($form, $request, $em);

            if($formHandler->process()) {
                $this->get('session')->getFlashBag()->add('success', "L'évènement a bien été ajouté.");
                return $this->redirect($this->generateUrl('photo_event_list'));
            }

            return $this->render('RoyalMovePhotoBundle:Event:add.html.twig', array(
                'form' => $form->createView()
            ));
        }
    }
    

#2


7  

In order to option appear selected in the form, you should set corresponding value to entity itself.

为了在表单中显示选项,您应该为实体本身设置相应的值。

$place = $repository->find(2);
$entity->setPlace($place);
$form = $this->createForm(new SomeFormType(), $entity);
....

#3


1  

For non-mapped entity choice fields, the method I found easiest was using the choice_attr option with a callable. This will iterate over the collection of choices and allow you to add custom attributes based on your conditions and works with expanded, multiple, and custom attribute options.

对于非映射的实体选择字段,我发现最简单的方法是使用带有可调用的choice_attr选项。这将迭代选择集合,并允许您根据条件添加自定义属性,并使用扩展,多个和自定义属性选项。

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('place', 'entity', array(
            //...
            'choice_attr' => function($place) {
                $attr = [];
                if ($place->getId() === 2) {
                    $attr['selected'] = 'selected';
                    //for expanded use $attr['checked'] = 'checked';
                 }
                 return $attr;
            }
       ))
       //...
    ;
}

#4


0  

When you use the query_builder option, and the data option expects an collection instance, and you don't want to touch your controller by adding setDatas for only certain fields, and you already have your querybuilder and the ids of the repopulating options in your form type class, you can repopulate a selection as following:

当您使用query_builder选项时,data选项需要一个集合实例,并且您不想通过仅为某些字段添加setDatas来触摸您的控制器,并且您已经拥有了querybuilder和表单中重新填充选项的ID在类类中,您可以按以下方式重新填充选择:

// Querybuilder instance with filtered selectable options
$entities = $qb_all; 
// Querybuilder instance filtered by repopulating options (those that must be marked as selected)
$entities_selected = $qb_filtered; 

Then in your add() Method

然后在你的add()方法中

'data' => $entities_selected->getQuery()->getResult(), // Repopulation
'query_builder' => $entities,

EDIT: Real use case example

编辑:真实用例示例

You want to repopulate a checkbox group rendered with following elements:

您想要重新填充使用以下元素呈现的复选框组:

Label: What is your favourite meal?

标签:你最喜欢的一餐是什么?

4 Checkboxes: Pasta, Pizza, Spaghetti, Steak

4个复选框:意大利面,比萨饼,意大利面,牛排

And you want to repopulate 2 Checkboxes:

你想重新填充2个复选框:

Pizza, Steak

比萨饼,牛排

$qb_all would be a QueryBuilder instance with the all 4 selectable Checkboxes

$ qb_all将是一个具有所有4个可选复选框的QueryBuilder实例

$qb_filtered would be a new additional QueryBuilder instance with the repopulating Checkboxes Pizza, Steak. So a "filtered" version of the previous one.

$ qb_filtered将是一个新的额外QueryBuilder实例,其中包含重新填充的Checkboxes Pizza,Steak。所以是前一个版本的“过滤”版本。

#1


24  

You only need set the data of your field:

您只需要设置字段的数据:

    
    class EventController extends Controller
    {
        // ...

        public function addAction()
        {
           $request = $this->getRequest();
            $em = $this->getDoctrine()->getManager();

            $event = new Event();
            $form = $this->createForm(new EventType(), $event);

            // -------------------------------------------
            // Suppose you have a place entity..
            $form->get('place')->setData($place);
            // That's all..
            // -------------------------------------------

            $formHandler = new EventHandler($form, $request, $em);

            if($formHandler->process()) {
                $this->get('session')->getFlashBag()->add('success', "L'évènement a bien été ajouté.");
                return $this->redirect($this->generateUrl('photo_event_list'));
            }

            return $this->render('RoyalMovePhotoBundle:Event:add.html.twig', array(
                'form' => $form->createView()
            ));
        }
    }
    

#2


7  

In order to option appear selected in the form, you should set corresponding value to entity itself.

为了在表单中显示选项,您应该为实体本身设置相应的值。

$place = $repository->find(2);
$entity->setPlace($place);
$form = $this->createForm(new SomeFormType(), $entity);
....

#3


1  

For non-mapped entity choice fields, the method I found easiest was using the choice_attr option with a callable. This will iterate over the collection of choices and allow you to add custom attributes based on your conditions and works with expanded, multiple, and custom attribute options.

对于非映射的实体选择字段,我发现最简单的方法是使用带有可调用的choice_attr选项。这将迭代选择集合,并允许您根据条件添加自定义属性,并使用扩展,多个和自定义属性选项。

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('place', 'entity', array(
            //...
            'choice_attr' => function($place) {
                $attr = [];
                if ($place->getId() === 2) {
                    $attr['selected'] = 'selected';
                    //for expanded use $attr['checked'] = 'checked';
                 }
                 return $attr;
            }
       ))
       //...
    ;
}

#4


0  

When you use the query_builder option, and the data option expects an collection instance, and you don't want to touch your controller by adding setDatas for only certain fields, and you already have your querybuilder and the ids of the repopulating options in your form type class, you can repopulate a selection as following:

当您使用query_builder选项时,data选项需要一个集合实例,并且您不想通过仅为某些字段添加setDatas来触摸您的控制器,并且您已经拥有了querybuilder和表单中重新填充选项的ID在类类中,您可以按以下方式重新填充选择:

// Querybuilder instance with filtered selectable options
$entities = $qb_all; 
// Querybuilder instance filtered by repopulating options (those that must be marked as selected)
$entities_selected = $qb_filtered; 

Then in your add() Method

然后在你的add()方法中

'data' => $entities_selected->getQuery()->getResult(), // Repopulation
'query_builder' => $entities,

EDIT: Real use case example

编辑:真实用例示例

You want to repopulate a checkbox group rendered with following elements:

您想要重新填充使用以下元素呈现的复选框组:

Label: What is your favourite meal?

标签:你最喜欢的一餐是什么?

4 Checkboxes: Pasta, Pizza, Spaghetti, Steak

4个复选框:意大利面,比萨饼,意大利面,牛排

And you want to repopulate 2 Checkboxes:

你想重新填充2个复选框:

Pizza, Steak

比萨饼,牛排

$qb_all would be a QueryBuilder instance with the all 4 selectable Checkboxes

$ qb_all将是一个具有所有4个可选复选框的QueryBuilder实例

$qb_filtered would be a new additional QueryBuilder instance with the repopulating Checkboxes Pizza, Steak. So a "filtered" version of the previous one.

$ qb_filtered将是一个新的额外QueryBuilder实例,其中包含重新填充的Checkboxes Pizza,Steak。所以是前一个版本的“过滤”版本。