Zend_Form Decorators Explained

February 22nd, 2010

One of the pain points for folks who are starting to work with the Zend Framework is the Decorating functionality found in the depths of Zend_Form. I’ve witnessed countless instances when a developer becomes excited by Zend_Form’s easy-to-implement form validation and creation, only to become frustrated by countless hours of fighting with Zend_Form_Decorators. This video is a humble attempt on my part to walk through how Zend_Form Decorators work and how you can reason your way through a desire result. I couldn’t have gotten my own head around this implementation of the decorator pattern without Matthew Weier O’Phinney’s excellent posts and his original devzone article.

UPDATE: check out this blog post / tutorial for ZF 1.10.0: http://framework.zend.com/manual/en/learning.form.decorators.html

I’ll show you a bit about how Zend_Form_Decorators are constructed and how to take the default zend_form layout and transform it into a table.

Grab a copy of the project or browse the repository.

ServerGrove is giving Zendcast viewers a coupon! ServerGrove specializes in Zend Framework hosting and they’ve offered a 10% rebate on hosting with coupon code “zc”. If you’re looking for a host, be sure to check them out (referral). They’ve also added an additional coupon for “Mini Hosting” plans, get $2 off by using code “zcmini”.
 


discuss video in the forum

14 Responses to “Zend_Form Decorators Explained”

  1. I revised and rewrote my series of blog posts as a tutorial for the manual as of 1.10.0: http://framework.zend.com/manual/en/learning.form.decorators.html

  2. David Danyi says:

    Hey.

    I found the ViewScript decorator a really big help, when I had to work with forms that would be very hard to design with normal form decorators.(Like images, separators, etc. in all the weird places…)

    You might want to shred some light on that too in the next video, since that would probably help a lot to people who are new to the whole form decorator business.

  3. undertruck says:

    Nice tutorial but form elements error messages don’t show up.

  4. undertruck says:

    Regarding my above mentioned comment, all errors show up fine if I remove all the decorators.

  5. undertruck says:

    Ohh, I see. I had to include ‘FormErrors’ decorators.

  6. Harald says:

    Great screencast. Learn a lot about decorators. Have always wanted to know how to change the forms.

    Thanks:)

  7. Bojilov says:

    Thanks for great screencast agean. But i agree with David Danyi. Its hard to create complicate form with many div around it and inside it and bunch ot images.

  8. Sathesh says:

    Thanks for the great tutorial which was really simple to understand and useful.. But I have a question.. I have a form with three select elements, say, year, month and day which is a way to select the Date of Birth. I need them to be grouped into a single line or how do I put all the three in a single td element? Any advice would be really helpful.. Thanks again..

  9. jon says:

    Hi Sathesh,

    I’m going to make a video about creating custom form elements. Hopefully, that will help answer your question!

  10. @Sathesh: You may want to look in the manual, as we cover this in a tutorial: http://framework.zend.com/manual/en/learning.form.decorators.composite.html

  11. Whisher says:

    Hi, I’ve just a lot of troubles with
    a captcha element.
    The element is put to the top and the
    description to the end :(
    I don’t know which way to turn.
    Here the form
    setMethod(‘post’);
    $this->setAttrib(‘enctype’, ‘application/x-www-form-urlencoded’);
    $this->setAttrib(‘id’,'frmUserRegister’);
    $this->setAttrib(‘class’,”);
    $translator = $this->getTranslator();

    // Email
    $this->addElement(‘text’, ‘email’, array(
    ‘required’ => true,
    ‘maxlength’ => 255,
    ‘title’ => $translator->translate(‘Your email’),
    ‘label’ => ‘Email :’,
    ‘filters’ => array(‘StringTrim’),
    ‘validators’ => array(
    array(‘EmailAddress’,true),
    array(‘Db_NoRecordExists’, false, array(‘table’ => ‘tn_user’,
    ‘field’ => ‘email’)))
    ));

    // Password
    $this->addElement(‘password’, ‘password’, array(
    ‘required’ => true,
    ‘maxlength’ => 30,
    ‘title’ => $translator->translate(‘Choose your password’),
    ‘label’ => ‘Password :’,
    ‘filters’ => array(‘StringTrim’),
    ‘validators’ => array(
    array(’stringLength’,true, array(3, 30)))
    ));

    //Re-Password
    $this->addElement(‘password’, ‘repassword’, array(
    ‘required’ => true,
    ‘maxlength’ => 30,
    ‘title’ => $translator->translate(‘Re-type your password’),
    ‘label’ => ‘Re-type password :’,
    ‘filters’ => array(‘StringTrim’),
    ‘validators’ => array(
    array(’stringLength’,true, array(3, 30)))
    ));

    // Firstname
    $this->addElement(‘text’, ‘first_name’, array(
    ‘required’ => true,
    ‘maxlength’ => 30,
    ‘title’ => $translator->translate(‘Your first name’),
    ‘label’ => ‘First name :’,
    ‘filters’ => array(‘StringTrim’,'StringtoLower’,'StripTags’),
    ‘validators’ => array(
    array(’stringLength’,true, array(3, 30)))
    ));

    // Lastname
    $this->addElement(‘text’, ‘last_name’, array(
    ‘required’ => true,
    ‘maxlength’ => 30,
    ‘title’ => $translator->translate(‘Your last name’),
    ‘label’ => ‘Last name :’,
    ‘filters’ => array(‘StringTrim’,'StringtoLower’,'StripTags’),
    ‘validators’ => array(
    array(’stringLength’,true, array(3, 30)))
    ));

    //Captcha
    $this->addElement(‘captcha’, ‘captchaRegister’, array(
    ‘required’ => true,
    ‘label’ => ‘Please enter the 5 letters displayed aside:’,
    ‘title’ => $translator->translate(‘Please enter the 5 letters displayed above’),
    ‘captcha’ => array(
    ‘captcha’ => ‘Figlet’,
    ‘wordLen’ => 5,
    ‘timeout’ => 300
    )
    ));

    // Csrf
    $this->addElement(‘hash’, ‘userRegisterHash’, array(
    ‘ignore’ => true,
    ));

    // Submit
    $this->addElement(’submit’, ‘userRegisterSubmit’, array(
    ‘ignore’ => true,
    ‘label’ => ‘Sign up’,
    ));

    $this->setElementDecorators(array(
    ‘ViewHelper’,
    array(array(‘data’ => ‘HtmlTag’), array(‘tag’ =>’td’, ‘class’=> ‘element’)),
    array(‘Label’, array(‘tag’ => ‘td’)),
    array(array(‘row’ => ‘HtmlTag’), array(‘tag’ => ‘tr’))
    ));

    $captcha = $this->getElement(‘captchaRegister’);
    $captcha->setDecorators(array(
    array(array(‘data’ => ‘HtmlTag’), array(‘tag’ =>’td’, ‘class’=> ‘element’)),
    array(‘Label’, array(‘tag’ => ‘td’)),
    array(array(‘row’ => ‘HtmlTag’), array(‘tag’ => ‘tr’))
    ));

    $submit = $this->getElement(‘userRegisterSubmit’);
    $submit->setDecorators(array(‘ViewHelper’,
    array(array(‘data’ => ‘HtmlTag’), array(‘tag’ =>’td’, ‘class’=> ‘element’)),
    array(array(‘emptyrow’ => ‘HtmlTag’), array(‘tag’ =>’td’, ‘class’=> ‘element’, ‘placement’ => ‘PREPEND’)),
    array(array(‘row’ => ‘HtmlTag’), array(‘tag’ => ‘tr’))
    ));

    $this->setDecorators(array(
    ‘FormElements’,
    array(‘HtmlTag’, array(‘tag’ => ‘table’)),
    ‘Form’
    ));

    }
    }

    Can you help me, please ?

  12. Whisher says:

    Sorry here the form
    (I pasted also the php tag)
    class Form_Test extends Zend_Form
    {
    public function init()
    {
    $this->setMethod(‘post’);
    $this->setAttrib(‘enctype’, ‘application/x-www-form-urlencoded’);
    $this->setAttrib(‘id’,'frmUserRegister’);
    $this->setAttrib(‘class’,”);
    $translator = $this->getTranslator();

    // Email
    $this->addElement(‘text’, ‘email’, array(
    ‘required’ => true,
    ‘maxlength’ => 255,
    ‘title’ => $translator->translate(‘Your email’),
    ‘label’ => ‘Email :’,
    ‘filters’ => array(‘StringTrim’),
    ‘validators’ => array(
    array(‘EmailAddress’,true),
    array(‘Db_NoRecordExists’, false, array(‘table’ => ‘tn_user’,
    ‘field’ => ‘email’)))
    ));

    // Password
    $this->addElement(‘password’, ‘password’, array(
    ‘required’ => true,
    ‘maxlength’ => 30,
    ‘title’ => $translator->translate(‘Choose your password’),
    ‘label’ => ‘Password :’,
    ‘filters’ => array(‘StringTrim’),
    ‘validators’ => array(
    array(’stringLength’,true, array(3, 30)))
    ));

    //Re-Password
    $this->addElement(‘password’, ‘repassword’, array(
    ‘required’ => true,
    ‘maxlength’ => 30,
    ‘title’ => $translator->translate(‘Re-type your password’),
    ‘label’ => ‘Re-type password :’,
    ‘filters’ => array(‘StringTrim’),
    ‘validators’ => array(
    array(’stringLength’,true, array(3, 30)))
    ));

    // Firstname
    $this->addElement(‘text’, ‘first_name’, array(
    ‘required’ => true,
    ‘maxlength’ => 30,
    ‘title’ => $translator->translate(‘Your first name’),
    ‘label’ => ‘First name :’,
    ‘filters’ => array(‘StringTrim’,'StringtoLower’,'StripTags’),
    ‘validators’ => array(
    array(’stringLength’,true, array(3, 30)))
    ));

    // Lastname
    $this->addElement(‘text’, ‘last_name’, array(
    ‘required’ => true,
    ‘maxlength’ => 30,
    ‘title’ => $translator->translate(‘Your last name’),
    ‘label’ => ‘Last name :’,
    ‘filters’ => array(‘StringTrim’,'StringtoLower’,'StripTags’),
    ‘validators’ => array(
    array(’stringLength’,true, array(3, 30)))
    ));

    //Captcha
    $this->addElement(‘captcha’, ‘captchaRegister’, array(
    ‘required’ => true,
    ‘label’ => ‘Please enter the 5 letters displayed aside:’,
    ‘title’ => $translator->translate(‘Please enter the 5 letters displayed above’),
    ‘captcha’ => array(
    ‘captcha’ => ‘Figlet’,
    ‘wordLen’ => 5,
    ‘timeout’ => 300
    )
    ));

    // Csrf
    $this->addElement(‘hash’, ‘userRegisterHash’, array(
    ‘ignore’ => true,
    ));

    // Submit
    $this->addElement(’submit’, ‘userRegisterSubmit’, array(
    ‘ignore’ => true,
    ‘label’ => ‘Sign up’,
    ));

    $this->setElementDecorators(array(
    ‘ViewHelper’,
    array(array(‘data’ => ‘HtmlTag’), array(‘tag’ =>’td’, ‘class’=> ‘element’)),
    array(‘Label’, array(‘tag’ => ‘td’)),
    array(array(‘row’ => ‘HtmlTag’), array(‘tag’ => ‘tr’))
    ));

    $captcha = $this->getElement(‘captchaRegister’);
    $captcha->setDecorators(array(
    array(array(‘data’ => ‘HtmlTag’), array(‘tag’ =>’td’, ‘class’=> ‘element’)),
    array(‘Label’, array(‘tag’ => ‘td’)),
    array(array(‘row’ => ‘HtmlTag’), array(‘tag’ => ‘tr’))
    ));

    $submit = $this->getElement(‘userRegisterSubmit’);
    $submit->setDecorators(array(‘ViewHelper’,
    array(array(‘data’ => ‘HtmlTag’), array(‘tag’ =>’td’, ‘class’=> ‘element’)),
    array(array(‘emptyrow’ => ‘HtmlTag’), array(‘tag’ =>’td’, ‘class’=> ‘element’, ‘placement’ => ‘PREPEND’)),
    array(array(‘row’ => ‘HtmlTag’), array(‘tag’ => ‘tr’))
    ));

    $this->setDecorators(array(
    ‘FormElements’,
    array(‘HtmlTag’, array(‘tag’ => ‘table’)),
    ‘Form’
    ));

    }
    }

  13. shaded says:

    How would i get rid of separators from radios or checkboxes?

  14. [...] Understanding decorators will save you a lot of trial and error programming. So put some time in learning what decorators do. The webcast on zendcast is a good starting point: Zend_Form Decorators explained. [...]

Leave a Reply

Desktop RSS feed iPhone + iPod