Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [php][symfony] Wszystkie pola formularza jako niewymagane, required => false?, oraz jak wstawić dane z requestu do formularza :)
luis2luis
post 20.11.2022, 08:38:22
Post #1





Grupa: Zarejestrowani
Postów: 190
Pomógł: 0
Dołączył: 25.11.2015

Ostrzeżenie: (0%)
-----


Witam.

Mam klasę formularza, w Symfony. Jest to wyszukiwarka zaawansowana. Mam problem z dwoma elementami.

1. Jak dla wszystkich pól ustawić parametr 'required' => false, aby nie były wymagane.

Pól jest ponad 20, nie chciałbym do każdego poprostu wkleić tego parametru. Myślałem, żeby w metodzie configureOptions() dodać taką opcje, w końcu jest to metoda do konfiguracji formularza, ale nie działa tak jak ja to robie .
  1. public function buildForm(FormBuilderInterface $builder, array $options): void
  2. {
  3.  
  4. $builder
  5. ->add('namne')
  6. ->add('description', TextareaType::class, ['data' => 'wpisany tekst'])
  7. ->add('deleted')
  8. ->add('prioryty')
  9. ->add('pinned')
  10. ->add('doneAt')
  11. ->add('doneByUser')
  12. ->add('remind')
  13. ->add('wontDo')
  14. .....;
  15. }
  16.  
  17. public function configureOptions(OptionsResolver $resolver): void
  18. {
  19. $resolver->setDefaults([
  20. 'data_class' => Task::class,
  21. 'required' => false, //tak nie działa
  22.  
  23. ]);
  24. }



2. Jak po wysłaniu takiego formularza, wstawić w wypełnione pola dane z requestu. Czyli jak ktos poda date kliknie "wyszukaj", żeby ta data była dalej wpisana w tym polu smile.gif

Formularz wyszukiwarki wyświetlam na roucie /tasks/list/ natomiast parametr action w formularzu odnosi się do /tasks/search/{search_phraze}

Dane te wyświetliłbym za pomocą parametru data.

Jak ten request przekazac do formularza?
  1. public function buildForm(FormBuilderInterface $builder, array $options): void
  2. {
  3.  
  4. $builder
  5. ->add('namne')
  6. ->add('description', TextareaType::class, ['data' => 'wpisany tekst'])
  7. ->add('deleted')
  8. ->add('prioryty')
  9. ->add('pinned')
  10. ->add('doneAt')
  11. ->add('doneByUser')
  12. ->add('remind')
  13. ->add('wontDo')
  14. .....;
  15. }


Będę wdzięczny za wszelkie wypowiedzi smile.gif

Ten post edytował luis2luis 20.11.2022, 09:19:23
Go to the top of the page
+Quote Post
Salvation
post 21.11.2022, 12:51:35
Post #2





Grupa: Zarejestrowani
Postów: 344
Pomógł: 70
Dołączył: 15.07.2014

Ostrzeżenie: (0%)
-----


Jak już dodasz wszystkie pola, to na końcu metody `buildForm()` wystarczy zwykła pętla po polach:
  1. foreach ($builder->all() as $field) {
  2. $field->setRequired(false);
  3. }
Go to the top of the page
+Quote Post
luis2luis
post 21.11.2022, 21:46:23
Post #3





Grupa: Zarejestrowani
Postów: 190
Pomógł: 0
Dołączył: 25.11.2015

Ostrzeżenie: (0%)
-----


Cytat(Salvation @ 21.11.2022, 12:51:35 ) *
Jak już dodasz wszystkie pola, to na końcu metody `buildForm()` wystarczy zwykła pętla po polach:
  1. foreach ($builder->all() as $field) {
  2. $field->setRequired(false);
  3. }


Dziękuje, ciekawe rozwiązanie.
Symfony zwraca błąd: "Buttons cannot be required".

Dziwna sytuacja, ponieważ przekazywana jest wartość 'false' więc not reuired smile.gif

