Załóżmy następującą sytuację: tworzymy w Zend Framework formularz, który wśród swoich pól będzie zawierał pole typu select. Pole te ma służyć do wyboru np. języka. Kod html, który ma powstać będzie wyglądał tak:
<select name="language"> <option value="">-- wybierz --</option> <option value="pl">Polski</option> <option value="en">Angielski</option> </select>
Jak widać nie ma tutaj nic specjalnego. Musimy tylko zadbać, aby użytkownik dokonał wyboru jakiegoś języka.
Kod formularza zawierający takie pole w Zend Framework 2 będzie wyglądał nastepująco:
namespace SmartGroup\Form;
use Zend\Form\Element\Select;
use Zend\Form\Form;
use Zend\InputFilter\Input;
use Zend\InputFilter\InputFilter;
use Zend\Validator\NotEmpty;
class MyForm extends Form {
private $serviceLocator;
public function __construct($name) {
parent::__construct($name);
$this->setAttribute('method', 'post');
$lang = new Select( 'language' );
$lang->setEmptyOption( '--- wybierz ---' )
->setValueOptions( array( 'pl' => 'Polski', 'en' => 'Angielski' )
->setLabel( 'Wybierz język' );
$this->add( $lang );
$this->addInputFilter();
}
public function addInputFilter() {
$inputFilter = new InputFilter();
$lang = new Input( 'language' );
$lang->getValidatorChain()->attachByName('notempty', array( 'messages' => array( NotEmpty::IS_EMPTY => 'Wybierz język' ) ), true );
$inputFilter->add($lang);
$this->setInputFilter($inputFilter);
}
}
Jak widać, wywoływana jest też metoda addInputFilter, która dodaje dla naszego pola validator NotEmpty, aby mieć pewność, że użytkownik na pewno dokona wyboru. W przeciwnym razie ma zostać wyświetlony odpowiedni komunikat.
Uruchamiamy naszą aplikację, widzimy, że pole typu select jest wyświetlone prawidłowo, z właściwymi opcjami. Submitujemy formularz bez dokonania żadnego wyboru i otrzymujemy komunikat o błędzie. A w zasadzie komunikaty:
[txt]
The input was not found in the haystack
Wybierz język
[/txt]
O ile drugi komunikat jest prawidłowy, o tyle pojawia się pytanie skąd pochodzi pierwszy komunikat. Otóż w Zend Framework 2 do każdego pola typu select dołączany jest automatycznie walidator InArray, którego zadaniem jest sprawdzenie, czy wartość z tego pola jest prawidłowa i pochodzi ze zbioru dopuszczalnych wartości przedstawionych w postaci tablicy. Niby wszystko ok, ale co zrobić jeżeli nie chcemy aż tak dogłębnie walidować tego pola i wystarczy nam sprawdzenie czy użytkownik dokonał wyboru.
Z pomoca przychodzi tutaj jedna z metod klasy Zend\Form\Element\Select, czyli: setDisableInArrayValidator(boolean), która jako parametr przyjmuje wartość logiczną określającą czy walidator InArray ma być automatycznie dodany czy nie.
Wystarczy więc nasze pole zdefiniować następująco, aby pozbyć się niechcianego walidatora i komunikatu błędu:
$lang = new Select( 'language' );
$lang->setDisableInArrayValidator(true);
$lang->setEmptyOption( '--- wybierz ---' )
->setValueOptions( array( 'pl' => 'Polski', 'en' => 'Angielski' )
->setLabel( 'Wybierz język' );
