Zend Framework dostarcza programiście ogromną ilość narzędzi, które znacznie ułatwiają pracę nad aplikacjami internetowymi. Jednym z takich narzędzi jest Zend_Form. Jego wykorzystanie znacznie przyspiesza proces tworzenia formularzy wraz z walidacją i filtrowaniem wprowadzonych danych.
Formularz można stworzyć na co najmniej kilka sposobów. W zasadzie każdy, kto używa ZF od dłuższego czasu, ma swój własny styl tworzenia formularzy. Poniżej przedstawiłem mój przepis na Zend_Form.
Co powinieneś wiedzieć?
Przede wszystkim powinieneś znać Zend Framework oraz potrafić się z niego korzystać. Wszystkie przykłady przedstawione w tym artykule będą bowiem bazowały na domyślnym projekcie wygenerowanym z wiersza poleceń. Jeśli nie wiesz w jaki sposób stworzyć projekt, zapoznaj się z Zend Framework Quick Start.
Formularz jaki zostanie stworzony będzie służył do zbierania informacji o pracownikach. W jego skład będą wchodzić następujące elementy:
- imię (wymagane)
- nazwisko (wymagane)
- stanowisko (wymagane)
- opis (opcjonalne)
Budujemy klasę formularza
Moje podejście do formularzy w ZF polega na tworzeniu osobnej klasy dla każdej formatki. Każda klasa dziedziczy po Zend_Form, a kod odpowiedzialny za formularz, walidatory, dekoratory oraz filtry znajduje się w przesłoniętej metodzie init, która jest wywoływana na końcu konstruktora Zend_Form.
Najpierw pokażę jak stworzyć poszczególne elementy formularza, a następnie dodam do nich wszystkie niezbędne elementy.
class Form_Employee extends Zend_Form
{
public function init()
{
$firstname = new Zend_Form_Element_Text('firstname');
$lastname = new Zend_Form_Element_Text('lastname');
$position = new Zend_Form_Element_Select('position');
$description = new Zend_Form_Element_Textarea('description');
$submit = new Zend_Form_Element_Submit('btn-submit');
$this->addElement($firstname);
$this->addElement($lastname);
$this->addElement($position);
$this->addElement($description);
$this->addElement($submit);
}
}
Powyższa klasa przedstawia szkielet formularza. Przy użyciu klas Zend_Form_Element_* utworzone zostały wszystkie niezbędne elementy, a następnie dodane do formularza. Należy pamiętać, że kolejność dodawania elementów ma wpływ na kolejność ich wyświetlania.
W kolejnym kroku do poszczególnych elementów dodane zostaną etykiety, filtry oraz walidatory. W tym miejscu można również dodać atrybuty do elementów oraz ustalić ich kolejność (która może się różnić od kolejności dodawania elementów).
$firstname->setLabel('Imię')
->setRequired(true)
->addValidator(new Zend_Validate_NotEmpty(), true)
->addValidator(new Zend_Validate_StringLength(0, 100), true)
->addFilter(new Zend_Filter_StripTags())
->addFilter(new Zend_Filter_StringTrim());
$lastname->setLabel('Nazwisko')
->setRequired(true)
->addValidator(new Zend_Validate_NotEmpty(), true)
->addValidator(new Zend_Validate_StringLength(0, 200), true)
->addFilter(new Zend_Filter_StripTags())
->addFilter(new Zend_Filter_StringTrim());
$position->setLabel('Stanowisko')
->setRequired(true)
->addValidator(new Zend_Validate_NotEmpty(), true)
->addMultiOption(null, null)
->addMultiOptions(array(1 => 'księgowość', 2 => 'kadry', 3 => 'IT'));
$description->setLabel('Opis')
->addFilter(new Zend_Filter_StripTags())
->addFilter(new Zend_Filter_StringTrim());
$submit->setLabel('Zapisz');
Najwyższa pora wyświetlić formularz. Wystarczy, dołączyć do kontrolera plik z klasą, stworzyć nowy obiekt, a następnie przekazać go do widoku.
// akcja w kontrolerze
public function indexAction()
{
require_once APPLICATION_PATH . '/forms/Employee.php';
$form = new Form_Employee();
$this->view->form = $form;
}
<!-- widok --> <?php echo $this->form; ?>
Po uruchomieniu formularza w przeglądarce, nie da się nie zauważyć , że nie wygląda on zbyt dobrze. Szybki rzut oka na źródło i już wiadomo dlaczego. Domyślnymi znacznikami, w jakie opakowane są elementy formularza, to wspomniane wcześniej dl, dd i dt. Można to zmienić odpowiednio modyfikując dekoratory. W tym celu należy usunąć domyślne dekoratory, dodać nowe z odpowiednimi opcjami, a na koniec stworzyć plik css, zawierający style, które umieszczą wszystkie elementy na swoim miejscu.
// dekoratory
$this->clearDecorators();
$this->addDecorator('FormElements')
->addDecorator('HtmlTag', array('tag' => 'div'))
->addDecorator('Form');
$this->setElementDecorators(array(
array('ViewHelper'),
array('Errors'),
array('Label'),
array('HtmlTag', array('tag' => 'div', 'class' => 'element-group'))
));
$submit->setDecorators(array(
array('ViewHelper'),
array('HtmlTag', array('tag' => 'div', 'class' => 'submit-group'))
));
#formemployee label {
display: block;
float: left;
width: 100px;
}
#formemployee .errors {
list-style-type: none;
margin: 0;
padding: 0;
}
#formemployee .errors li {
color: #FF0000;
margin: 0;
padding: 0;
}
#formemployee .element-group, #formemployee .submit-group {
clear: left;
margin: 2px 0;
}
#formemployee .element-group textarea {
width: 300px;
height: 100px;
}
Ostatnią czynnością jaką należy wykonać, to modyfikacja domyślnych komunikatów błędów.
$firstname->getValidator('NotEmpty')->setMessages(array(
Zend_Validate_NotEmpty::IS_EMPTY => 'Proszę podać imię'
));
$firstname->getValidator('StringLength')->setMessages(array(
Zend_Validate_StringLength::TOO_LONG => 'Imię nie może zawierać więcej niż 100 znaków'
));
$lastname->getValidator('NotEmpty')->setMessages(array(
Zend_Validate_NotEmpty::IS_EMPTY => 'Proszę podać nazwisko'
));
$position->getValidator('NotEmpty')->setMessages(array(
Zend_Validate_NotEmpty::IS_EMPTY => 'Proszę wybrać stanowisko'
));
$lastname->getValidator('StringLength')->setMessages(array(
Zend_Validate_StringLength::TOO_LONG => 'Nazwisko nie może zawierać więcej niż 200 znaków'
));
W ten oto sposób napisany został formularz, który nie dość, że w każdej przeglądarce wygląda tak samo, to jeszcze jest zgodny ze standardami.
Obsługa formularza
Aby w pełni cieszyć się formularzem, należy go obsłużyć. Obsługa sprowadza się do sprawdzenia dwóch warunków – czy wysłano dane post oraz czy są one poprane – oraz do uzupełnienia formularza domyślnymi danymi (co nie jest koniczne).
public function indexAction()
{
require_once APPLICATION_PATH . '/forms/Employee.php';
$form = new Form_Employee();
$postData = array();
// czy formularz zostal wyslany
if($this->_request->isPost()) {
// pobranie danych post
$postData = $this->_request->getPost();
// walidacja danych post
if($form->isValid($postData)) {
// pobranie danych wyslanych z formularza
$formData = $form->getValues();
// operacje na danych
Zend_Debug::dump($formData);
}
}
// uzupelnij formularz domyslnymi danymi
else {
// jest to tylko przyklad. nie jest wymagane uzupelnianie
// formularza domyslnymi wartosciami
$postData['firstname'] = 'Jan';
}
// uzupelnienie formularza danymi
$form->populate($postData);
$this->view->form = $form;
}
W powyższym przykładzie na uwagę zasługuje metoda populate. Metoda ta uzupełnia formularz danymi przekazanymi w postaci tablicy, gdzie kluczem jest nazwa pola do jakiego dane mają zostać zapisane. Metoda ta doskonale nadaje się na uzupełnienie formularza danymi z bazy lub innego źródła danych.
Podsumowanie
Niniejszy artykuł miał za zadanie przedstawić możliwości jakie oferuje Zend_Form oraz zaprezentować, iż przy jego pomocy, można w krótkim czasie stworzyć dobrze wyglądający, a przede wszystkim, bezpieczny formularz. Zend Framework ma to do siebie, że jedną czynność można wykonać na wiele sposobów. Najlepszym przykładem będzie tutaj zmiana komunikatów błędów, które można modyfikować przy pomocy plików ini.
W kolejnym artykule poświęconym Zend_Form opiszę sposób tworzenia zaawansowanych formularzy zbudowanych w oparciu o Zend_Form_Subform.
Materiały do pobrania
W załączonym do tego artykule archiwum znajduje się klasa z formularzem oraz plik css.
Tworzenie_formularzy_z_wykorzystaniem_Zend_Form.zip
Czytaj dalej.