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
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 (IMG:style_emoticons/default/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 (IMG:style_emoticons/default/smile.gif)

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





Grupa: Zarejestrowani
Postów: 406
Pomógł: 73
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
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 (IMG:style_emoticons/default/smile.gif)

Go to the top of the page
+Quote Post
Salvation
post
Post #4





Grupa: Zarejestrowani
Postów: 406
Pomógł: 73
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
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() (IMG:style_emoticons/default/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() == (IMG:style_emoticons/default/questionmark.gif) ) { // :)
  7. $field->setRequired(false);
  8. }
  9.  
  10. }

Go to the top of the page
+Quote Post
Salvation
post
Post #6





Grupa: Zarejestrowani
Postów: 406
Pomógł: 73
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
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 (IMG:style_emoticons/default/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
Post #8





Grupa: Zarejestrowani
Postów: 406
Pomógł: 73
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
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
Post #10





Grupa: Zarejestrowani
Postów: 406
Pomógł: 73
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
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 (IMG:style_emoticons/default/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
Post #12





Grupa: Zarejestrowani
Postów: 406
Pomógł: 73
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
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
Post #14





Grupa: Zarejestrowani
Postów: 406
Pomógł: 73
Dołączył: 15.07.2014

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


Tak, już usunąłem głupoty co powypisywałem... (IMG:style_emoticons/default/wink.gif)
Go to the top of the page
+Quote Post
luis2luis
post
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... (IMG:style_emoticons/default/wink.gif)


Dziękuje za pomoc i fatygę, jestem bardzo wdzięczny (IMG:style_emoticons/default/smile.gif)

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

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





Grupa: Zarejestrowani
Postów: 406
Pomógł: 73
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
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 (IMG:style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post

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

 



RSS Aktualny czas: 5.10.2025 - 21:34