Zend_Form is a great component to help with the headache of form creation, validation and error handling. I’ll be the first to admit that I’ve had problems with the configuration of the Decorators, however one of the more powerful ones; ViewScript is somewhat overlooked. This decorator, to me seems to be the most logical way to configure how form elements and error messages are rendered, it also removes the need for the smelly practice of defining bits of html in your application code. Here’s the example, lifted straight from the documentation
Firstly we tell the Zend_Form_Element object to use the ViewScript decorator.
<?php
// Setting the decorator for the element to a single, ViewScript,
// decorator, specifying the viewScript as an option, and some extra
// options:
$element->setDecorators(array(array('ViewScript', array(
'viewScript' => '_element.phtml',
'class' => 'form element'
))));
// OR specifying the viewScript as an element attribute:
$element->viewScript = '_element.phtml';
$element->setDecorators(array(array('ViewScript', array('class' => 'form element'))));
And here’s code for _element.phtml
<div class="<?php echo $this->class ?>">
<?php echo $this->formLabel($this->element->getName(), $this->element->getLabel()) ?>
<?php echo $this->{$this->element->helper}($this->element->getName(), $this->element->getValue(), $this->element->getAttribs()) ?>
<?php echo $this->formErrors($this->element->getMessages()) ?>
<div class="hint"><?php echo $this->element->getDescription() ?></div>
</div>
As you can see, this approach gives you full access the element and the markup for rendering. If I had my way this would be the only approach, it’s more verbose and I’d even be comfortable letting my designers loose on it. However the example doesn’t go much further than this, so during development I encountered a few issues using different types of elements.
All that needs to be done specify the particular script for the element to render when declaring the ViewScript decorator, like this example of a Zend_Form_Element_Text element:
$element->setDecorators(
array(array('ViewScript', array('viewScript' => 'input.phtml')))
);
Here’s some of scripts I’ve created along the way.
Text Input/Textarea (input.phtml)
I’ve added a little logic to check for errors in the element and add css class accordingly. This is not entirely neccessary but I think it highlights the ways you can use the ViewScript Decorators’ power.
<div class="element<?php if($this->element->hasErrors()): ?> errors<?php endif; ?>">
<?= $this->formLabel($this->element->getName(), $this->element->getLabel()) ?>
<?= $this->{$this->element->helper}($this->element->getName(), $this->element->getValue(), $this->element->getAttribs()) ?>
<?php if( $this->element->hasErrors() ): ?>
<div class="messages">
<?= $this->formErrors($this->element->getMessages()) ?>
</div>
<?php endif; ?>
</div>
Select (select.phtml)
There’s only one difference here and it’s the results of the call to getMultioptions() on the element being passed to the element view helper.
<div class="element<?php if($this->element->hasErrors()): ?> errors<?php endif; ?>">
<?= $this->formLabel($this->element->getName(), $this->element->getLabel()) ?>
<?= $this->{$this->element->helper}($this->element->getName(), $this->element->getValue(), $this->element->getAttribs(), $this->element->getMultiOptions()) ?>
<?php if( $this->element->hasErrors() ): ?>
<div class="messages">
<?= $this->formErrors($this->element->getMessages()) ?>
</div>
<?php endif; ?>
</div>
Submit (submit.phtml)
<div class="element">
<?= $this->{$this->element->helper}($this->element->getName(), $this->element->getValue(), $this->element->getAttribs()) ?>
</div>
So there you have it. A simple solution to the complex issue of Zend_Form_Element Decorators.
#1 by dsantamaria on July 24, 2009 - 5:00 PM
Quote
helllo, first of wall thx for the blog, ill be checkin it constantly since im startingt with this zend thing and your blog is very clear and helpful.
i got a few questions for u , if u dont mind of course, thx in advance
first of all is, im using decorators on my zend_forms but dont completely understand the parameters and options of the setDecorator method, I.E
i got this set of code i got form a tutorial:
$username->setDecorators(array(
‘ViewHelper’,
‘Description’,
‘Errors’,
array(array(‘data’=>’HtmlTag’), array(‘tag’ => ‘td’)),
array(‘Label’, array(‘tag’ => ‘td’)),
array(array(‘row’=>’HtmlTag’),array(‘tag’=>’tr’))
));
works like a charm but i dont quite get it… what are the three first parameters? what does data=>htmlTag means?, and row=>htmltag
could u plz explain me a little? or guide me to some api doc or reference site? ive tried everything but the zend api documentation is not so clear
2nd im ttrying to create a goBack button but zend style, with _redirect or something like that, is there anyway? i ont want it to be hardcoded like _redirect(/auth/login) but something bor elike the javascript history.go(-1)
and last but not elast what ide ur using? im on zend studio for eclipse 6.1.2 and cant set a theme like the one you show us here, im back to the eye-burning whit theme
thank you!!!!!
#2 by Shaun on July 25, 2009 - 12:29 PM
Quote
Hi, Thanks for commenting. I’ve been quite busy lately and haven’t managed to write any more articles but I will be soon.
To answer your questions:
1) Those paramaters are basically telling Zend_Form_Element which decorator to use when rendering the element. The paramater array(‘data’ => ‘HtmlTag’) is telling it which decorator to use and the other parameters like array(‘tag’ => ‘td’) are telling HtmlTag to use that tag when rendering the element. I would however reccommend using the technique described in this article as it makes life much easier, as you know, the configuration of these decorators is quite confusing.
2) If I understand your question correctly, you could create a view helper that outputs a link to the refering url. Something like this:
<?php class My_View_Helper_GoBack extends Zend_View_Helper_Abstract { public function goBack($text) { $request = Zend_Controller_Front::getInstance()->getRequest(); echo '<a href="' . $request->getServer('HTTP_REFERER') . '">' . $text . '</a>'; } }Then to access the helper in the view script
<?php echo $this->goBack('back'); ?>The code is a little rough and could do with some logic to check if there actually is a refering url but I hope it illustrates a simple solution.
3) I use TextMate and also Eclipse. The syntax highlighting on this blog is just a plugin, I’m afraid.
Thanks for reading,
Shaun