2013-04-01 29 views
9

Próbuję ustawić wybraną wartość wewnątrz pola encji. Zgodnie z wielu dyskusji widziałem na ten temat, próbowałem ustawić opcję data ale to nie wybrać żadnej z wartości domyślnie:Symfony2 - Ustaw wybraną wartość dla pola encji

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

    // ... 
} 

Patrząc na bardziej Odkryłam, że niektóre ludzie musieli dezaktywować mapowanie formularzy na jednostkę. Że wydaje się logiczne, więc starałem się dodać 'mapped' => false do opcji, bez powodzenia ...

Jeśli to może pomóc, oto mój kontroler:

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

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

Trochę utknąłem w tej chwili, czy jest ktoś, kto ma pomysł?

Odpowiedz

24

wystarczy ustawić dane swojej dziedzinie:

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

+1

Naprawdę nie pamiętam, ale myślę, że już wcześniej próbowałem tego, bez powodzenia. Cóż, zaakceptuję to jako odpowiedź, ponieważ nie mogę w tej chwili wypróbować twojego rozwiązania (nie pracuję już nad tym projektem), wydaje się, że jest to bardziej logiczny sposób. – Nesk

7

Aby ustawić opcję wybraną w formularzu, należy ustawić odpowiednią wartość dla samej jednostki.

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

Właściwie, przepraszam za pierwszy komentarz, działa, to był błąd po mojej stronie! –

+1

W rzeczywistości już to zrobiłem, ale zapomniałem wspomnieć o tym w pytaniu. Zmontowałem to. Dzięki za pomoc. – Nesk

0

Podczas korzystania z opcji query_builder, a opcja data przewiduje wystąpienie zbiórki, a ty don” t chcesz dotknąć kontrolera, dodając setDatas tylko dla niektórych pól, a masz już swój querybuilder i identyfikatory opopulacji ns w formularzu klasy typu można repopulate wybór następująco:

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

Następnie w add() Metoda

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

EDIT: Prawdziwe przypadek użycia przykładem

Chcesz ponownie zaludnić grupę pól wyboru wykonaną za pomocą następujących elementów:

Label: What is your favourite meal?

4 Checkboxes: Pasta, Pizza, Spaghetti, Steak

I chcesz repopulate 2 wyboru:

Pizza, Steak

$qb_all byłoby wystąpienie QueryBuilder z wszystkich 4 wybieralne Checkboxes

$qb_filtered byłoby nowa dodatkowa instancja QueryBuilder z repopulating Ch eckboxes Pizza, Steak. Tak więc "przefiltrowana" wersja poprzedniej.

+0

Proszę wyjaśnij to lepiej. Co to jest '$ qb_all' i co' 'qb_filtered' w prawdziwym przypadku użycia? –

+0

@ purchased777 Dodałem EDYCJĘ do mojego posta. Czy teraz jest bardziej przejrzysty? –

0

Dla non-mapped pola wyboru podmiotu, sposób znalazłem najłatwiejszy był używając opcji choice_attr z callable. Spowoduje to powtórzenie wyboru kolekcji i pozwoli na dodanie niestandardowych atrybutów na podstawie warunków i będzie działać z rozszerzonymi, wieloma i niestandardowymi opcjami atrybutów.

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