How would I format Zend_Form_Element_Radio so the label follows the input?
Asked Answered
C

6

5

The default decorator for the Zend_Form_Element_Radio is

<label for="type_id-1"><input type="radio" name="type_id" id="type_id-1" value="1">Pack</label>

The label tag wraps the input tag. Instead I would like to to look like

<input type="radio" name="type_id" id="type_id-1" value="1"><label for="type_id-1">Pack</label>

I thought it might have to do with the "Label" of the element, but that is different. Even with the following code, I still get the label wrapping the radio. When I use this form code.

public function init()
{
    parent::init();

    $this->setName('createdomain');

    $type_id = new Zend_Form_Element_Radio('type_id');
    $type_id->setLabel('Please Choose')
            ->setRequired()
            ->setMultiOptions(array('m' => "male", 'f' => 'female'));

    $this->addElement($type_id);

    $this->setElementDecorators(array(
    'ViewHelper',
     array('Label',array('placement' => 'APPEND')),
));       
}

I get this HTML as a result

<form id="createdomain" enctype="application/x-www-form-urlencoded" action="" method="post"><dl class="zend_form">
<label for="type_id-m"><input type="radio" name="type_id" id="type_id-m" value="m">male</label><br />
<label for="type_id-f"><input type="radio" name="type_id" id="type_id-f" value="f">female</label>
<label for="type_id" class="required">Please Choose</label></dl>
</form>

Notice how there is a label tag wrapping the input tag?

Cranio answered 4/9, 2010 at 2:31 Comment(2)
Can you do it using CSS?Safire
I'm trying to use jQuery UI's buttonset which expects the label to follow the input tag, not be included in the label tag.Cranio
C
-1

It's an issue with jQuery and not the Zend Framework. The wrapping of the element in the label tag is perfectly valid it's just jQuery UI doesn't support it. I have posted a bug report.

* Update Answer *

However I think what you are trying to do (as you commented) is to use the jQuery UI buttonset, which is what I was doing when I came across the jQuery UI bug. In short you have two options until the bug is fixed:

1) Use Dennis D.'s custom view helper to over ride the default radio button element.

2) Patch the Zend Framework Radio button view helper with the code Dennis D. has written. It appears in the file Zend_View_Helper_FormRadio on line 169 (Zend framework Version 1.11.0).

Firstly create a new label and close the tag

// Create the label
$label = '<label'
. $this->_htmlAttribs($label_attribs) . ' for="' . $optId . '">'
. (('prepend' == $labelPlacement) ? $opt_label : '')
. '<input type="' . $this->_inputType . '"'
. $opt_label
. '</label>';

Secondly alter the code that creates the radio button to:

// Create the radio button
$radio = '<input type="' . $this->_inputType . '"'

Thirdly remove the closing of the label tag (as you've already done it) in the view helper, change:

. $endTag
. (('append' == $labelPlacement) ? $opt_label : '')
. '</label>';

And simply replace with:

. $endTag;

Then combine the radio and the label using the placement positioning:

// Combine the label and the radio button
if ('prepend' == $labelPlacement) {
    $radio = $label . $radio;
} else {
    $radio = $radio . $label;
}

And that's it (again Dennis D has done it in the view helper) but the changed code should look like (starting at line 169:

// Create the label
        $label = '<label'
                . $this->_htmlAttribs($label_attribs) . ' for="' . $optId . '">'
                . $opt_label
                . '</label>';

        // Create the radio button
        $radio = '<input type="' . $this->_inputType . '"'
                . ' name="' . $name . '"'
                . ' id="' . $optId . '"'
                . ' value="' . $this->view->escape($opt_value) . '"'
                . $checked
                . $disabled
                . $this->_htmlAttribs($attribs)
                . $endTag;

        // Combine the label and the radio button
        if ('prepend' == $labelPlacement) {
            $radio = $label . $radio;
        } else {
            $radio = $radio . $label;
        }
        // add to the array of radio buttons
        $list[] = $radio;
Controversy answered 4/1, 2011 at 9:24 Comment(1)
I agree, jQuery should be a little more flexible with format of the input and label, but I'm a whole lot more confident editing ZF decorators than diving into the bowels of jQuery UI.Cranio
B
3

i've create a custom view helper named MyLib_View_Helper_FormRadio (so it's called automatically if your bootstraping does so), and overrode and changed the Zend_View_Helper_FormRadio::formRadio() method at Line 160 (Version 1.11), where the radio button is created.


$label = '<label ' . $this->_htmlAttribs($label_attribs) . ' for="' . $optId . '">'
               . $opt_label 
               .'</label>';

        // Wrap the radios in labels
        $radio =  '<input type="' . $this->_inputType . '"'
                . ' name="' . $name . '"'
                . ' id="' . $optId . '"'
                . ' value="' . $this->view->escape($opt_value) . '"'
                . $checked
                . $disabled
                . $this->_htmlAttribs($attribs)
                . $endTag;

        if ('prepend' == $labelPlacement) {
            $radio = $label . $radio;
        }
        elseif ('append' == $labelPlacement) {
            $radio .= $label;
        }
Bruton answered 29/11, 2010 at 11:25 Comment(0)
W
0

Probably my best idea so far, is to change the ZF [Zend Framework] HTML code from within jQuery, so that it gets compatible with jQuery UI format.

Here is the solution:

in ZF Form construction:

$this->setElementDecorators(array(
                                'ViewHelper',
                                'Errors',
                                array(array('rowElement'=>'HtmlTag'), array('tag'=>'div', 'class'=>'element')),
                                array('Label', array('class'=>'first')),
        ));

