How would I format Zend_Form_Element_Radio so the

2019-02-14 02:17发布

问题:

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?

回答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;


回答2:

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;
        }


回答3:

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();
});


回答4:

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);


回答5:

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



回答6:

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.