Zend Framework Tutorial: A Fully Customized Form Using Zend_Form and Decorators (UPDATED now using Tables)
Filed Under (General) by Wenbert on 29-10-2008
Tagged Under : decorators, Zend Framework, zend_form
This tutorial is derived from this post. So I suggest that you read weirophinney’s post first before this.
This method of rendering a form can be more verbose, but it also allows you to tweak the form at almost infinitely whole still gaining the advantages of error reporting, labeling, etc that decorators provide (by using the decorators associated with the elements).
I would like to stress out the advantages:
- Error Reporting
- And Labelling
You get these by doing only this in your view script (.phtml file):
<?=$this->form->firstname ?> <?=$this->form->lastname ?>
Looking good? Well, here is the rest of it.
First, create this file: application/forms/sample/sampleform.php
Inside sampleform.php, you should have something like this:
class forms_sample_sample2form extends Zend_Form { public $checkboxDecorator = array( 'ViewHelper', 'Errors', 'Description', array('HtmlTag',array('tag' => 'td')), array('Label',array('tag' => 'td','class' =>'element')), array(array('row' => 'HtmlTag'), array('tag' => 'tr'))); public $elementDecorators = array( 'ViewHelper', 'Errors', 'Description', array('HtmlTag',array('tag' => 'td')), array('Label',array('tag' => 'td','class' =>'element')), array(array('row' => 'HtmlTag'), array('tag' => 'tr'))); public $buttonDecorators = array( 'ViewHelper', array('HtmlTag',array('tag' => 'td')), //array('Label',array('tag' => 'td')), NO LABELS FOR BUTTONS array(array('row' => 'HtmlTag'), array('tag' => 'tr'))); public function init() { $this->setAction(''); $this->setMethod('post'); $this->addElement('text', 'email', array( 'decorators' => $this->elementDecorators, 'label' => 'Email:', 'required' => true, 'validators' => array( 'EmailAddress', ), 'attribs' => array( 'id'=>'email_id', 'class'=>'email_class' ), )); $this->addElement('text', 'age', array( 'decorators' => $this->elementDecorators, 'label' => 'Age:', 'required' => true, )); $this->addElement('select', 'country', array( 'decorators' => $this->elementDecorators, 'label' => 'Country:', 'required' => true, 'attribs' => array( 'id'=>'country_id', ), 'multioptions' => array( 'ph' => 'Philippines', 'us' => 'USA', ), )); $this->addElement('text', 'username', array( 'decorators' => $this->elementDecorators, 'label' => 'Username:', 'validators' => array( array('stringLength', 1, 255) ), 'required' => true, )); $this->addElement('text', 'firstname', array( 'decorators' => $this->elementDecorators, 'label' => 'First Name:', 'required' => true, )); $this->addElement('text', 'lastname', array( 'decorators' => $this->elementDecorators, 'label' => 'Last Name:', 'required' => true, )); $this->addElement('radio', 'gender', array( 'decorators' => $this->elementDecorators, 'label' => 'Gender:', 'required' => true, 'attribs' => array( 'id'=>'country_id', ), 'multioptions' => array( 'male' => 'Male', 'female' => 'Female', ), )); $checkboxDecorator = array( 'ViewHelper', 'Errors', array(array('data' => 'HtmlTag'), array('tag' => 'span', 'class' => 'element')), array('Label', array('tag' => 'dt'), array(array('row' => 'HtmlTag'), array('tag' => 'span')), )); $this->addElement('checkbox', 'agreement', array( 'decorators' => $checkboxDecorator, 'label' => 'Agreement:', 'required' => true, )); $this->addElement('submit', 'save', array( 'decorators' => $this->buttonDecorators, 'label' => 'Save', )); } public function loadDefaultDecorators() { $this->setDecorators(array( 'FormElements', array('HtmlTag', array('tag' => 'table')), 'Form', 'Errors' )); } }
Then inside one of my controller-action, I have this:
public function sample2Action() { require_once 'forms/sample/sampleform.php'; $form = new forms_sample_sampleform(); //get the request object $request = $this->getRequest(); if($request->isPost()) { if($form->isValid($request->getPost())) { //do some saves here var_dump($request->getPost()); } } $this->view->form = $form; }
Now, in my view script. These are the .phtml files.
<h4>Please register with us!</h4> <form action="<?= $this->escape($this->form->getAction()) ?>" method="< ?= $this->escape($this->form->getMethod()) ?>"> <fieldset> <legend>Demographics</legend> Please provide us the following information so we can know more about you. < ?= $this->form->age ?> < ?= $this->form->country ?> </fieldset> <fieldset> <legend>User Information</legend> Now please tell us who you are and how to contact you. < ?= $this->form->username ?> < ?= $this->form->firstname ?> < ?= $this->form->lastname ?> < ?= $this->form->email ?> < ?= $this->form->gender ?> < ?= $this->form->agreement ? </fieldset> < ?= $this->form->save ?> </form>
Enjoy!
Feel free to comment/suggest…
Some references in order to help you understand the form decorators ($elementDecorators, etc.) can be found in this thread from Nabble Zend Framework.
UPDATE:
The $elementDecorators variable above might seem a little bit confusing, so here is another example on how to handle it. This one sets a “class” for the first cell and the second cell of the table.
public $elementDecorators = array( 'Label', array(array('labelTd'=>'HtmlTag'), array('tag'=>'td', 'class'=>'label_cell')), array(array('elemTdOpen'=>'HtmlTag'), array('tag'=>'td', 'openOnly'=>true, 'class'=>'input_cell', 'placement'=>'append')), 'ViewHelper', 'Errors', array('Description', array('tag' => 'div')), array(array('elemTdClose'=>'HtmlTag'), array('tag'=>'td', 'closeOnly'=>true, 'placement'=>'append')), array(array('row' => 'HtmlTag'), array('tag' => 'tr'))); public $checkboxDecorator = array( 'ViewHelper', 'Errors', 'Description', array('HtmlTag',array('tag' => 'td')), array('Label',array('tag' => 'td','class' =>'element')), array('Description', array('tag' => 'span')), array(array('row' => 'HtmlTag'), array('tag' => 'tr'))); public $buttonDecorators = array( 'ViewHelper', array('HtmlTag',array('tag' => 'td')), //array('Label',array('tag' => 'td')), NO LABELS FOR BUTTONS array(array('row' => 'HtmlTag'), array('tag' => 'tr')));