W poprzednim tekście poświęconym formularzom w Zend Framework-u, pokazałem jak w prosty i szybki sposób można stworzyć bezpieczny formularz, wykorzystując do tego Zend_Form. Dzisiaj pokażę w jaki sposób można stworzyć skomplikowany formularz, zawierający dwie kolumny z kontrolkami oraz podpowiedzi (tooltip).  By nie przesłonić głównego celu tego wpisu, nie będę dodawał filtrów i walidatorów do elementów formularza oraz napiszę maksymalnie uproszczony kod dla tooltip-a.

Jak się za chwilę przekonacie, najwięcej pracy należy włożyć nie w kodowanie formularza, a w jego ostylowanie. CSS bowiem jest tutaj najważniejszym graczem. ZF ma niewiele do powiedzenia. Do wyświetlania/ukrywania tooltip-a użyłem jQuery. Ponadto zresetowałem style. Niestety w chwili obecnej mam do dyspozycji jedynie Fx3.5 oraz IE8, więc nie przetestowałem wyglądu na innych przeglądarkach.

A teraz do rzeczy. Kod formularza różni się od poprzedniego (opisanego w pierwszym wpisie nt. Zend_Form) jedynie w dwóch miejscach. Pierwsza różnica to użycie metody addDisplayGroup, druga to ustawienie dekoratorów dla zgrupowanych elementów.

<?php
class Form_Adv extends Zend_Form
{
	public function init()
	{
		$this->setName('form-adv');

		$name = new Zend_Form_Element_Text('name');
		$tags = new Zend_Form_Element_Text('tags');
		$groups = new Zend_Form_Element_MultiCheckbox('groups');
		$description = new Zend_Form_Element_Textarea('description');
		$submit = new Zend_Form_Element_Submit('btn-submit');
		
		$name->setLabel('Nazwa');
		$tags->setLabel('Tagi')
			 ->setDescription('Oddziel tagi przecinkiem');
		$groups->setMultiOptions(array('Grupa 1', 'Grupa 2'));
		$description->setLabel('Opis');
		$submit->setLabel('Zapisz');
		
		$this->addElement($name);
		$this->addElement($tags);
		$this->addElement($groups);
		$this->addElement($description);

		$this->addDisplayGroup(array('name', 'tags'), 'basic');
		$this->addDisplayGroup(array('groups'), 'checkbox');
		$this->addDisplayGroup(array('description'), 'details');

		$this->addElement($submit);

		$this->clearDecorators();
		$this->addDecorator('FormElements')
			 ->addDecorator('HtmlTag', array('tag' => 'div'))
			 ->addDecorator('Form');

		$this->setDisplayGroupDecorators(array(
			array('FormElements'),
			array('Fieldset')
		));

		$this->setElementDecorators(array(
			array('ViewHelper'),
			array('Label'),
			array('Errors'),
			array('Description'),
			array('HtmlTag', array('tag' => 'div', 'class' => 'element-group'))
		));

		$submit->setDecorators(array(
			array('ViewHelper'),
			array('HtmlTag', array('tag' => 'div', 'class' => 'submit-group'))
		));
	}
}

Wszystkie elementy, które mają zostać zgrupowane, muszą być dodane do formularza, ponieważ metoda addDisplayGroup, jako pierwszy parametr przyjmuje tablicę z nazwami istniejących  już elementów. Drugim parametrem jest nazwa grupy, na podstawie której wygenerowany zostanie identyfikator.

Po przypisaniu odpowiednich elementów do grup, możemy sprawdzić co za potworek nam powstał. Jeśli zajrzymy w źródło wygenerowanego formularza, zauważymy, że elementy zostały zagnieżdżone w znaczniku  fieldset, do którego wepchnięto tagi dt, dd i dl. Aby się ich pozbyć, trzeba zmodyfikować dekoratory. Robimy to przy pomocy metody setDisplayGroupDecorators. Ustawiamy interesujące nas dekoratory oraz dodajemy dekorator Description do elementów formularza w celu wyświetlenia tooltip-a  i możemy przejść do CSS-a.

#formadv label {
	display: block;
	float: left;
	width: 80px;
	line-height: 20px;
}

#formadv .element-group, #formemployee .submit-group {
	clear: left;
	margin: 2px 0;
}

#formadv .element-group textarea {
	width: 300px;
	height: 100px;
}

#formadv #fieldset-checkbox label {
	display: inline;
	float: none;
	line-height: normal;
}

#formadv .hint {
	display: none;
	position: absolute;
	width: 100px;
	border: 1px solid #707070;
	background-color: #DBDBDB;
	padding: 5px;
	text-align: center;	
}

#formadv #fieldset-basic {
	width: 300px;
	float: left;
}

#formadv #fieldset-checkbox {
	width: 300px;
	float: left;
}

#formadv #fieldset-details {
	clear: left;
}

CSS jest bardzo podobny do poprzedniego przykładu. Doszło jedynie kilka nowych elementów. Prosta sztuczka polegająca na zastosowaniu atrybutu float w połączeniu z wygenerowanym znacznikiem fieldset, pozwoliła stworzyć bardziej skomplikowany formularz.

Na sam koniec pozostawiłem tooltip, który stworzyłem na podstawie opisu dodanego do pola Tagi. Przy pomocy CSS ukryłem wygenerowany znacznik P, a następnie przy pomocy prostego skryptu jQuery, stworzyłem mechanizm do jego wyświetlania i chowania.

Materiały do pobrania

Tworzenie_formularzy_z_wykorzystaniem_Zend_Form_cz2.zip