Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Zend Framework Zend_Form Decorators: <span> Inside Button Element?

I have a button element that I've created like so:

$submit = new Zend_Form_Element_Button('submit');
$submit->setLabel('My Button');
$submit->setDecorators(array(
    'ViewHelper',
     array('HtmlTag', array('tag' => 'li'))
));
$submit->setAttrib('type', 'submit');

This generates the following HTML:

<li>
    <label for="submit" class="optional">My Button</label> 
    <button name="submit" id="submit" type="submit">My Button</button>
</li>

I would like to wrap the inside of the button with a <span>, like this:

<button...><span>My Button</span></button>

What is the best way to do this using Zend_Form?

like image 543
leek Avatar asked Apr 22 '09 19:04

leek


3 Answers

I have tried and, ultimately, failed to achieve this myself using the same approach. It would seem that the easiest way to do this would be to do:

...
$submit->setLabel('<span>My Button</span>');
...

However, the span will be escaped. It's perfectly possible to turn off the escaping of a lable decorator, however, adding a label decorator renders the output incorrectly, for instance:

$decorator = array(
    array('ViewHelper'),
    array('HtmlTag', array('tag' => 'li')),
    array('Label', array('escape' => false))
);

$submit = new Zend_Form_Element_Button('submit');
$submit->setLabel('<span>My Button</span>');
$submit->setDecorators($decorator);
$submit->setAttrib('type', 'submit');

... renders:

<label for="submit" class="optional"><span>My Button</span></label>
<li>
    <button name="submit" id="submit" type="submit">&lt;span&gt;My Button&lt;/span&gt</button>
</li>

...which, aside from being semantically incorrect (easily fixable), is still escaping the span tags inside the element.

So what do you do?

Well I think the best approach (and this is my meta-advice when it comes to tight control over Zend_Form rendering) is to use the ViewScript decorator.

$submit = new Zend_Form_Element_Button('submit');
$submit->setLabel('My Button');
$submit->setDecorators(array(array('ViewScript', array('viewScript' => '_submitButton.phtml'))));
$submit->setAttrib('type', 'submit');

...then in _submitButton.phtml define the following:

<li>
    <?= $this->formLabel($this->element->getName(), $this->element->getLabel()); ?>
    <button 
    <?php 

    $attribs = $this->element->getAttribs();

    echo
    ' name="' . $this->escape($this->element->getName()) . '"' .
    ' id="' . $this->escape($this->element->getId()) . '"' . 
    ' type="' . $this->escape($attribs['type']) . '"';
    ?>
    <?php

    $value = $this->element->getValue();

    if(!empty($value))
    {
        echo ' value="' . $this->escape($this->element->getValue()) . '"';
    }
    ?>
    >
    <span>
    <?= $this->escape($this->element->getLabel()); ?>
    </span>
    </button>
</li>

The _submitButton.phtml file will need to be in a view script directory (you might be best adding a specific one for your form decorators using $view->addScriptPath('/path/to/my/form/decorators')).

This should render what you're looking for. I've only just started looking at the ViewScript decorator due to flexibility issues I'm experiencing in work. You'll notice that my script isn't that flexible, and certainly isn't in BNF, given all the members that can be populated on the element object. That said, it's a start and it solves your problem.

like image 160
Kieran Hall Avatar answered Nov 20 '22 03:11

Kieran Hall


You could do this:

$this->addElement(new Zend_Form_Element_Button(
            'send',
            array(
                'label' => '<span>registrieren</span>',
                'class' => 'button-red',
                'type' => 'submit',
                'escape' => false,
                'required' => false,
                'ignore' => false,
            )
 ));
like image 35
Rafael Avatar answered Nov 20 '22 03:11

Rafael


Just escaping the label works fine. It only breaks when someone starts messing with the label decorator (usually happens when customising tags)

You can use the Zend_Form function setElementDecorators() and exclude some elements from styling. Read Example #3 Setting Decorators for Some Elements in Zend_Form Manual (including the Note!) for more details.

For those who are still confused, here is an example code to style the form as a table, and have a button that is encased in double span:

//(...)putting some other elements in the form first

//now add submit button 
$form       ->addElement('button', 'submit', array(
                        'label'     => '<span><span>SUBMIT</span></span>', 
                        'value'     => 'submit'
            ));

$form
            //set decorators for non-button elements
            ->setElementDecorators(array(
                    'ViewHelper',
                    'Errors',
                    array(array('data' => 'HtmlTag'), array('tag' => 'td', 'class' => 'element')),
                    array('Label', array('tag' => 'td')),
                    array(array('row' => 'HtmlTag'), array('tag' => 'tr'))), array('submit'), false)
            //and then for button elements only
            ->setElementDecorators(array(
                    'ViewHelper',
                    'Errors',
                    array(array('data' => 'HtmlTag'), array('tag' => 'td', 'class' => 'element')),
                    array(array('row' => 'HtmlTag'), array('tag' => 'tr'))), array('submit'), true)
            //and finally for the form
            ->setDecorators(array(
                    'FormElements',
                    array('HtmlTag', array('tag' => 'table')),
                    'Form'
            ));

where $form is a Zend_Form element. Hope this helps!

like image 1
Aya Avatar answered Nov 20 '22 01:11

Aya