Zend framework custom Form decorators

13 Nov

Zend framework custom Form decorators
Recently when I posted an article on Zend Form decorators as well as Zend Form display group decorators, hundred of developers visit that post. This clearly indicate that developers using Zend_Form to create html form are having difficulties in using decorators.
Although I have created very nice and fancy forms using display groups and decorators in one of my application using the methods I’ve previously discussed. However as most developers are having problems using decorators I decided to wit my hands and take a deeper look it into this topic.
Although Zend framework documentation is extremely helpful and give comprehensive knowledge of how to use different components shipped with it, however most of developer find it hard because of lack of examples, I think.
I say this because I wasn’t able to properly following it and take benefits out of it in the beginning.
Few days back I studied how to create and use our own custom decorators. Studying the topic for about some time I came to the conclusion that it is quite easy to create and implement our own decorator. Creating and using your own decorators give the ability to layout your form what ever way you like.
In this post I am going to give you a very simple example of how to create and then use you own decorators.
So lets get started.
Before define our own decorators I would like to tell you that the standard decorators shipped with Zend Framework can be found in Zend/Form/Decorators. This directory contains an abstract class Zend_Form_Decorator_Abstract that is extend by all the standard decorators.
To define our own custom decorator class we will also need to extend our class form the same abstract class.
Before writing the code, create My/Form/Decorators/ directory structure under /library folder in your application.
Now create Simple.php and place the following code in it.

class My_Form_Decorators_Simple extends Zend_Form_Decorator_Abstact
{

Public function render($content)
{

$element = $this->getElement();
if(!$element instanceof Zend_Form_Element){
return $content;

}

if(null = = = $element->getView()){
return $content;

}

$seperator = $this->getSeperator();
$placement = $this->getPlacement();

 

$label = $this->buildLabel();
$label = $this->buildInput();
$label = $this->buildErrors();
$label = $this->buildDescription();

$output=’

. $label
. $input
.$errors
.$decs
.’ ‘;
switch($placement)
{
case (self::PREPEND):
return $output.$seperator.$content;
break;
case (self::APPEND):
default:
return $content.$seperator.$output;
break; 

}

}

 

public function buildLabel()
{

$element=$this->getElement();
$label=$element->getLabel();
if($transtalor=$element->getTranslator()){

$label = $translator->translate($label);

}

 

if($element->isRequired()){

$label .= ‘*’;

}

 

$label .= ‘:’;

 

return $element->getView()->formLabel($element->getName(),$label);

}

public function buildInput()
{

$element = $this->getElement();
$helper = $this->helper;
return $element->getView()->$helper(

$element->getName(),
$element->getValue(),
$element->getAttribs(),
$element->getOptions(),

);

}

 

function buildErrors()
{

$element $this->getElement();
$messages = $element->getMessages();

if(empty($messages)){

return ”;

}

return ” . $element->getView()->formErrors($messages).”;

}          

public function buildDescription()
{

$element = $this->getElement();
$desc = $element->getDescription();
if(empty($desc)){

return ”;

}

return ”.$desc.”;

}

 

}

?>
Explanation:
The code is not I think hard to understand.
Whenever you apply decorator using setDecorators() methd, View called render($content) method of Zend_Form_Decorator_Abstact at the time of rendering form.
In the code above we first extend our custom decorator class form Zend_Form_Decorator_Abstact and then define our our render() function. so when we apply this custom decorator to any of our element in the form, view will call this render() method.
In our fist few line of render method we get element(by using getElement() function) and check whether or not it is instance of the Zend_Form_Element using instanceof operator. If not then we simply return the contents passed to this function. we also check the view(by using getView method on $element).
Next we get separator and placement. Placement can be either prepand or append(by default).
The next few lines are important.
We call four method buildLabel(), buildInput(), buildErrors() and buildDescription();
The buildLabel() method apply decorators to the Lable of the element. In this method we first get the element and then label. If translator is applied we translate the label. If it is required we concatenate “*” with the label and then “:” colon.
At the end we return the label.
buildInput() apply decorators to the inputbox/checkbox/radion etc.
the code is simple, we get element and helper and then return the elements with its value, attribs and options.
buildErrors() apply decorators to the errors if any. As usual we get element, get error message if any and then return errors messages in div.
buildDescripiton() method check for the description and return it in the div if any.
That’s it our own custom decorator class.
Next we will need to apply this to our Zend_Form elements.
Let you have the following form

