Issues

ZF-3024: Zend_Form Radio and MultiCheckbox elements fail W3C validations due to missing IDs

Description

Multi elements such as Radio and MultiCheckbox do not pass W3C validations with the default decorators due to an issue with how labels are generated.

W3C says that the 'for' attribute of an element must point to the id of a single other input element in the form. However, in cases such as the radio and multicheckbox, there are actually multiple elements in the form related to the same label. Our current solution uses the element name (which is the same between all input elements) in the label "for" attribute -- which is invalid markup.

Potential solutions:

  • Do not use an id with the label in these situations (may be invalid markup)
  • Generate a unique ID for each input element, and utilize the first for the label.

Comments

Scheduling for next minor release.

Doesn't seem that the solution to this was put in to a minor release since Matthew's comment in April, as looking at version 1.7.2 now the problem of having no 'for' attribute in the labels still exists. Random IDs are generated, but then only used within the input tag itself.

I'd suggest simply updating FormRadio.php so that the line:

$radio = '<label'

becomes:

$radio = '<label for="' . $optId . '"'

Patch file for the update.

This has been resolved at some point in the past; please see Zend_View_Helper_FormRadioTest::testRadioLabelContainsForAttributeTag(), as well as line 161 of the FormRadio view helper, which reads:


. $this->_htmlAttribs($label_attribs) . ' for="' . $optId . '">'

I found a solution by redefining "Label" decorator on these fields !

You have to pass the "disableFor" option to the decorator. It will remove the "for" attribute of the main "label" tag but not from the checkboxes' ones.

Current trunk validates fine with


$form = new Zend_Form();
$form->addElement('Radio', 'Woo', array('MultiOptions' => array('foo','bar','baz')));
$form->addElement('Select', 'Zaa', array('MultiOptions' => array('foo','bar','baz')));
$form->addElement('Multiselect', 'Qua', array('MultiOptions' => array('foo','bar','baz')));
$form->addElement('MultiCheckbox', 'Qui', array('MultiOptions' => array('foo','bar','baz')));
$form->addElement('submit','submit');
die($form->render());