I'm currently building my own set of Form elements with Zend_Form and want all my elements in my custom form to be able to use my custom Decorators
So i've created a custom form like this:
<?php
class Nuke_Form extends Zend_Form
{
public function __construct($options = null)
{
$this->addElementPrefixPath('Nuke_Form_Decorator_TwitterBootstrap', 'Nuke/Form/Decorator/TwitterBootstrap/', 'decorator');
parent::__construct($options);
}
}
And for completeness sake, this is my Decorator
<?php
class Nuke_Form_Decorator_TwitterBootstrap_ControlGroup extends Zend_Form_Decorator_Abstract
{
public function render($content)
{
$class = $this->getOption('class') ?: "control-group";
$element = $this->getElement();
$errors = $element->getMessages();
if (!empty($errors)) {
$class .= " error";
}
$output = '<div class="' . $class . '">' . $content . '</div>';
return $output;
}
}
and the concrete form implementation I'm creating in my Controllers
class App_Form_Index_Test extends Nuke_Form
{
public function init()
{
parent::init();
$this->addAttribs(array('class' => 'form-horizontal'));
$username = new Nuke_Form_Element_Text('username');
$username->setLabel("Gebruikersnaam")
->setDescription("This is a description")
->setRequired(true)
->addValidator('NotEmpty', true)
->addValidator('int');
$submit = new Zend_Form_Element_Submit('submit');
$this->addElements(array($username, $submit));
}
}
But for some reason the Elements fail to find the Decorators and output the following exception:
Message: Plugin by name 'ControlGroup' was not found in the registry; used paths: Zend_Form_Decorator_: Zend/Form/Decorator/
Analyzing the exception I see my plugin path isn't added, even though I've added it explicitly by using addElementPrefixPath() in the Nuke_Form class.
The strange thing is, when I'm adding the PluginPath to each of my Custom Elements individually, it works flawlessly, like below.
<?php
class Nuke_Form_Element_Text extends Zend_Form_Element_Text
{
public function init()
{
$this->addPrefixPath('Nuke_Form_Decorator_TwitterBootstrap', 'Nuke/Form/Decorator/TwitterBootstrap/', 'decorator');
$this->addDecorators(array(
array('ViewHelper', array(
'helper' => 'formText'
)),
array('Errors'),
array('Description', array(
'placement' => Zend_Form_Decorator_Abstract::APPEND,
'class' => 'help-block'
)),
array(array('controls' => 'HtmlTag'), array(
'tag' => 'div',
'class' => 'controls',
)),
array('Label', array(
'class' => 'control-label',
'requiredSuffix' => ' *',
'placement' => Zend_Form_Decorator_Abstract::PREPEND
)),
array('ControlGroup')
));
}
}
I'm using the latest version of Zend Framework (v1.11.11).
After some research i've noticed that addElementPrefixPath() will add the path to all added form elements when invoked, I think this is why it won't work when calling it in the Nuke_Form constructor since at that time no elements have been added yet. But how are we supposed to use this method then? I've found several examples online that do call it in the constructor with success. I'm puzzled or overlooking something.
try passing it in the constructor:
$options = array('elementPrefixPath' => 'Nuke/Form/Decorator/TwitterBootstrap/');
or maybe put it in init():
I think calling it in init() will work best. And don't bother to call
parent::init();
here, it's just an empty function in Zend_Form, nothing to override.THIS DOES WORK
I used all of your code except the custom element, I set the elementPrefixPath in inti() and called ControlGroup Decorator using addDecorator() against a normal Zend_Form_Element, this is the output:
the only change I made was to add a trailing _ to the prefix.
of course I used my own path...
I only renamed the decorator to fit my path
I think your problem is somewhere else...
I also got the __constructor to work, I had to adjust the parameters to get the correct options:
I really hope this helps :)