Grouping Form errors for display purpose in Zend Framework

5 Dec

Some time developers need to display summery of errors instead of displaying them with each form element. Previous version of Zend Framework was not providing way for grouping errors together, and display them above the form or any other place. However in ZF 1.7 this cool feature is added and now we can display summery of errors.

Recently I wrote a post on how to play with Zend Form error messages and straight away got a suggestion from Matthew Weier O’Phinney to use Zend_Form_Decorator_FormErrors available in the latest version. Thanks Matthew for giving such useful and easy solution.

In this post I am going to discuss this new cool feature with hope that it will help lot of souls.

Fist create your form as

<?

class forms_SimpleForm extends Zend_Dojo_Form

{

public function __construct($options = null)

{

parent::__construct($options);

$this->setMethod(‘post’);

$username=new Zend_Form_Element_Text(‘username’, array(

‘required’   => true,

‘label’      => ‘Username:’,

‘filters’    => array(‘StringTrim’, ‘StringToLower’),

‘validators’ => array(

‘Alnum’,

array(‘Regex’,false,array(‘/^[a-z][a-z0-9]{2,}$/’))

)

));

$username->removeDecorator(‘Errors’);

$password=new Zend_Form_Element_Password(‘password’, array(

‘required’   => true,

‘label’      => ‘Password:’,

‘filters’    => array(‘StringTrim’),

‘validators’ => array(

‘NotEmpty’,

array(‘StringLength’, false, array(6))

)

));

$password->removeDecorator(‘Errors’);

$save=new Zend_Form_Element_Submit(‘save’, array(

‘label’ => ‘save’,

‘required’=> false,

‘ignore’ => true,

));

$this->addElements(array($username, $password, $save));

$this->setDecorators(array(

‘FormElements’,

‘FormErrors’,

‘Form’

));

}

}

?>

In the above form you need to keep in mind the code

$username->removeDecorator(‘Errors’);

$password->removeDecorator(‘Errors’);

These two lines are compulsory. If you don’t include these two line, errors will be will render next to each line.

The final things, that you will need to include is

$this->setDecorators(array(

‘FormElements’,

‘FormErrors’,

‘Form’

));

If you remove “FormErrors”, error summery will not be render. The form render is

Zend Form errors summery

Zend Form errors summery

you can clearly see that instead of rendering error next to each elements. Errors are now rendered at the bottom. This is the default behavior of the Zend_From_Decorator_FormErrors. You can change this behavior by simply writing

$this->setDecorators(array(

‘FormElements’,

new Zend_Form_Decorator_FormErrors(array(

‘ignoreSubForms’=>true,

‘markupElementLabelEnd’=> ‘</b>’,

‘markupElementLabelStart’=> ‘<b>’,

‘markupListEnd’ => ‘</div>’,

‘markupListItemEnd’=>'</span>’,

‘markupListItemStart’=>'<span>’,

‘markupListStart’=>'<div’

)),

‘Form’

));

Instead of

$this->setDecorators(array(

‘FormElements’,

‘FormErrors’,

‘Form’

));

In your form.

The code above will wrap the whole errors summery in the “div” tag and individual element errors in “span” tag. The form render will be

Zend Form error summery in Div tag

Zend Form error summery in Div tag

Although the forms are looking identical, however they are not. If you see the source code you will see that the entire errors summery is now wrapped in the “div” tag.

By simply setting the style attribute of the “div” tag will place it where ever you want to display it.

9 Responses to “Grouping Form errors for display purpose in Zend Framework”

  1. stephen December 20, 2008 at 4:22 pm #

    Wow! Really helpful Now I can format them using CSS

  2. anna January 1, 2009 at 9:27 pm #

    Thanks for the information!

    Use “array(‘Errors’, array(‘placement’ => ‘prepend’))” to prepend/append the errors.

  3. Kristo January 7, 2009 at 12:32 am #

    Hi,
    is there a possibility to translate those errors… ?
    in my form, the labels are translated, but in error messages theres default values…

  4. Faheem Abbas January 8, 2009 at 6:20 am #

    Kristo,
    Read my article on handling errors manually https://zendguru.wordpress.com/2008/12/04/handling-zend-framework-form-error-messages/
    hope this will help you out.

  5. Clément January 15, 2009 at 5:13 pm #

    Is there a possibility to retrieve all those errors in the form object so we can display them directelly ?

    Let me explain : I have my news.phtml views which not contain the actually

    echo $this->form

    but contain

    echo $this->form->login
    echo $this->form->password
    echo $this->form->submit

    Using the method explain upper work only when you use the full form object.

    At the moment, i have to use a foreach on the form->getMessages() (which is quite the same method as Faheem describes) to display it which is quite annoying in the view in my mind.
    (i can’t use the full form object in this view because I want to create a multilanguage “add/modify news”, all displayed on the same page in a tab container, one container by language)

  6. Delazee March 2, 2009 at 8:50 am #

    It’s really simple to add a title to the FormErrors decorator,
    Set the markupListStart option in your call to the decorator.


    $form->setDecorators(array(
    array( 'FormErrors', array( 'markupListStart' => 'ErrorsPlease check the form for the following errors' ), ),
    'FormElements',
    array('HtmlTag', array('tag' => 'dl', 'class' => 'da_form')),
    'Form',
    ));

  7. Delazee March 2, 2009 at 8:55 am #

    See above, the forum has stripped out some tags in the comment I made.
    Here’s another example with html entities instead of tags:

    $form->addDecorator( array( ‘FormErrors’, array( ‘markupListStart’ => ‘<h2>Errors</h2><p>Please check the form for the following errors</p>’ ), ),

  8. Maurício Vinicius April 29, 2009 at 7:52 pm #

    How can I place the errors messages above the form?

  9. René Klatt July 9, 2009 at 4:08 pm #

    Hello,

    i tried to validate my form via ajax. I use the processAjax method like this:

    $form->processAjax($formData);
    $currentField = key($formData);
    $currentElement = $form->getElement($currentField);
    $response = array(
    $currentField => $currentElement->getDecorator(‘Errors’)->setElement($currentElement)->render(”)
    );

    but if i validate via ajax it doesnt work because $elem->removeDecorator(‘Errors’) so my field cant be validate via ajax. Has anyone an idea for me how i can handle this???

    Thanks
    René Klatt

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: