I've implemented a custom validation message on my input for the pattern
validation rule while leaving the default message for required
as is. However, when I do so, once the input becomes invalid, it never becomes valid again, even though I am meeting the pattern
criteria.
document.addEventListener("DOMContentLoaded", function () {
const txtUsername = document.getElementById("UserName");
txtUsername.oninvalid = function (e)
{
const input = e.target;
if (input.validity.patternMismatch)
{
input.setCustomValidity("Usernames cannot contain the @ symbol");
}
}
})
<form onsubmit="event.preventDefault(); alert('Form submitted');" action="post">
<!--pattern regex prohibits use of the @ symbol-->
<input id="UserName" type="text" pattern="^((?!@).)*$" required />
<button type="submit">Submit</button>
</form>
When I remove my custom oninvalid
event handler, this issue does not occur. What am I doing wrong?
One additional question, though not essential to me resolving this issue: why does Chrome's built in validation pop-up text animate in so slowly and choppy, almost as if there's some sort of performance bottleneck? My machine is powerful and has no issues with any other type of graphical processing.
First of all, per MDN:
It's vital to set the message to an empty string if there are no errors. As long as the error message is not empty, the form will not pass validation and will not be submitted.
This agrees with that the HTML standard says:
Suffering from a custom error
When a control's custom validity error message (as set by the element's
setCustomValidity()
method orElementInternals
'ssetValidity()
method) is not the empty string.An element satisfies its constraints if it is not suffering from any of the above validity states.
Your sample does not clear the custom error if the form field is determined to be valid. As such, once the field is determined invalid, it stays so for the remainder of the session.
Moreover, you modify custom error only after the field has already been determined invalid. This means the form will still not be submitted even if you clear the message in the same handler.
A better way to accomplish your goal would be to monitor the field in the change
event handler for the field and set the custom message there:
document.getElementById('UserName').addEventListener('change', function (ev) {
const input = ev.target;
if (input.validity.patternMismatch) {
input.setCustomValidity("Usernames cannot contain the @ symbol");
} else {
input.setCustomValidity("");
}
}, false);
<form onsubmit="event.preventDefault(); alert('Form submitted');" action="post">
<!--pattern regex prohibits use of the @ symbol-->
<input id="UserName" type="text" pattern="^((?!@).)*$" required />
<button type="submit">Submit</button>
</form>