Manually Triggering Form Validation using jQuery
TL;DR: Not caring about old browsers? Use form.reportValidity()
.
Need legacy browser support? Read on.
It actually is possible to trigger validation manually.
I'll use plain JavaScript in my answer to improve reusability, no jQuery is needed.
Assume the following HTML form:
<form>
<input required>
<button type="button">Trigger validation</button>
</form>
And let's grab our UI elements in JavaScript:
var form = document.querySelector('form')
var triggerButton = document.querySelector('button')
Don't need support for legacy browsers like Internet Explorer? This is for you.
All modern browsers support the reportValidity()
method on form
elements.
triggerButton.onclick = function () {
form.reportValidity()
}
That's it, we're done. Also, here's a simple CodePen using this approach.
Approach for older browsers
Below is a detailed explanation how
reportValidity()
can be emulated in older browsers.However, you don't need to copy&paste those code blocks into your project yourself — there is a ponyfill/polyfill readily available for you.
Where reportValidity()
is not supported, we need to trick the browser a little bit. So, what will we do?
- Check validity of the form by calling
form.checkValidity()
. This will tell us if the form is valid, but not show the validation UI. - If the form is invalid, we create a temporary submit button and trigger a click on it. Since the form is not valid, we know it won't actually submit, however, it will show validation hints to the user. We'll remove the temporary submit button immedtiately, so it will never be visible to the user.
- If the form is valid, we don't need to interfere at all and let the user proceed.
In code:
triggerButton.onclick = function () {
// Form is invalid!
if (!form.checkValidity()) {
// Create the temporary button, click and remove it
var tmpSubmit = document.createElement('button')
form.appendChild(tmpSubmit)
tmpSubmit.click()
form.removeChild(tmpSubmit)
} else {
// Form is valid, let the user proceed or do whatever we need to
}
}
This code will work in pretty much any common browser (I've tested it successfully down to IE11).
Here's a working CodePen example.
var field = $("#field")
field.keyup(function(ev){
if(field[0].value.length < 10) {
field[0].setCustomValidity("characters less than 10")
}else if (field[0].value.length === 10) {
field[0].setCustomValidity("characters equal to 10")
}else if (field[0].value.length > 10 && field[0].value.length < 20) {
field[0].setCustomValidity("characters greater than 10 and less than 20")
}else if(field[0].validity.typeMismatch) {
field[0].setCustomValidity("wrong email message")
}else {
field[0].setCustomValidity("") // no more errors
}
field[0].reportValidity()
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="email" id="field">
In some extent, You CAN trigger
HTML5 form validation and show hints to user without submitting the form!
Two button, one for validate, one for submit
Set a onclick
listener on the validate button to set a global flag(say justValidate
) to indicate this click is intended to check the validation of the form.
And set a onclick
listener on the submit button to set the justValidate
flag to false.
Then in the onsubmit
handler of the form, you check the flag justValidate
to decide the returning value and invoke the preventDefault()
to stop the form to submit. As you know, the HTML5 form validation(and the GUI hint to user) is preformed before the onsubmit
event, and even if the form is VALID you can stop the form submit by returning false or invoke preventDefault()
.
And, in HTML5 you have a method to check the form's validation: the form.checkValidity()
, then in you can know if the form is validate or not in your code.
OK, here is the demo: http://jsbin.com/buvuku/2/edit
You can't trigger the native validation UI (see edit below), but you can easily take advantage of the validation API on arbitrary input elements:
$('input').blur(function(event) {
event.target.checkValidity();
}).bind('invalid', function(event) {
setTimeout(function() { $(event.target).focus();}, 50);
});
The first event fires checkValidity
on every input element as soon as it loses focus, if the element is invalid
then the corresponding event will be fired and trapped by the second event handler. This one sets the focus back to the element, but that could be quite annoying, I assume you have a better solution for notifying about the errors. Here's a working example of my code above.
EDIT: All modern browsers support the reportValidity()
method for native HTML5 validation, per this answer.