Zend Framework Tutorial: A Fully Customized Form Using Zend_Form and Decorators (UPDATED now using Tables)
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'=>'gender_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')));
Browse Timeline
Comments ( 4 )
Gerard added these pithy words on Oct 29 08 at 6:30 pm1. application/forms/sample/sampleform.php L95-101 Make the checkbox decorator a property.
2. Be consistent
sample2Action() L6-7
$request = $this->getRequest();
if($this->getRequest()->isPost()) {
}should be
$request = $this->getRequest();
if($request->isPost()) {
}Other than that, thanks.
Javatuan added these pithy words on May 24 09 at 6:34 pmattribs of gender is “array(’id’=>’country_id’,)”, Should it be gender_id or something like that?
Wenbert added these pithy words on May 24 09 at 9:06 pm@Javatuan you’re right. It should have been gender_id. The post is now fixed ;-)