Go to the top of the page
+Quote Post
Salvation
post 21.11.2022, 21:56:24
Post #4





Grupa: Zarejestrowani
Postów: 344
Pomógł: 70
Dołączył: 15.07.2014

Ostrzeżenie: (0%)
-----


No bo `->all()` zwróci wszystkie pola + button submit. Wrzuć przed `->setRequired()` ifa gdzie sprawdzisz typ i będzie grać.
Go to the top of the page
+Quote Post
luis2luis
post 21.11.2022, 23:18:36
Post #5





Grupa: Zarejestrowani
Postów: 190
Pomógł: 0
Dołączył: 25.11.2015

Ostrzeżenie: (0%)
-----


Cytat(Salvation @ 21.11.2022, 21:56:24 ) *
No bo `->all()` zwróci wszystkie pola + button submit. Wrzuć przed `->setRequired()` ifa gdzie sprawdzisz typ i będzie grać.


Przeleciałem dział dokumentacji Symfony, dotyczący formularzy i nie widzę nigdzie informacji, że na obiekcie FormBuilder mogę wykonać metode all() smile.gif

PHPStorm podpowiedział mi, że istnieje metoda $field->getType() ale zwróciła spory obiekt i nie widać w nim informacji o typie pola jaki własnie jest przetwarzany w pętli.

Czy metoda getType() jest odpowiednia?

  1. foreach ($builder->all() as $field) {
  2.  
  3. dump($field->getType());
  4.  
  5.  
  6. if ($field->getType() == questionmark.gif) { // :)
  7. $field->setRequired(false);
  8. }
  9.  
  10. }

Go to the top of the page
+Quote Post
Salvation
post 21.11.2022, 23:32:33
Post #6





Grupa: Zarejestrowani
Postów: 344
Pomógł: 70
Dołączył: 15.07.2014

Ostrzeżenie: (0%)
-----


Ten "spory obiekt", to na górze ma nazwę tego obiektu. Czyli potrzebujesz użyć operatora `instanceof` do porównania.

Czyli to będzie poprawny kod:
  1. foreach ($builder->all() as $field) {
  2. if (
  3. ($field->getType() instanceof SubmitType::class) ||
  4. ($field->getType() instanceof ButtonType::class) ||
  5. ($field->getType() instanceof ResetType::class)
  6. ) {
  7. continue;
  8. }
  9.  
  10. $field->setRequired(false);
  11. }
Go to the top of the page
+Quote Post
luis2luis
post 22.11.2022, 21:42:33
Post #7





Grupa: Zarejestrowani
Postów: 190
Pomógł: 0
Dołączył: 25.11.2015

Ostrzeżenie: (0%)
-----


Cytat(Salvation @ 21.11.2022, 23:32:33 ) *
Ten "spory obiekt", to na górze ma nazwę tego obiektu. Czyli potrzebujesz użyć operatora `instanceof` do porównania.



Zrobiłem to troszeczke inaczej, ale dziekuje za naprowadzenie smile.gif Nie mogłem dojść, jakiej klasy jest to instancja.
Warunek zrobiłem tak:
  1. if (
  2. ($field->getName() === 'save') ||
  3. ($field->getName() === 'hide')
  4. ) {
  5. continue;
  6. }


Ten post edytował luis2luis 22.11.2022, 21:43:39
Go to the top of the page
+Quote Post
Salvation
post 23.11.2022, 09:02:59
Post #8





Grupa: Zarejestrowani
Postów: 344
Pomógł: 70
Dołączył: 15.07.2014

Ostrzeżenie: (0%)
-----


No spoko, tylko bazując na `name` musisz pamiętać o tym, że jak się zmieni jego nazwa, to musisz też zmienić to w pętli, a w przypadku klasy pola nie będziesz musiał tego zmieniać.
No i to co wrzuciłeś, to możesz zamienić na to:
  1. if (in_array($field->getName(), ['save', 'hide'], true)) {
  2. continue;
  3. }

