Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [SF][SF3] Dynamiczne pole w formularzu w zależności od wartości pola select
Forum PHP.pl > Forum > PHP > Frameworki
swiezak
Witajcie.
Mam pewien problem z oprogramowaniem formularza w SF 3.1 z uwagi na to, że trochę wyszedłem poza relacyjność bazy danych.

Idea jest taka, że użytkownik ma możliwość dodawania wybranych produktów, zestawów produktów oraz harmonogramów dnia do "Ulubionych / Schowka".
W związku z tym zostały utworzone 4 tabele:
- product (przechowująca produkty)
- kit (zestawy produktów)
- workday (harmonogramy dnia)
- clipboard (ulubione "elementy" użytkownika).

Nie tworzyłem odrębnych tabel dla ulubionych produktów, ulubionych zestawów produktów, czy ulubionych harmonogramów dnia użytkownika.

Tabela clipboard ma m.in. następujące pola:
item_id (id produktu lub id zestawu produktów lub id harmonogramu dnia - w zależności od typu "elementu"; nie ma tu relacji z innymi tabelami)
type (typ "elementu" dodanego do "Ulubionych" - product lub kit lub workday)
user_id (id użytkownika)

Teraz w "symfoniastym" formularzu chcę wyświetlić pole typu select (przechowujące typy elementów) i w zależności od wybranej opcji wyświetlać dodatkowe pole, które będzie pobierało z bazy listę produktów lub listę zestawów produktów lub harmonogramy dnia, a następnie wyświetlało opcje do wyboru (do bazy danych ma "lecieć" tylko id elementu). W templatce z widokiem formularza do pracy zostanie poproszony Ajax, aby w zależności od dokonanego wyboru generować dynamicznie nowe pole select.

Dotychczas w ClipboardType.php mam coś takiego:
  1. class ClipboardType extends AbstractType
  2. {
  3. public function buildForm(FormBuilderInterface $builder, array $options)
  4. {
  5. $builder
  6. ->add('type', ChoiceType::class, array('placeholder' => '', 'choices' => array('Produkt' => 'product', 'Zestaw produktów' => 'kit', 'Harmonogram dnia' => 'workday'), 'required' => true))
  7. ->add('user')
  8. ;
  9.  
  10. $builder->addEventListener(
  11. FormEvents::PRE_SET_DATA,
  12. function (FormEvent $event) {
  13. $form = $event->getForm();
  14. $data = $event->getData();
  15. $type = $data->getType();
  16.  
  17. if ($type == 'product') {
  18. $form->add('itemId', EntityType::class, array(
  19. 'class' => 'DietBackendBundle:Product',
  20. 'choice_label' => 'name',
  21. 'multiple' => false,
  22. 'expanded' => false,
  23. 'group_by' => 'name',
  24. 'query_builder' => function (EntityRepository $er)
  25. {
  26. $queryBuilder = $er->createQueryBuilder('p');
  27. $query = $queryBuilder
  28. ->where($queryBuilder->expr()->isNotNULL('p.name'))
  29. ;
  30.  
  31. return $query;
  32. }
  33. ));
  34. }
  35. );
  36. }
  37.  
  38. public function configureOptions(OptionsResolver $resolver)
  39. {
  40. $resolver->setDefaults(array(
  41. 'data_class' => 'Diet\BackendBundle\Entity\Clipboard'
  42. ));
  43. }


Czy ktoś bardziej doświadczony, podpowie czy to jest optymalne rozwiązanie i w jaki sposób zapisać id przykładowo wybranego produktu?
Będę wdzięczny za wskazówki.
Pilsener
Jeśli chodzi o formularze symfony to nie ma optymalnych rozwiązań - zawsze będzie jakiś problem (a najczęściej kilka), dlatego jeśli formularz:
- wymaga własnego modelu danych
- wymaga specjalnego HTML/CSS
- wymaga wewnętrznej logiki

To lepiej obejść się bez symfony. Inaczej można spędzić kilka dni kombinując a efekt może być daleki od oczekiwań.

Np. u Ciebie użyłeś eventu PRE_SET_DATA - to jest dobre, kiedy masz np. edycję użytkownika i w zależności od jego np. roli w bazie i chcesz dodać dodatkowe pole do formularza - jednak to nie zadziała, kiedy formularz ma być zależny od danych wprowadzonych bezpośrednio przez użytkownika (czyli następne pole zależne od poprzedniego).
Tutaj wypadałoby użyć POST_SUBMIT, jednak w dokumentacji ładnie wyróżniono:
Cytat
At this point, you cannot add or remove fields to the form.
- za dużo osób o to pytało facepalmxd.gif
Dlatego zostaje tylko PRE_SUBMIT, gdzie $event->getData() zwraca tylko prostą tablicę nazwa pola => wartość pola, jednak lepsze to niż nic. Kolejny problem (jeden z wielu) to taki, że event się wykona tylko wtedy gdy user kliknie "submit", a być może potrzebujemy pola także, gdy formularz jest w stanie początkowym (wyjściowym).

Oczywiście można te problemy obejść/rozwiązać na parę sposobów, ale to już od developera zależy. Ja jeszcze nie widziałem prostego i wygodnego rozwiązania tego, ale próbuj Lkingsmiley.png
swiezak
Dzięki wielkie za zainteresowanie moim tematem i wskazówki. Formularze w Symfony 3 to czasami koszmar, kiedy trzeba skorzystać z niestandardowych rozwiązań.

Pozdrawiam.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.