W ostatnim projecie musiałem stworzyć dwa pola typu select, gdzie wartości dostępne w drugim polu były zależne od wybranej opcji w pierwszego pola select. Sztandarowym przykładem może tutaj być lista województw + lista miejscowości w ramach wybranego województwa.
Sytuacja wygląda tak, że mamy pierwsze pole typu select:
$voivodeship= new Zend_Form_Element_Select( 'voivodeship' ); $voivodeship->setLabel( 'Województwo') ->setAttrib( 'onchange', 'reloadCities(this)' ) ->setRequired( true ) ->addMultiOptions( SmartGroup_Model_Voivodeship::getVoivodeshipsList);
Jak więc widać w polu tym umieszczony jest handler eventu “onchange”, który spowoduje wczytanie listy miast dla wybranego województwa i wstawienie ich do drugiego pola typu select, które jest zdefiniowane następująco:
$city= new Zend_Form_Element_Select( 'city' ); $city->setLabel( 'Miasto')
Nie będę przestawiał tutaj całej logiki stojącej za wczytaniem listy miast i wstawieniem ich do drugiego select’a, bo nie to jest przedmiotem wpisu.
Chciałem zwrócić uwagę na jedną kwestię, z którą zapewne się spotkamy dokonując submitowania tak zdefiniowanego formularza. Otóż otrzymamy wówczas błąd walidacji pola city o treści: “‘%value%’ was not found in the haystack“. Dlaczego on się pojawia, skoro nie mamy ustawionego żadnego walidatora dla tego pola. Otóż pole typu Zend_Form_Element_Select domyślnie posiada dodany walidator InArray. Jak więc nie trudno zuważyć walidator sprawdza, czy wartość danego elementu, która została zasubmitowana znajduje się na liście wartości, z którymi zostało zainicjowane dane pole. W przypadku wartości dodawanych javascriptem oczywiście warunek ten nie zostanie spełniony.
Rozwiązaniem w tej sytuacji jest metoda setRegisterInArrayValidator, która pozwala nam deaktywować walidator InArray. Wystarczy więc dodać następującą linię do definicji pola city:
$city->setRegisterInArrayValidator(false);
Spowoduje to deaktywację domyślnego walidatora i pozbycie się tego błędu.
Tym sposobem jedynie wyłączamy całkowicie pewną linię obrony, a czy jest możliwość dodania dynamicznie wartości do “stosu” doswolonych podczas pobierania AJAX’em wartości do drugiego select’a?
Przy walidacji przed sprawdzeniem calego formularza sprawdzic trzeba element od ktorego zalezna jest zawartosc select’a i jesli jest on poprawny dodac do elementu to co powinno tam byc i mozna wtedy spokojnie zwalidowac caly formularz.