简体   繁体   中英

Symfony2 - Set a selected value for the entity field

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...

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:

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?

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

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);
....

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.

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;
            }
       ))
       //...
    ;
}

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:

// 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

'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

And you want to repopulate 2 Checkboxes:

Pizza, Steak

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM