ZF-3242: Add functionality to set form-level errors
Description
As discussed on fw-mvc, it would be nice to be able to set form-level errors that apply to a form submission as a whole and not to any particular element. This could be useful for, e.g., 'Invalid login credentials' or 'there was an error submitting your form'.
I have outlined a possible solution at http://codecaine.co.za/blog/posts/….
I think that the code should operate at the Zend_Form level and not at the Zend_Form_Element level.
Comments
Posted by Matthew Weier O'Phinney (matthew) on 2008-05-12T08:43:40.000+0000
Scheduling for next minor release.
Posted by bullfrogblues (gerardroche) on 2008-08-30T07:55:27.000+0000
version 1.6.0RC3
if you set the decorator "Errors" at form level
e.g.. $form->setDecorators(array( 'Description', 'Errors', 'FormElements', 'Form' ));
and then set a form level error $form->addError('Error message') it will produce a form level error
BUT, if you don't set a form level error i.e. $form->addError('Error message') an error occurs on post back:
Warning: htmlspecialchars() expects parameter 1 to be string, array given in \path\zend\1.6.0RC3\library\Zend\View\Abstract.php on line 804
Warning: htmlspecialchars() expects parameter 1 to be string, array given in \path\to\zend1.6.0RC3\library\Zend\View\Abstract.php on line 804
Posted by Matthew Weier O'Phinney (matthew) on 2008-11-05T12:51:12.000+0000
Functionality released with 1.6.0
Posted by Wil Sinclair (wil) on 2008-11-13T14:10:07.000+0000
Changing issues in preparation for the 1.7.0 release.
Posted by Giuliano Riccio (cosmo87rg) on 2009-04-10T17:17:18.000+0000
I still get an error adding the Errors decorator to the form.
This is the code that reproduces the issue using Zend 1.7.8:
Posted by Casey (casey@solid.net.au) on 2009-08-04T20:03:46.000+0000
I'm particularly keen to see this one resolved, too. Whole of form error messages is just too common a function to not be properly catered for in Zend.
Seems to me that this issue would be solved with a sanitisation filter on the {{$errors}} parameter of the {{formErrors}} function in the {{FormErrors}} view helper.
The function expects the parameter {{$errors}} to be either a string or an array of strings. When the "Errors" decorator is used at the form level and element level errors are created an array of arrays of strings is passed in. These sub arrays may then be passed to {{$this->view->escape}} which causes the above error or are output as empty strings in the html output (undesirable to have empty errors showing up).
Removing any non-string values from the {{$errors}} parameter would solve this. The filter could be akin to:
{quote} foreach ($errors as $key => $error) { if (!is_string($error)) { unset($errors[$key]); } } if (count($errors) == 0) { return ''; } {quote}
Posted by Casey (casey@solid.net.au) on 2009-08-04T20:14:42.000+0000
Oops. Wiki markup-fail. : (
Posted by Matthew Weier O'Phinney (matthew) on 2009-08-05T04:39:07.000+0000
Apparent errors in current functionality.
Posted by Matthew Weier O'Phinney (matthew) on 2009-08-06T11:09:40.000+0000
Closing again. The functionality added was the FormErrors decorator. If you wish to report form-level errors, or report all errors on a given form at once, use the FormErrors decorator. The Errors decorator is intended for individual form elements only.
Posted by Casey (casey@solid.net.au) on 2009-08-06T16:45:47.000+0000
But the FormErrors decorator doesn't support form-level errors:
Posted by Matteo Orefice (orefice.matteo) on 2009-11-02T09:31:32.000+0000
I cannot get it working. I watch in the FormErrors decorator , method _recurseForm() , I noticed $errors should be indexed by element name, but when you attach errors with $form->addError("...") error messages are indexed by int value 0,1,2....
Posted by Casey (casey@solid.net.au) on 2009-11-17T21:26:46.000+0000
You can't get it to work because Zend doesn't natively support form-level errors.
Here's a quick plugin that I use:
<>\Zend\Form\Decorator\FormLevelErrors.php
Usage example
Posted by Strict Coding (strictcoding) on 2012-01-18T12:42:13.000+0000
I know this a two year old issue, but it's still not resolved IMO. Only the code from Casey works as expected:
Whereas the behavior of Casey's code is to display: - Form-level errors at the top of the form - Element-level errors next to the elements
And I think this is what most users expect. Could it be possible to have this feature built-in ZF?
Anyone to reopen the issue, or should we create a new one as a feature request?
Posted by Matthew Weier O'Phinney (matthew) on 2012-01-18T14:15:02.000+0000
I'm confused as to what you want, to be honest.
Do I understand correctly that what you would like to do is have a form-level decorator that displays only errors attached directly to the form? (That appears to be what Casey is suggesting.)
If so, we can re-open. However, this would be a target for 1.12 (next minor release) as opposed to the next 1.11 bugfix.
Posted by Strict Coding (strictcoding) on 2012-01-18T15:32:11.000+0000
I'll try to summarize the issue with screenshots. For all examples, unless otherwise specified, this code is applied to the form:
1) If no specific decorator is used, the form-level errors are not displayed:
!http://i.imgur.com/prHiv.png!
2) If the FormErrors decorator is used, the form-level errors are shown, but the element-level errors are shown twice:
!http://i.imgur.com/UldKB.png!
3) If the Errors decorator is used, that looks perfect:
!http://i.imgur.com/dusJp.png!
But here is what happens if you remove the call to addError():
!http://i.imgur.com/Jwk0O.png!
So I'm not sure whether Zend_Form needs a new decorator, or if something just needs to be fixed. Casey highlighted a possible fix in [his comment above|#comment-33194], but that doesn't completely solve the problem: if the form is posted with only form-level errors, these are not displayed.
In my opinion, the default behavior for Zend_Form (which shouldn't break backward compatibility) should be to unconditionally display both kind of errors with default decorators, as highlighted again in this screenshot:
!http://i.imgur.com/dusJp.png!
That won't break any code relying on the default decorators, as they'll have no form-level errors set. I don't know what is the best way to achieve this goal, but I can work on a patch on my own if you agree with this behavior.
Posted by Giuliano Riccio (cosmo87rg) on 2012-01-18T15:35:13.000+0000
You can set the onlyCustomFormErrors option to true for the FormErrors decorator so that it will return only custom errors and ignore any error returned by the form elements. The code below (line 433 in FormErrors.php) is the part that retrieves the messages.
Posted by Strict Coding (strictcoding) on 2012-01-18T15:42:23.000+0000
Actually, after reading through everything again I think that all this behavior is consistent with what you've just said in your post, Matthew. What's missing is indeed a form-level-errors-only decorator, and Casey's [FormLevelErrors|#comment-36076] fits the bill perfectly. It could even be part of the default Zend_Form decorators.
Posted by Casey (casey@solid.net.au) on 2012-01-18T21:58:14.000+0000
Thanks for picking up the baton on this one, Strict Coding. ;)
Posted by Strict Coding (strictcoding) on 2012-01-19T12:45:57.000+0000
@Giuliano: sorry, I hadn't taken the time to look at your post closely. You're right, this solution, poorly documented, actually works perfectly, no need for modifications in Zend_Form!
It could be helpful to document carefully this feature on the website. Or wouldn't it be interesting, once again, to make this decorator part of the default decorators?