Thursday, July 2, 2009

Applying Zend_Form decorators to all elements

After writing two posts on how to setDecorators to different form elements I think it is now time to provide a simple way to set decorators to all form elements at once.
Take a look at the following code.
class SimpleForm extends Zend_Form
{
public function __construct($options = null)
{
parent::__construct($options);
$countryList=array(
'United States',
'United Kindom',
'Pakistan'
);

$firstName = $this->createElement('text', 'firstName');
$firstName ->addValidator('alnum')
->addValidator('regex', false, array('/^[a-z]+/'))
->addValidator('stringLength', false, array(6, 20))
->setRequired(true)
-> setLabel('First Name:')
->addFilter('StringToLower');

$lastName = $this->createElement('text', 'lastName');
$lastName ->addValidator('StringLength', false, array(6))
->setRequired(true)
-> setLabel('Last Name:');

$address1 = $this->createElement('text', 'address1');
$address1->setLabel('Address1:')
->addValidator('StringLength', false,array(3,50))
->setValue('')
->setRequired(true);

$address2 = $this->createElement('text', 'address2');
$address2->setLabel('Address2:')
->addValidator('StringLength', false,array(3,50))
->setValue('')
->setRequired(false);

$postalCode = $this->createElement('text', 'postalCode');
$postalCode->setLabel('Postalcode:')
->addValidator('StringLength', false,array(3,15))
->setValue('')
->setRequired(false);

$city = $this->createElement('text', 'city');
$city->setLabel('City:')
->setValue('')
->setRequired(false)
->setAttrib('tabindex','6');

$state = $this->createElement('text', 'state');
$state->setLabel('State:')
->setAttrib('maxlength', 2)
->setValue('')
->setRequired(false)
->setAttrib('tabindex','7');

$country = $this->createElement('select', 'country');
$country->setLabel('Country:')
->setAttrib('class','select')
->addMultiOptions($countryList)
->setRequired(false);

$phone = $this->createElement('text', 'phone');
$phone->setLabel('Phone:')
->setAttrib('maxlength', '25')
->setValue('')
->setRequired(true);

$emailAddress = $this->createElement('text', 'emailAddress');
$emailAddress->setLabel('Email:')
->addValidator('StringLength', false,array(5,50))
->addValidator('EmailAddress')
->setValue('')
->setRequired(true);

$this->addElements( array (
$firstName,
$lastName,
$address1,
$address2,
$postalCode,
$city,
$state,
$country,
$phone
));

$this->setElementDecorators(array(
'viewHelper',
'Errors',
array(array('data'=>'HtmlTag'),array('tag'=>'td')),
array('Label',array('tag'=>'td')),
array(array('row'=>'HtmlTag'),array('tag'=>'tr'))
));

$this->setDecorators(array(
'FormElements',
array(array('data'=>'HtmlTag'),array('tag'=>'table')),
'Form'
));
}
}

If you have read my previous post on decorators, you will easily understand the code. However those how are new to my blog and decorators may need some explanation.
As usual we are extending our form from Zend_Form, define our constructor, call parent constructor and then define our elements.
The most important line are after we add elements to our form. The code
$this->setElementDecorators(array(
'viewHelper',
'Errors',
array(array('data'=>'HtmlTag'),array('tag'=>'td')),
array('Label',array('tag'=>'td')),
array(array('row'=>'HtmlTag'),array('tag'=>'tr'))
));

simply set decorators to all the elements to the form elements. Here we are define that close label in “td”, form elements in “td” and put both these in “tr”.
If you want to set decorators to only few elements then
$this->setElementDecorators(array(
'viewHelper',
'Errors',
array(array('data'=>'HtmlTag'),array('tag'=>'td')),
array('Label',array('tag'=>'td')),
array(array('row'=>'HtmlTag'),array('tag'=>'tr'))

),array('firstname','lastname'));

This code will set decorators to only fistname and lastname element of the form. Rest of the form elements will be render in the default decorators.
At the end we define
$this->setDecorators(array(
'FormElements',
array(array('data'=>'HtmlTag'),array('tag'=>'table')),
'Form'
));

This define the form level decorators. We are putting “table” tag after “form” tag. So all the row will be wrapped in table.

4 comments:

  1. setting decorators to all form elements sucks, because it sets Label decorator for submit elements which do not need label...
    any idea how to solve that?

    ReplyDelete
  2. Excellent. I'd not seen the 'openonly' before, which helps a load.

    Any idea how to stop the
    tag appearing in radio lists (so all the radio text/buttons appear on a single line? Perhaps a new post!

    ReplyDelete
  3. $shipTo = new Zend_Form_Element_Radio('shipTo');
    $shipTo->setRequired(true)

    ->setAttrib('class', 'required radio')
    ->setDecorators(self::$CHECKOUT_RADIO_DECORATORS)
    ->setSeparator('')
    ->setattrib('escape', false)
    ->addMultiOption(self::SHIPPING_BILLING, 'Ship to Billing Address')
    ->addMultiOption(self::SHIPPING_DIFFERENT, 'Ship to Different Address')

    ->setValue(self::SHIPPING_DIFFERENT);

    Can anyone tell me why my setValue is being ignored? No matter what I've tried, the SHIPPING_BILLING will always be checked.

    ReplyDelete
  4. thanks for the clear explanation :-)

    ReplyDelete