views:

53

answers:

2

I am building an application using Zend_Framework and I would like to ask you for an advice regarding Zend_Form. All forms on the site should be decorated with tables, instead of definition lists. My idea is that I should create a common form (with no elements) and then just instantiate it across the site and add elements as needed. This common form would need to modify the standard decorators, so that tables are used instead of definition lists. How do you suggest to do this? Override Zend_Form's addElement() method so that it alters decorators of new elements?

But there's another caveat. There should be an option of using a different set of decorators for a particular element, if needed. So I'm a bit puzzled how to do this. Do you have any advice?

+2  A: 

There is no simple way to override the default decorators. The solution I use is to override all the elements and redefine the loadDefaultDecorators method.

The problem is that each element have a specific set of decorator. For example, the hidden element needs only the ViewHelper decorator while file element needs File, Errors, Description, HtmlTag (td), Label (th), HtmlTag (tr).

You can also use Zend_Form::setElementDecorators at the end of your init method (after calls to addElement). But you need to customize it for each form...

Maxence
+1  A: 

Use an intermediate class for your project wide configuration. You will then extend this class instead of Zend_Form

file My/Form.php

<?php
abstract class My_Form extends Zend_Form {

    public function __construct ( $options = null ) {
        parent::__construct($options);

        $this->setElementDecorators(array(
                // the base <input, <select, <textarea markup
                'ViewHelper',

                // wrap that into a <div class="input-wrap" />
               array (
                    'HtmlTag',
                    array (
                        'tag'   => 'div',
                        'class' => 'input-wrap',
                    )
                ),

                // append errors in <ul/li>
               'Errors',

                // then prepend <label markup
                'Label',
            ));
    }
}

then in file My/Form/Demo.php

<?php
class My_Form_Demo extends My_Form {

    public function init () {
        // Your elements here
    }
}

You can do this for specific element as well

file My/Form/Element/Group.php

<?php
class My_Form_Element_Group extends Zend_Form_Element_Select {

    public function init () {
        // Specific options
        $this->addMultiOptions(array(
            'A' => 'group A',
            'B' => 'group B',
        ));

        // This element doesn't need the div.input-wrap
        $this->removeDecorator('HtmlTag');
    }
}
Julien