How do I detect an attempted submission of invalid HTML forms?
Asked Answered
G

3

11

When using HTML form validation, having an invalid input value in a form will halt submission of that form. How can I detect that the user attempted a failed form submission? The form's onsubmit handler does not fire when submission is halted by validation failure.

I'm currently listening for keypress and click events on the submit button to detect submit attempts. Is there a better way of detecting a failed form submission?

Goldfinch answered 25/6, 2013 at 14:36 Comment(12)
Like onsubmit, and then just return false if there's an invalid entry?Optimism
Do you have any browser constraints? IE10 is good with HTML5 validation but the older versions are a little lacking.Zusman
like oninvalid ? O.o ?Topdress
@AvnerSolomon Yes, I think oninvalid is pretty close to what the OP is looking for. It seems that oninvalid only applies to inputs, rather than the form itself, though. Certainly you could put an oninvalid handler on every input -- that seems like a valid (although somewhat brittle) solution.Constipate
@Constipate ... it doesn't work like that even id you do it via javascript. The validity property/object is defined only per input. All you can do is have a function launched onclick when the submit button is pressed and check each element.Topdress
@AvnerSolomon "The validity property... is defined only per input." I completely agree, as I said above ("...oninvalid only applies to inputs, rather than the form"). I meant that you could use a handler function as the oninvalid listener on every validated input of the form. Thus, if there are any invalid fields, the handler will be called at least once. This is obviously brittle and suboptimal (as I said above), since you must remember to add the handler to each input. It might be possible to use event delegation to catch all invalid events that fire from inputs inside of a form.Constipate
@Constipate your idea is good , but should be done via a javascript like this I think : jsfiddle.net/m2FDvTopdress
not sure if this is what OP is looking forTopdress
The problem with checking individual inputs is those events sometimes fire even when the form is not being submitted - they are not a good indicator for attempted form submission. @AvnerSolomon - something like an oninvalid event on the form is exactly what's needed (or, even better, perhaps an onsubmitattempt). Maybe it'll creep into the html spec at some point. It seems like a clumsy omission for there not to be an event fired at this crucial point in a HTML5 form's flowGoldfinch
@Goldfinch ... check my jsfiddle. It's not oninvalid. It checks the validity when you submitTopdress
@Avner_Solomon I think what your test function does is replicate what form.checkValidity already does nativelyGoldfinch
Can you clarify an objective metric you are seeking when you say "better"?Dilatant
L
3

A simple way to get around this is to add an event listener to each input in the form to see when it has been prevented from submitting. The 'invalid' event should do everything you need.

Example

Array.prototype.slice.call(document.querySelectorAll("[required]")).forEach(function(input){
                input.addEventListener('invalid',function(e){
                    //Your input is invalid!    
                })
            });

More info here http://www.html5rocks.com/en/tutorials/forms/constraintvalidation/

Lutetium answered 28/1, 2015 at 8:43 Comment(0)
A
3

I suggest you to use noValidate property. You can turn off default validation, and run it manually within onsubmit method

var form = document.getElementById("myForm");
form.noValidate = true; // turn off default validation

form.onsubmit = function(e) {
  e.preventDefault(); // preventing default behaviour
  this.reportValidity(); // run native validation manually

  // runs default behaviour (submitting) in case of validation success
  if (this.checkValidity()) return form.submit();

  alert('invalid'); // your code goes here
}

you can check it here: https://jsfiddle.net/titulus_desiderio/Laon29f3/

Androsterone answered 5/2, 2018 at 15:52 Comment(0)
K
2

Building on @Titulus' code above, here's how I would do it in jQuery; you can adapt this to native events if need be.

$('form-selector').on('submit', function(event) {
  // Don't do anything if constraint validation isn't supported by the browser.
  if (
    !('checkValidity' in this) ||
    // In the unlikely case this is a property but not actually a function.
    // Hypothetically, a botched polyfill could do this; it pays to be careful
    // and build resilient code.
    typeof this.checkValidity !== 'function'
  ) {
    return;
  }

  if (this.checkValidity() === true) {
    // Valid values code.
  } else {
    // Invalid values code.

    // Leave this until the last possible moment in the handler in case there's
    // an error in any of the handler code to reduce the chances of a broken
    // form where the submit does nothing. If an exception is thrown before
    // this, the browser shouldn't get this far, (hopefully) allowing the basic
    // form to still work.
    event.preventDefault();
  }
});

// Tell the browser to not validate automatically, as that would prevent submit
// from being triggered. We prevent the submission above if form doesn't pass
// validation. This is here in case there's an error in the preceding code, so
// this (hopefully) doesn't get applied in that case and browser validation
// takes place as a fallback.
this.noValidate = true;
Kidskin answered 28/3, 2019 at 22:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.