views:

263

answers:

3

Hi,

I am having trouble over ridding the default set of decorators with Zend_Form.

I am attempting to extend Zend_Form in order to implement a different decorator style.

class CRM_Form extends Zend_Form
{
 public function init()
 {  
  $this->setDisableLoadDefaultDecorators(true);

  $this->addDecorator('FormElements')
->addDecorator('Form');

  $this->setElementDecorators(array(
  'ViewHelper',
  'Label',
 'Errors',
   new Zend_Form_Decorator_HtmlTag(array('tag' => 'p'))
  ));
 }
}

When I attempt to make use of this class like so:

$form = new CRM_Form();
$form->setAction('/')->setMethod('post'); 
$id = $form->createElement('text','id')->setLabel('ID:');
$form->addElement($id);

The old decorators are used (definition list) rather than my paragraph style.

If I addElement()'s in the init() method of the CRM_Form class they use the style that I have set.

How can I force all elements created using that class to use my default style?

A: 

Zend Form is decorating the Elements after you add them. So create an method like "addAndDecorte":

public function addAndDecorate($element) 
{
   $this->addElement($element);

   // do your decorating stuff..
}
ArneRie
Thanks for the point in the right direction in the end I re-implemented the createElement() method and added the decorator options to that.
Tom
A: 

When you call setElementDecorators in init, you don't have any elements to decorate, so nothing happens. Instead, you can override the Zend_Form::createElement function, which will do the following:

  1. If the options array contains a decorators listing, then simply pass along without change.
  2. If the options don't, then add your defaults.

..

// not tested
public function createElement($type, $name, $options = null)
{
  if ( !is_array($options) ) {
    $options = array();
  }
  if ( !isset($options['decorators']) ) {
    $options['decorators'] = array(
      'ViewHelper','Label','Errors',
      new Zend_Form_Decorator_HtmlTag(array('tag' => 'p'))
    );
    // I'd make this array a protected class member
  }

  return parent::createElement($type, $name, $options);
}
Derek Illchuk
+1  A: 

By default, if you are using $form->addElement('type', 'name', array('options'=>'example')); format of adding elements, Zend_Form will use the Decorators you set in the setElementDecorators.

If you are creating elements yourself, then passing them to the $form->addElement() function, it will not take care of setting the decorators automatically.

You could easily override that function to set the decorators on elements that are already created by doing something like this in your form:

public function addElement($element, $name = null, $options = null)
{
  if ($element instanceOf Zend_Form_Element) {
    $element->setDecorators($this->_elementDecortors);
  }
  return parent::addElement($element, $name, $options);
}
gnarf