views:

2691

answers:

4

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?

A: 

I would add a class to the button, then define that class in your CSS to make it act like a span. I'm sure you're wanting to do more than just stick it in a span.

Just add one more setAttrib() call:

$submit->setAttrib('class', 'submitButton');

Then in your CSS:

.submitButton {
   display:inline;
   font-weight:bold; /* Or whatever you're wanting to do */
}

I added display:inline as this will make the button act like a span. This should get you started at least. Of course you could base your CSS on the id of the button as well, just use display:inline to get span behavior.

Kekoa
My goal actually is to do "button span { display: none; }" to hide the text of the button (but I'd like it to still be there for people without CSS/JS support).
leek
Aaah. I knew there was something else to it!
Kekoa
+5  A: 

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.

Kieran Hall
Thank you for the very detailed reply. I'm aware of the ViewScript decorator, but I did not know it could be applied to individual elements.
leek
This was very helpful!
tharkun
+1  A: 

You could do this:

$this->addElement(new Zend_Form_Element_Button( 'send', array( 'label' => 'registrieren', 'class' => 'button-red', 'type' => 'submit', 'escape' => false, 'required' => false, 'ignore' => false, ) ));

Rafael
A: 

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!

Aya