Wrzuć może kod z dump jaki dostajesz po wywołaniu metody `getType`.

Ten post edytował Salvation 23.11.2022, 09:05:28
Go to the top of the page
+Quote Post
luis2luis
post 24.11.2022, 11:08:30
Post #9





Grupa: Zarejestrowani
Postów: 190
Pomógł: 0
Dołączył: 25.11.2015

Ostrzeżenie: (0%)
-----


Cytat(Salvation @ 23.11.2022, 09:02:59 ) *
Wrzuć może kod z dump jaki dostajesz po wywołaniu metody `getType`.


Dump, bez rozwinięcia całości wygląda tak:
  1. ^ Symfony\Component\Form\Extension\DataCollector\Proxy\ResolvedTypeDataCollectorPr
    oxy {#731 ▼
  2. -proxiedType: Symfony\Component\Form\ResolvedFormType {#732 ▼
  3. -innerType: Symfony\Component\Form\Extension\Core\Type\DateType {#723}
  4. -typeExtensions: []
  5. -parent: Symfony\Component\Form\Extension\DataCollector\Proxy\ResolvedTypeDataCollectorPr
    oxy {#661 ▶}
  6. -optionsResolver: Symfony\Component\OptionsResolver\OptionsResolver {#733 ▶}
  7. }
  8. -dataCollector: Symfony\Component\Form\Extension\DataCollector\FormDataCollector {#647 ▼
  9. #data: array:3 [▶]
  10. -dataExtractor: Symfony\Component\Form\Extension\DataCollector\FormDataExtractor {#648}
  11. }
  12. }
Go to the top of the page
+Quote Post
Salvation
post 24.11.2022, 12:44:18
Post #10





Grupa: Zarejestrowani
Postów: 344
Pomógł: 70
Dołączył: 15.07.2014

Ostrzeżenie: (0%)
-----


O widzisz, tego szukałem:
Kod
-innerType: Symfony\Component\Form\Extension\Core\Type\DateType

Nie mam jak sprawdzić teraz poprawności poniższego kodu, ale powinien za działać...
  1. foreach ($builder->all() as $child) {
  2. $fieldType = $child->getType()?->getProxiedType()?->getInnerType();
  3.  
  4. if (
  5. ($fieldType instanceof SubmitType::class) ||
  6. ($fieldType instanceof ButtonType::class) ||
  7. ($fieldType instanceof ResetType::class)
  8. ) {
  9. continue;
  10. }
  11.  
  12. $field->setRequired(false);
  13. }
Go to the top of the page
+Quote Post
luis2luis
post 24.11.2022, 13:58:07
Post #11





Grupa: Zarejestrowani
Postów: 190
Pomógł: 0
Dołączył: 25.11.2015

Ostrzeżenie: (0%)
-----


Cytat(Salvation @ 24.11.2022, 12:44:18 ) *
O widzisz, tego szukałem:
Kod
-innerType: Symfony\Component\Form\Extension\Core\Type\DateType

Nie mam jak sprawdzić teraz poprawności poniższego kodu, ale powinien za działać...



Dziękuje bardzo za pomoc jeszcze raz smile.gif Teraz kod wygląda dużo lepiej i jest bardziej uniwersalny.

Troszeczkę zmodyfikowałem Twój kod i działa. Usunąłem "?->getProxiedType()" i przy klasach zapis "::class"

  1. foreach ($builder->all() as $field) {
  2.  
  3. $fieldType = $field->getType()?->getInnerType();
  4.  
  5. if (
  6. ($fieldType instanceof SubmitType) ||
  7. ($fieldType instanceof ButtonType) ||
  8. ($fieldType instanceof ResetType)
  9. ) {
  10. continue;
  11. }
  12.  
  13. $field->setRequired(false);
  14.  
  15. }
  16.  


Gdzie można poczytać o tych metodach np. getInnerType() to jest integralna część Symfony?

Znalazłem coś takiego np: https://symfony.com/doc/current/components/...s_resolver.html

Ten post edytował luis2luis 24.11.2022, 13:58:39
Go to the top of the page
+Quote Post
Salvation
post 24.11.2022, 14:17:38
Post #12





Grupa: Zarejestrowani
Postów: 344
Pomógł: 70
Dołączył: 15.07.2014

Ostrzeżenie: (0%)
-----


Cytat(luis2luis @ 24.11.2022, 13:58:07 ) *
Usunąłem "?->getProxiedType()" (...)

OK, faktycznie. Masz rację.
Tutaj cała klasa: https://github.com/symfony/symfony/blob/6.2...lectorProxy.php

Cytat(luis2luis @ 24.11.2022, 13:58:07 ) *
Gdzie można poczytać o tych metodach np. getInnerType() to jest integralna część Symfony?

Integralna część komponentu. Sam komponent możesz używać poza frameworkiem. A wyżej już podałem link do repo.

Cytat(luis2luis @ 24.11.2022, 13:58:07 ) *

OptionsResolver, to trochę inny komponent.

Ten post edytował Salvation 24.11.2022, 14:33:16
Go to the top of the page
+Quote Post
luis2luis
post 24.11.2022, 14:19:49
Post #13





Grupa: Zarejestrowani
Postów: 190
Pomógł: 0
Dołączył: 25.11.2015

Ostrzeżenie: (0%)
-----


Cytat(Salvation @ 24.11.2022, 14:17:38 ) *
Przywróć `::class`, bo to przechowuje pełny namespace dla obiektu, a jak wiadomo, klasa może nazywać się tak samo, ale mieć inny namespace i możesz mieć problem...
Poczytaj o FQCN (Fully-Qualified Class Name).


po przywróceniau ::class Symfony wyrzuca błąd.

Cytat
syntax error, unexpected token "class", expecting variable or "$"
Go to the top of the page
+Quote Post
Salvation
post 24.11.2022, 14:35:44
Post #14





Grupa: Zarejestrowani
Postów: 344
Pomógł: 70
Dołączył: 15.07.2014

Ostrzeżenie: (0%)
-----


Tak, już usunąłem głupoty co powypisywałem... wink.gif
Go to the top of the page
+Quote Post
luis2luis
post 24.11.2022, 14:56:05
Post #15





Grupa: Zarejestrowani
Postów: 190
Pomógł: 0
Dołączył: 25.11.2015

Ostrzeżenie: (0%)
-----


Cytat(Salvation @ 24.11.2022, 14:35:44 ) *
Tak, już usunąłem głupoty co powypisywałem... wink.gif


Dziękuje za pomoc i fatygę, jestem bardzo wdzięczny smile.gif

Czy odpłatnie zgodziłbyś się poasekurować przy takim prostym treningowym projekcie Symfony "todo"? Jakieś tam drobne pytania od czasu do czasu? smile.gif

Ten post edytował luis2luis 24.11.2022, 14:59:14
Go to the top of the page
+Quote Post
Salvation
post 24.11.2022, 15:34:59
Post #16





Grupa: Zarejestrowani
Postów: 344
Pomógł: 70
Dołączył: 15.07.2014

Ostrzeżenie: (0%)
-----


Jesteśmy na forum, możesz zakładać tematy do woli. Nie zawsze mam czas na odpisanie pomiędzy 7:00 a 17:00.
Go to the top of the page
+Quote Post
luis2luis
post 24.11.2022, 15:37:11
Post #17





Grupa: Zarejestrowani
Postów: 190
Pomógł: 0
Dołączył: 25.11.2015

Ostrzeżenie: (0%)
-----


Cytat(Salvation @ 24.11.2022, 15:34:59 ) *
Jesteśmy na forum, możesz zakładać tematy do woli. Nie zawsze mam czas na odpisanie pomiędzy 7:00 a 17:00.


ok rozumie smile.gif
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 28.04.2024 - 07:46