ZF-10608: Label decorators do not allow modification of the wrapping tag.

Description

When working with the Label decorator in a decorator stack you are not allowed to modify a wapper tag that is specified, for example if you use:


    public $basicElementDecorators = array(
        'ViewHelper',
        'Errors',
        array('HtmlTag', array('tag'=>'div', 'class'=>'form_element_wrapper')),
        array('Label', array('tag'=>'div', 'class'=>'applytowrapper')),
        array(array('wrapper'=>'HtmlTag'), array('tag'=>'div', 'class'=>'form_element_container'))
    );

This does not move the attribute to the wrapper instead it generates:


Date of Birth

I noticed that there is no configurable way to modify the attributes of the wrapping tag of the Label decorator due to the way it calls the render(); function of the wrapping tag:


        if (null !== $tag) {
            require_once 'Zend/Form/Decorator/HtmlTag.php';
            $decorator = new Zend_Form_Decorator_HtmlTag();
            $decorator->setOptions(array('tag' => $tag,
                                         'id'  => $this->getElement()->getName() . '-label'));

            $label = $decorator->render($label);
        }

My proposal is to allow a special key in the options array of the Label decorator called 'tag_options'. If this key is found it is merged with the above segment but also removed from the label tag's options array as we do not want to render attributes in the tag that are invalid. Patch:


--- Label.php   2010-10-28 11:09:22.677596859 -0400
+++ MyLabel.php 2010-10-28 11:09:18.333231838 -0400
@@ -300,7 +300,12 @@ class Zend_Form_Decorator_Label extends 
         $id        = $this->getId();
         $class     = $this->getClass();
         $options   = $this->getOptions();
+        $tag_options = null;
 
+        if(isset($options['tag_options'])) {
+                $tag_options = $options['tag_options'];
+                unset($options['tag_options']);
+        }
 
         if (empty($label) && empty($tag)) {
             return $content;
@@ -314,10 +319,15 @@ class Zend_Form_Decorator_Label extends 
         }
 
         if (null !== $tag) {
+            if($tag_options === null) {
+                $tag_options = array('tag' => $tag,'id'  => $this->getElement()->getName() . '-label');
+            } else {
+                $tag_options = array_merge(array('tag'=> $tag, 'id' => $this->getElement()->getName() . '-label'), $tag_options);
+            }
+
             require_once 'Zend/Form/Decorator/HtmlTag.php';
             $decorator = new Zend_Form_Decorator_HtmlTag();
-            $decorator->setOptions(array('tag' => $tag,
-                                         'id'  => $this->getElement()->getName() . '-label'));
+            $decorator->setOptions($tag_options);
 
             $label = $decorator->render($label);
         }

I think this is an important improvement over the existing way on how it renders the wrapping tag. Extending the Label decorator class may also be a viable means of doing this but overwriting render() to provide functionality from the beginning did not seem intuitive to me. Therefore if I know specify:


    public $basicElementDecorators = array(
        'ViewHelper',
        'Errors',
        array('HtmlTag', array('tag'=>'div', 'class'=>'form_element_wrapper')),
        array('Label', array('tag'=>'div', 'tag_options'=>array('class'=>'applytowrapper'))),
        array(array('wrapper'=>'HtmlTag'), array('tag'=>'div', 'class'=>'form_element_container'))
    );

This generates:


Date of Birth

Comments

May I offer an alternate solution? Create an alternate, custom decorator for labels, and use that. The more options we provide, the harder it is to understand precedence and specificity.

For a default decorator that ships with ZF, not allowing the ability to apply attributes to a wrapping tag element makes that element useless. Especially if you are trying to change the look and feel of a form through CSS. If I cannot specify the id of the class then I have to select it via a parent or child DOM element which may not always be available. Since it is the default decorator that ships with the library this is a 100% improvement.

There is already a solution: {{Zend_Form_Decorator_Label::setTagClass()}}

You can find an example here: zfforum.de (in German)