views:

1118

answers:

2

Having (more) issues with zend form decorators. I've got this so far:

Reset overall form decorator:

    $this->clearDecorators();
    $this->setDecorators(array('FormElements', 'Form'));

I'm adding all my elements to a display group that i want to be inside a fieldset, within a DL

    $group->setDecorators(array(
           'FormElements',
            array('HtmlTag', array('tag' => 'dl')),
           'Fieldset'
    ));   

all working so far, now i want to place an image tag immediately before the fieldset. on its own this would work:

        $group->setDecorators(array(
            'FormElements',
            'Fieldset',
            array('HtmlTag',array('tag'=>'img','placement'=>'prepend','src'=>'/images/'.$imgs[$i-1]->im_name.'_main.jpg'))
        ));   

but this doesnt (it stops the DL being added inside the fieldset):

        $group->setDecorators(array(
            'FormElements',
            array('HtmlTag', array('tag' => 'dl')),
            'Fieldset',
            array('HtmlTag',array('tag'=>'img','placement'=>'prepend','src'=>'/images/'.$imgs[$i-1]->im_name.'_main.jpg'))
        ));

Where am i going wrong?

+1  A: 
$group->setDecorators(array(
    'FormElements',
    array('HtmlTag', array('tag' => 'dl')),
    'Fieldset',
    array(array('ImageTag' => 'HtmlTag'), array('tag'=>'img', 'placement'=>'prepend', 'src'=>'/images/'.$imgs[$i-1]->im_name.'_main.jpg'))
));

Explination from the manual : Internally, Zend_Form_Element uses a decorator's class as the lookup mechanism when retrieving decorators. As a result, you cannot register multiple decorators of the same type; subsequent decorators will simply overwrite those that existed before. To get around this, you can use aliases. Instead of passing a decorator or decorator name as the first argument to addDecorator(), pass an array with a single element, with the alias pointing to the decorator object or name:

// Alias to 'FooBar':
$element->addDecorator(array('FooBar' => 'HtmlTag'),
                       array('tag' => 'div'));

// And retrieve later:
$decorator = $element->getDecorator('FooBar');

In the addDecorators() and setDecorators() methods, you will need to pass the 'decorator' option in the array representing the decorator:

// Add two 'HtmlTag' decorators, aliasing one to 'FooBar':
$element->addDecorators(
    array('HtmlTag', array('tag' => 'div')),
    array(
        'decorator' => array('FooBar' => 'HtmlTag'),
        'options' => array('tag' => 'dd')
    ),
);

// And retrieve later:
$htmlTag = $element->getDecorator('HtmlTag');
$fooBar  = $element->getDecorator('FooBar');
solomongaby
thanks for the explanation, it makes sense but unfortunately your solution doesn't work :(
seengee
to clarify i end up with:form > div > fieldset > dl The Div being a wrapper around the fieldset, its in the position i want the image to be in though
seengee
i got it, you were missing a bracket: array(array('ImageTag' => 'HtmlTag', should have been array(array('ImageTag' => 'HtmlTag'),
seengee
glad to hear it, edited
solomongaby
+1  A: 

Wheh you create the HtmlTag decorators, give them names. Here's an example from my code:

protected $_fileElementDecorator = array(
    'File',
    array(array('Value'=>'HtmlTag'), array('tag'=>'span','class'=>'value')),
    'Errors',
    'Description',
    'Label',
    array(array('Field'=>'HtmlTag'), array('tag'=>'div','class'=>'field file')),
);

As you can see, I named the first one 'Value', and the second one 'Field'. Naming them also gives you the ability to reference the decorator later, like this:

$file = $form->getElement('upload_file');
$decorator = $file->getDecorator('Field');
$options = $decorator->getOptions();
$options['id'] = 'field_' . $file->getId();
if ($file->hasErrors()) {
    $options['class'] .= ' errors';
}
$decorator->setOptions($options);
Sonny