Zend Forms (ZF1) How to add extra HTML after checkbox inside DD

743 Views Asked by At

UPD: solved - added extra decorator.

I need to have the following result:

<dd id="daily_722-element">
    <input id="daily_722" type="checkbox" name="daily_722" value="1">
    <span> some text </span>
</dd>

I need to have "some text" wrapped by html tags just after checkbox, BUT before /DD (NOT after)!

My current code is as follows:

$chk = new Zend_Form_Element_Checkbox('daily_shit');
$chk->setLabel('<span class="dt-note">'. $firstName. '</span>');
$chk->getDecorator('label')->setOption('escape', false);

So it produces:

<dd id="daily_722-element">
<input id="daily_722" type="checkbox" name="daily_722" value="1">
</dd>

And I cannot get a clue how to inject extra HTML after checkbox... but inside DD

2

There are 2 best solutions below

1
On

ZF1 decorators are a known source of confusion. If you put a little bit of effort though and get to know how they build up a resulting HTML it's quite simple to achieve what you want.

I suppose you haven't overridden ZF's default decorators for form element. Then they are (remember they're executed in order, altering what was returned by previous decorator):

  • ViewHelper (renders input itself)
  • Errors (appends error message, if needed)
  • Description (appends element description, if set)
  • HtmlTag (surrounds with dd)
  • Label (prepends with label wrapped by dt)

Now what you need is adding <span> some text </span> after input (or errors/description), but before it's wrapped by dd. It means new decorator should be added to a chain of existing decorators in a correct position.

$chk = new Zend_Form_Element_Checkbox('daily_shit');
$chk->setLabel('<span class="dt-note">firstName</span>');
$chk->getDecorator('label')->setOption('escape', false);

// Create a new decorator to render span you need
$postCheckboxDecorator = new Zend_Form_Decorator_Callback(
    array(
        'callback' => function () {
            return '<span>some text</span>';
        }
    )
);

// Add it into existing chain of decorators, right after ViewHelper
$decorators = $chk->getDecorators();
$decorators = array_slice($decorators, 0, 1, true) +
    array('PostCheckboxDecorator' => $postCheckboxDecorator) +
    array_slice($decorators, 1, count($decorators) - 1, true);

// Replace element's decorators with a modified chain
$chk->setDecorators($decorators);
1
On

You can write custom decorator for this. Method render receives original content and changes it, than returns changed content.

class MyDecorator extends Zend_Form_Decorator_Abstract
{
    public function render($content)
    {
        return $content . $this->_options['content'];
    }
}

And use it in form building

$form = new Zend_Form();

$chk = new Zend_Form_Element_Checkbox('daily_shit');
$chk->setLabel('<span class="dt-note">maxa</span>');
$chk->getDecorator('label')->setOption('escape', false);

$decorators = $chk->getDecorators();
$chk->clearDecorators();
$chk->addDecorator($decorators['Zend_Form_Decorator_ViewHelper']);
$chk->addDecorator(new MyDecorator(array('content' => '<span> some text </span>')));
$chk->addDecorator($decorators['Zend_Form_Decorator_Errors']);
$chk->addDecorator($decorators['Zend_Form_Decorator_Description']);
$chk->addDecorator($decorators['Zend_Form_Decorator_HtmlTag']);
$chk->addDecorator($decorators['Zend_Form_Decorator_Label']);

$form->addElement($chk);