class MyForm extents Zend_Form
{

public function __construct($options=array())
{

parent::__construct($options);

$username = $this->CreateElement(‘text’,’username’);
$username->setLabel()

->setDecription(‘Required’);

}

}
?>

To apply the above custom decorator write

$this->addElementPrefixPath(‘My_Form_Decorators’,

‘My/Form/Decorator’,
‘decorator’);

 

after parent::__construct($options); in your constructor.
and replace

$username = $this->CreateElement(‘text’,’username’);
$username->setLabel()

->setDecription(‘Required’);

With

$username = $this->CreateElement(‘text’,’username’);
$username->setLabel()

->setDecription(‘Required’)
->setDecorators(array(‘Simple’));

That’s it. We have now applied our custom decorator to our form element. You can apply this custom decorator to as many form element as you like.

9 Responses to “Zend framework custom Form decorators”

  1. Mr. Magic November 13, 2008 at 1:50 pm #

    Have you ever tried reading one of your posts yourself? It’s pretty fun to read text with absolutely no spaces in between clauses…

  2. Streamer November 16, 2008 at 2:09 pm #

    Thank you for this article, a tryied to solve my problem with decorators few mounts ago but only this article helps me how to create it, thanks (sorry for my english)

  3. Hab January 30, 2009 at 2:43 pm #

    I’m a newbie in ZF. I’ve created my first application with the help http://framework.zend.com/docs/quickstart an I tried to add custom decorator with the help this article.. but it’s getting error “Message: Decorator by name Label does not exist”..

    Any idea?

    Thanks
    Hab

  4. Hab January 30, 2009 at 3:25 pm #

    I’ve tried this

    $this->Name->addDecorator(‘Simple’);

    But got this error
    Parse error: syntax error, unexpected T_SWITCH in E:\wamp\www\matri\library\My\Form\Decorators\Simple.php on line 76

  5. Hab January 30, 2009 at 5:11 pm #

    I’ve tried addDecorators(array(‘Simple’));

    but got error
    Warning: Zend_Loader::include_once(Zend\Form\Decorator\Abstact.php) [zend-loader.include-once]: failed to open stream: No such file or directory in E:\wamp\www\matri\library\Zend\Loader.php on line 84

    Warning: Zend_Loader::include_once() [function.include]: Failed opening ‘Zend\Form\Decorator\Abstact.php’ for inclusion (include_path=’E:\wamp\www\matri\application/../library;.;C:\php5\pear’) in E:\wamp\www\matri\library\Zend\Loader.php on line 84

    Fatal error: Class ‘Zend_Form_Decorator_Abstact’ not found in E:\wamp\www\matri\library\My\Form\Decorators\Simple.php on line 2

    But Abstact.php is there at Zend\Form\Decorator\

  6. Jesse February 25, 2009 at 4:25 am #

    Can someone tell me what the ini file config looks like for this?

    I’m trying something like this

    userForm.elements.name_first.type = “text”
    userForm.elements.name_first.options.label = “Name First”
    userForm.elements.name_first.options.validators.notempty.validator = “NotEmpty”
    userForm.elements.name_first.options.validators.notempty.options.messages.isEmpty = “A valid user name is required.”

    userForm.elements.name_first.options.elementprefixPath.my.type = “decorator”
    userForm.elements.name_first.options.elementprefixPath.my.path = “My/Form/Decorator/”
    userForm.elements.name_first.options.elementprefixPath.my.prefix = “My_Form_Decorator”
    userForm.elements.name_first.options.decorator = “Simple”

  7. MikeA December 20, 2009 at 1:29 pm #

    Zend_Form_Decorator_Abstact is misspelled.

    It should be Zend_Form_Decorator_Abstract (missing ‘r’ in Abstract)

  8. Jignesh Thummar February 26, 2010 at 5:11 am #

    ‘My/Form/Decorator’ is also miss spaelled correct one is ‘My/Form/Decorators’
    or just pest following code

    $this->addElementPrefixPath(‘My_Form_Decorators’,’My/Form/Decorators’,’decorator’);

  9. Russell March 20, 2010 at 11:35 am #

    This could be useful, got one that works, without all the typos?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: