This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 19751 - Constraint Validation - Add a means of detecting invalid form submissions
Summary: Constraint Validation - Add a means of detecting invalid form submissions
Status: RESOLVED WORKSFORME
Alias: None
Product: HTML WG
Classification: Unclassified
Component: HTML5 spec (show other bugs)
Version: unspecified
Hardware: All All
: P2 normal
Target Milestone: ---
Assignee: Robin Berjon
QA Contact: HTML WG Bugzilla archive list
URL:
Whiteboard:
Keywords: CR
Depends on:
Blocks:
 
Reported: 2012-10-29 03:02 UTC by TJ VanToll
Modified: 2013-06-11 11:20 UTC (History)
5 users (show)

See Also:


Attachments

Description TJ VanToll 2012-10-29 03:02:32 UTC
The traditional means of performing client side validation has always been to listen for the submit event on a form, manually perform some error checking logic, and prevent the form submission if necessary.

With HTML5's constraint validation this approach no longer works because a form will not fire a submit event until its data is deemed valid.  For most situations this is fine, but with the current constraint validation API it is not possible to know when a user attempted a form submission and it was prevented.

Yes an invalid event will be fired for each invalid field, but there's no way tell whether that event occurred because the user has just finished interacting with that field (i.e. blur), versus an attempted form submission.

Use case: Display a list of all error messages to the user whenever they attempt a submission with invalid data.  This is a technique frequently used on web forms and it is difficult to implement with the constraint validation API currently.

At the moment you have to listen for anything that might trigger a submission (usually clicks of submit buttons) and run the appropriate logic there.  I give concrete code on how I've implemented this here http://tjvantoll.com/2012/08/05/html5-form-validation-showing-all-error-messages/.

While this works it is not ideal.  An event fired on the form whenever a form submission was attempted and failed (much like invalid on form elements) would make the implementation much simpler.

Thanks.
Comment 1 Mounir Lamouri 2012-10-29 09:46:49 UTC
(In reply to comment #0)
> The traditional means of performing client side validation has always been
> to listen for the submit event on a form, manually perform some error
> checking logic, and prevent the form submission if necessary.
> 
> With HTML5's constraint validation this approach no longer works because a
> form will not fire a submit event until its data is deemed valid.  For most
> situations this is fine, but with the current constraint validation API it
> is not possible to know when a user attempted a form submission and it was
> prevented.

The invalid event tells you that.

> Yes an invalid event will be fired for each invalid field, but there's no
> way tell whether that event occurred because the user has just finished
> interacting with that field (i.e. blur), versus an attempted form submission.

The invalid event should only be sent when the element has been found invalid when trying to submit the form.

> Use case: Display a list of all error messages to the user whenever they
> attempt a submission with invalid data.  This is a technique frequently used
> on web forms and it is difficult to implement with the constraint validation
> API currently.

When the 'invalid' event occurs, you can read all 'validationMessage' attributes.

> At the moment you have to listen for anything that might trigger a
> submission (usually clicks of submit buttons) and run the appropriate logic
> there.  I give concrete code on how I've implemented this here
> http://tjvantoll.com/2012/08/05/html5-form-validation-showing-all-error-
> messages/.
> 
> While this works it is not ideal.  An event fired on the form whenever a
> form submission was attempted and failed (much like invalid on form
> elements) would make the implementation much simpler.

This is quite simple actually. See this example:
http://software.hixie.ch/utilities/js/live-dom-viewer/?saved=1870
Comment 2 TJ VanToll 2012-10-30 02:03:12 UTC
(In reply to comment #1)

> > At the moment you have to listen for anything that might trigger a
> > submission (usually clicks of submit buttons) and run the appropriate logic
> > there.  I give concrete code on how I've implemented this here
> > http://tjvantoll.com/2012/08/05/html5-form-validation-showing-all-error-
> > messages/.
> > 
> > While this works it is not ideal.  An event fired on the form whenever a
> > form submission was attempted and failed (much like invalid on form
> > elements) would make the implementation much simpler.
> 
> This is quite simple actually. See this example:
> http://software.hixie.ch/utilities/js/live-dom-viewer/?saved=1870

The issue with this approach is that the logic will run once per invalid field on the form.  If you give an invalid email address in your example you'll end up with two alerts.  Unless I'm missing something there's no way to run the logic just one time per attempted submission with the current API.
Comment 3 Erika Doyle Navara 2012-11-19 23:22:36 UTC
Moving this to HTML.next as we work to lock down HTML5.0 for CR.
Comment 4 Robin Berjon 2013-01-21 15:59:26 UTC
Mass move to "HTML WG"
Comment 5 Robin Berjon 2013-01-21 16:02:12 UTC
Mass move to "HTML WG"
Comment 6 Robin Berjon 2013-03-11 15:52:07 UTC
(In reply to comment #2)
> (In reply to comment #1)
> > > At the moment you have to listen for anything that might trigger a
> > > submission (usually clicks of submit buttons) and run the appropriate logic
> > > there.  I give concrete code on how I've implemented this here
> > > http://tjvantoll.com/2012/08/05/html5-form-validation-showing-all-error-
> > > messages/.
> > > 
> > > While this works it is not ideal.  An event fired on the form whenever a
> > > form submission was attempted and failed (much like invalid on form
> > > elements) would make the implementation much simpler.
> > 
> > This is quite simple actually. See this example:
> > http://software.hixie.ch/utilities/js/live-dom-viewer/?saved=1870
> 
> The issue with this approach is that the logic will run once per invalid
> field on the form.  If you give an invalid email address in your example
> you'll end up with two alerts.  Unless I'm missing something there's no way
> to run the logic just one time per attempted submission with the current API.

The OP has a point here Mounir, alerting twice doesn't help. I hit the same issue with a more sophisticated example in which my invalid handler would cause an error dialog element to be shown, and would append the validationMessage to an ul. This all sounded great, until the user submitted again with errors, at which point it just appended errors to the list without clearing the previous ones (since nothing said that all errors had been received). There are work-arounds, but we shouldn't design something on such grounds.

TJ: is there a preferred solution you would have here? Perhaps a new invalid-submit event with all validationMessage collected and mapped to the relevant elements?
Comment 7 TJ VanToll 2013-03-12 02:27:46 UTC
The most popular polyfill for this API (webshims) triggers "firstinvalid" and "lastinvalid" events.

From its docs (http://afarkas.github.com/webshim/demos/demos/webforms.html):

firstinvalid: firstinvalid is a simple, bubbling event, which is triggered on the first invalid form element. Preventing the default of firstinvalid will automatically prevent the default behavior of all current invalid elements.

lastinvalid: lastinvalid is an extended, bubbling, (but) uncancelable event, which is triggered on the last invalid form element. The property invalidlist is a jQuery-collection of all current invalid elements.

I present this to show the most popular solution for this use case in the wild.  In my mind we only need one event fired after invalid events have been fired for each invalid field within the form.  

Would it be possible to fire an "invalid" event on the form itself?  The event's target could be checked, and if it is a form you would know that this situation occurred.  If not "validation", "forminvalid", "invalidsubmit", etc would be fine.  We just need a hook.

A mapping of invalid fields --> validationMessage would be a nicety, but it would also be easy to derive.
Comment 8 Robin Berjon 2013-06-11 11:20:40 UTC
EDITOR'S RESPONSE: This is an Editor's Response to your comment. If you are
satisfied with this response, please change the state of this bug to CLOSED. If
you have additional information and would like the Editor to reconsider, please
reopen this bug. If you would like to escalate the issue to the full HTML
Working Group, please add the TrackerRequest keyword to this bug, and suggest
title and text for the Tracker Issue; or you may create a Tracker Issue
yourself, if you are able to do so. For more details, see this document:

   http://dev.w3.org/html5/decision-policy/decision-policy.html

Status: Accepted
Change Description: none (this has already been fixed in the meantime)
Rationale:

This has been addressed while this discussion was taking place. Please consider this note:

"""
Note: When a form is submitted, invalid events are fired at each form control that is invalid, and then at the form element itself. This can be useful for displaying a summary of the problems with the form, since typically the browser itself will only report one problem at a time.
"""
-- http://www.w3.org/html/wg/drafts/html/master/forms.html#client-side-form-validation

and more importantly this normative requirement:

"""
If the submitted from submit() method flag is not set, and the submitter element's no-validate state is false, then interactively validate the constraints of form and examine the result: if the result is negative (the constraint validation concluded that there were invalid fields and probably informed the user of this) then fire a simple event named invalid at the form element and then abort these steps.
"""
-- http://www.w3.org/html/wg/drafts/html/master/forms.html#form-submission-algorithm

What happens here is that when the form is submitted (using whatever method) then its validity is assessed. If it is invalid, in addition to the invalid events for each control, there is a final invalid event dispatched at the form itself. So you can check what the event's target is and know that it was an invalid event for the form itself.