The important thing here is the div with class=element that will wrap all inputs [so that it is easy to get to them in jQuery]

And here is the JS code:

$(function() {
    $( "div.element > label" ).each(function() {
        $('input', this).after('<label for="'+$(this).attr('for')+'"></label>');
        $('label', this).text($(this).text());
        var input = $('input', this).detach();
        var label = $('label', this).detach();

        var parent = $(this).parent();
        $(this).remove(); 
        input.appendTo(parent);
        label.appendTo(parent);
    });
    $( "div.element" ).buttonset();
});
Wallford answered 16/1, 2011 at 20:28 Comment(0)
K
0

This is the best thing you might can do, which I found it after a lot of pain :))

$radios = new Zend_Form_Element_Radio('notifications');
$notificationTypesArray = array();
foreach ($notificationTypes as $key => $value) {
     $notificationTypesArray[$key] = $value
$radios->removeDecorator('DtDdWrapper');
$radios->removeDecorator('HtmlTag');
$radios->setSeparator('</td></tr><tr><td class="notification_type_row">');
$radios->setDecorators(array(
    'ViewHelper',
    'Errors',
    array(array('data' => 'HtmlTag'), array('tag' => 'td', 'class' => 'notification_type_row')),
    array('Label', array('tag' => 'span')),
    array(array('row' => 'HtmlTag'), array('tag' => 'tr')),
);
$radios->addMultiOptions($notificationTypesArray);              
$this->addElement($radios);
Klump answered 1/4, 2011 at 4:26 Comment(0)
S
0

My answer from a different post on the same subject should help you zend form for multicheckbox remove input from labels

Schrock answered 7/6, 2011 at 14:9 Comment(0)
I
-1

Try:

$this->setElementDecorators(array(
        'ViewHelper',
         array('Label',array('placement' => 'APPEND')),
    ));

Check out zendcasts video about it its really great. Decorators can be really complicated with ZF but this video really explains it well.

Irrefragable answered 4/9, 2010 at 15:31 Comment(4)
Sorry, that's not it either. With that, Zend just appends another label after the two radios. <label for="type_id-1"><input type="radio" value="1" id="type_id-1" name="type_id">Girl</label><br><label for="type_id-2"><input type="radio" value="2" id="type_id-2" name="type_id">Boy</label> <label class="required" for="type_id">Make Selection</label> I'm sure the answer lies somewhere in assigning a different ViewHelper to the radio element, but I'm just not sure how to do it. Thank for the help though.Cranio
@nvoyageur you should post more code then because what I posted in my answer works perfectly and does exaclty what you ask for in your question. So something else must be wrong. Post your whole form?Irrefragable
I've updated the question to include the Form code I am using and the result HTML. You'll notice the input tag is surrounded by a label tag, then both radio buttons are followed by a label for the button set.Cranio
I favorited your question to remember to check it out tonight when I get home from work.Irrefragable
C
-1

It's an issue with jQuery and not the Zend Framework. The wrapping of the element in the label tag is perfectly valid it's just jQuery UI doesn't support it. I have posted a bug report.

* Update Answer *

However I think what you are trying to do (as you commented) is to use the jQuery UI buttonset, which is what I was doing when I came across the jQuery UI bug. In short you have two options until the bug is fixed:

1) Use Dennis D.'s custom view helper to over ride the default radio button element.

2) Patch the Zend Framework Radio button view helper with the code Dennis D. has written. It appears in the file Zend_View_Helper_FormRadio on line 169 (Zend framework Version 1.11.0).

Firstly create a new label and close the tag

// Create the label
$label = '<label'
. $this->_htmlAttribs($label_attribs) . ' for="' . $optId . '">'
. (('prepend' == $labelPlacement) ? $opt_label : '')
. '<input type="' . $this->_inputType . '"'
. $opt_label
. '</label>';

Secondly alter the code that creates the radio button to:

// Create the radio button
$radio = '<input type="' . $this->_inputType . '"'

Thirdly remove the closing of the label tag (as you've already done it) in the view helper, change:

. $endTag
. (('append' == $labelPlacement) ? $opt_label : '')
. '</label>';

And simply replace with:

. $endTag;

Then combine the radio and the label using the placement positioning:

// Combine the label and the radio button
if ('prepend' == $labelPlacement) {
    $radio = $label . $radio;
} else {
    $radio = $radio . $label;
}

And that's it (again Dennis D has done it in the view helper) but the changed code should look like (starting at line 169:

// Create the label
        $label = '<label'
                . $this->_htmlAttribs($label_attribs) . ' for="' . $optId . '">'
                . $opt_label
                . '</label>';

        // Create the radio button
        $radio = '<input type="' . $this->_inputType . '"'
                . ' name="' . $name . '"'
                . ' id="' . $optId . '"'
                . ' value="' . $this->view->escape($opt_value) . '"'
                . $checked
                . $disabled
                . $this->_htmlAttribs($attribs)
                . $endTag;

        // Combine the label and the radio button
        if ('prepend' == $labelPlacement) {
            $radio = $label . $radio;
        } else {
            $radio = $radio . $label;
        }
        // add to the array of radio buttons
        $list[] = $radio;
Controversy answered 4/1, 2011 at 9:24 Comment(1)
I agree, jQuery should be a little more flexible with format of the input and label, but I'm a whole lot more confident editing ZF decorators than diving into the bowels of jQuery UI.Cranio

© 2022 - 2024 — McMap. All rights reserved.