Foxx
14.03.2011, 16:10:18
Symfony 1.4.
Formularz rejestracji zaczyna się od wyboru typu użytkownika. Domyślnie jest to firma i rejestracja składa się z pól login, hasło i nazwa firmy. Jeżeli zostanie wybrany typ "osoba prywatna" to pole "nazwa firmy" znika i pojawiają się pola "imię" i "nazwisko".
Dane firmy są połączone relacją z tabelą z użytkownikami więc do wyświetlenia takiego mieszanego formularza (login i hasło + nazwa firmy) używam merge obu formularzy. Każde z wymienionych pól jest obowiązkowe.
Mój problem polega na tym, że jeżeli zostanie wybrana "osoba prywatna" to mimo, ze pole "nazwa firmy" jest ukrywane za pomocą JS to walidacja nadal działa i domaga się wpisania czegoś w to niewidoczne pole.
1. Jedne co mi przychodzi do głowy to deaktywacja walidacji dla tego pola już w akcji wykonywanej po wysłaniu formularza, po bind() a przed if($this->form->isValid()). Jeżeli to jest prawidłowe podejście to w jaki sposób powinna wyglądać instrukcja dla przykładowego pola?
2. Czy jest jakaś bardziej elegancka metoda na zrobienie czegoś takiego?
toffiak
14.03.2011, 18:55:22
Skoro dane firmy są w osobnej tabeli to przy wybranym typie "osoba prywatna" żadne dane/rekordy firmowe nie powinny być zapisywane a więc nazwa firmy nie musi być wymagana, podobnie jak imie i nazwisko, dzięki temu formularz przechodziłby walidację a następnie w metodzie doSave() formularza wystarczyłoby sprawdzić które pola zostały wybrane.
Czyli dla rejestracji osoby prywatnej wystarczyłoby wyczyścić zmienną łączącą formularze żeny nie tworzyć pustych rekordów a nastąpnie zapisać cały formularz a dla firmy tylko zapisać formularz, odpowiednie rekordy zostałyby dodane automatycznie.
Foxx
14.03.2011, 18:59:59
Ale zauważ, że w przypadku firmy muszę zlikwidować walidację imienia i nazwiska pozostawiając jednak resztę formularza użytkownika bo jest tam jego login i hasło. Zrobiłem to teraz za pomocą:
public function executeRejestruj($request)
{
$this->form = new UzytkownikForm();
$this->form->mergeForm(new FirmaForm());
# manipulacja walidacją
$formularz = $request->getParameter('uzytkownik');
if($formularz['typ_id'] == 1) # firma
{
$this->form->getValidator('imie')->addOption('required', false);
$this->form->getValidator('nazwisko')->addOption('required', false);
}
else # osoba
{
$this->form->getValidator('nazwa')->addOption('required', false);
}
$this->form->bind($request->getParameter('uzytkownik'));
Czy to ujdzie?
bela
14.03.2011, 22:29:17
To mówiąc szczerze mało eleganckie rozwiązanie. Myślałeś może o tym, żeby zrobić dwuetapowy formularz? (hasła: symfony multipage form, symfony form wizard)
Foxx
14.03.2011, 22:52:04
Dzielenie tak prostego formularza na dwa kroki nie będzie zbyt przyjemne dla użytkowników.
Popatrzę czym są multipage form i form wizard, dzięki.
Crozin
14.03.2011, 23:04:34
Tak naprawdę to Ty tam masz dwa różne formularze, jeden dla firm, jeden dla osób prywatnych. Tak więc utwórz sobie dwa osobne formularze, ich część wspólną możesz wrzucić do jakiejś abstrakcyjnej klasy bazowej. Później to już jedynie:
$form = $request->hasParameter('compay') ? new CompanyForm() : new IndividualForm();
$form->bind($request->getParameter($form->getName()));
Foxx
14.03.2011, 23:47:34
Dzięki.
Cysiaczek
15.03.2011, 08:20:38
Ja dość często nadpisuję metodę bind(), w której dokonuję modyfikacji walidatorów. Jeśli formularz posiada wiele różnych modyfikatorów walidacji to jest to dobra metoda.
evertras
27.03.2011, 12:23:27
Nadpisanie bind() jest chyba najlepszym rozwiązaniem w takim przypadku. Sprawdzisz sobie tylko typ wybranego konta i pozmieniasz opcje required w validatorach. Nie trzeba kombinować z dzieleniem formularza na dwuetapowe, a tym bardziej ustawianiem validacji w widoku.
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.