Mirin webspace

Nejbohatší život má ten, kdo žije s minimem nároků

12. 4. 2008 Zend Framework

Zend_Form I

Jak jsem slíbil, zmíním se o poslední věci, kterou jsem si na Zend_Frameworku zkusil a to jsou formuláře. Formulářů na blogu mám povícero, většina jich byla implementována tak, že formulář s veškerým HTML a případně Javascriptem byl implementován ručně v šabloně a data z formuláře se na straně PHP zpracovávala přes Zend_Filter_Input. Protože s příchodem Zend Frameworku 1.5 přišel na řadu i Zend_Form, přepsal jsem si formulář pro komentáře (ten co je pod článkem) právě na Zend_Form.

Dále budu popisovat to, jak jsem postupoval při tvorbě formuláře já, proto nebudu zmiňovat všechny možnosti, kterými Zend_Form oplývá, těch je skutečně hodně a jsou poměrně srozumitelně popsány v referenčním manuálu.

Tvorbu formuláře pomocí Zend_Form lze shrnout zhruba do tohoto postupu.

  • Nadefinování prvků formuláře, případně jejich hodnot
  • Validátory, případně filtry
  • Dekorátory

Zend_Form sám o sobě je kontejner na jednotlivé prvky, které se do něho přidávají. Samotná třída Zend_Form má několik metod, které souvisejí s formulářem samotným. Jedná se zejména o nastavení metody odeslání, URL pro odeslání.

Inicializujeme tedy formulář, nastavíme url pro odeslání. Metoda setAttrib pak nastaví jakýkoli další parameter, který se použije jako atribut HTML elementu form.

 $commentForm = new Zend_Form();
 $commentForm->setAction($urlEnum->blogEntry)
             ->setMethod('post')
             ->setAttrib('id', 'comentForm');

Dále pak do formuláře budeme přidávat jednotlivé prvky a nastavovat jejich hodnoty a validátory. Elementy můžete vytvářet klasicky přes operátor new jako instance tříd Zend_Form_Element_* nebo přes metodu createElement třídy Zend_Form, který využívá pole. Tento způsobe vytváření instancí je v Zend_Frameworku použit i u dalších komponent jako třeba u zmíněného Zend_Filter_Input. Je možný i deklarativní přístup podle konfigurace v XML. Já jsem využil metody createElement třídy Zend_Form.

Vytvářeným elementům se přidávají validátory a filtry. Já jsem použil jen validátory. Pokud jste dříve pracovali se Zend_Filter_Input, tak validátory jistě znáte, jsou v Zend_Frameworku již dlouho.

 $username = $commentForm->createElement('text','username');
 $username->addFilter('StringTrim');
 $username->setLabel('Name (Required)');
 $username->setAttrib('size',30);
 $username->setRequired(true);
 
 $email = $commentForm->createElement('text', 'email');
 $email->addFilter('StringTrim');
 $email->setRequired(true);
 $email->setLabel('Email (Required)');
 $email->setAttrib('size',30);
 $email->addValidator(new Zend_Validate_EmailAddress());
 
 $www = $commentForm->createElement('text', 'www');
 $www->addFilter('StringTrim');
 $www->setLabel('www');
 $www->setAttrib('size',30);
 $www->addValidator(new UrlValid());
 
 $antiSpam = $commentForm->createElement('text','homepage');
 $antiSpam->setRequired(true);
 $antiSpam->addValidator(new Zend_Validate_Identical('NejsemSpammer'));
 
 $formAction = $commentForm->createElement('hidden','formAction');
 $formAction->setValue('addCommentDb');
 
 $submit = $commentForm->createElement('submit','submitB',array('class'=>'dialogButton'));
 $submit->setName('submitB');
 $submit->setLabel('Submit');
 
 $reset = $commentForm->createElement('reset','resetB',array('class'=>'dialogButton'));
 $reset->setName('resetB');
 $reset->setLabel('Reset');

Dodatečné HTML atributy se mohou nastavovat přímo v metodě createElement

 $message = $commentForm->createElement('textarea', 'message',
  array(
   'label'=>'message',
   'style'=>'width:500px',
   'rows'=>10,
   'cols'=>40
  )
 );
 $message->addFilter('StringTrim');
 $message->setRequired(true);
 $message->setLabel('Your comment (allowed tags <a href>,<pre>)');

nebo opět metodou setAttrib, níže uvedený element buttonu využívá jak tento postup, tak způsob nastavení parametrů (class atribut pro třídu stylu) v metodě createElement.

 $preview = $commentForm->createElement('button','preview',array('class'=>'dialogButton'));
 $preview->setAttrib('onclick','commentPreview(); return false;');
 $preview->setLabel('Preview');

Důležitý je zejména druhý parametr (preview), který určuje název elementu, přes něj se pak na element můžeme odvolat přímo z objektu formuláře.

$previewButton = $commentForm->getElement('preview');
$previewButton = $commentForm->preview;

Nakonec elementy přidáme do formuláře a ten dáme do view.

 $commentForm->addElement($username)
             ->addElement($email)
             ->addElement($www)
             ->addElement($message)
             ->addElement($antiSpam)
             ->addElement($formAction)
             ->addElement($submit)
             ->addElement($reset)
             ->addElement($preview);
 
 $this->view->commentForm=$commentForm;

V šabloně pak stačí vykreslit formulář přes metodu render nebo ho přímo vypsat, Zend_Form implementuje metodu toString.

<div>Our nice form</div>
 <?php echo $this->commentForm?>
</div>

Pokud je formulář odeslán, provedeme jeho validaci, vybere hodnoty a s těmi už pak nakládáme jak potřebujeme, třeba je ukládáme přes model třídy do databáze.

 //form was send, try validate and save result
 if ($this->_request->isPost()) {
  if ($commentForm->isValid($this->_request->getPost())) {
   $values = $commentForm->getValues();
 
   try {
    //create model
    $comment=new Comment();
    $comment->setData($values);
 
    //insert new item into the data source
    $comment->insert();
   } catch (Zend_Db_Exception $e) {
    $messages[]="Db error was occurred";
    return;
   }
    $messages[]="Comment saved";
  }
 }

Jak elementy, tak samotný Zend_Form používají předdefinovanou sadu dekorátorů. která způsobuje vykreslování elementů do tagů dd,dt a formulářů do dl a výpis validačních chyb.

Jen pro upřesnění, implicitní dekorátory pro elementy jsou

  • ViewHelper
  • Errors
  • HtmlTag - použitý tag dd
  • Label - použitý tag dt

pro formulář samotný pak

  • FormElements
  • HtmlTag - použitý tag dl a třída stylu zend_form
  • Form

O dekorátorech se zmíním příště, kdy formuláře dorazím, zmíním se také o lokalizaci labelů u elementů a chybových hlášek od validátorů.


Komentáře (0)

Komentáře jsou uzavřeny.