A custom validation message is not shown if setCustomValidity() is called in ‘submit’ event handler.
@tkent:
I confirmed Opera 11.50 worked as your expectation, but Firefox 6 and
Chrome 14 didn’t.However, Chrome’s behavior is correct according to the standard.
http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#form-submission-algorithm
- 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 abort
these steps.- If the submitted from submit() method flag is not set, then fire
a simple event that is cancelable named submit, at form. If the
event’s default action is prevented (i.e. if the event is canceled)
then abort these steps. Otherwise, continue (effectively the default
action is to perform the submission).Browsers must invoke the interactive validation BEFORE ‘submit’ event
is fired. You need to call setCustomValidity() before ‘submit’ event
if you want a browser to show a validation message. Opera seems to
handle these steps in incorrect order. Note that checkValidity() in
your code has no effect anyway. checkValidity() never shows a
validation message.
http://code.google.com/p/chromium/issues/detail?id=95970
[Bug 11287] New: ‘setCustomValidity’ call in element should use ‘oninput’ event…
@Nick:
‘setCustomValidity’ call in element should use ‘oninput’
event…
http://lists.w3.org/Archives/Public/public-html/2010Nov/0186.html
Re: [whatwg] Form element invalid message
@Mounir Lamouri:
So, what you do is making the element valid in the invalid event which
is too late. After the invalid event, Firefox tries to show the UI
using the validationMessage which return the empty string when the
form is valid. You should cancel the event if you want to have no UI
at all but still cancel the submission. You should use
onchange/oninput (emphasis added) to change the validity state if you want the form to
be submitted.
http://www.mail-archive.com/whatwg@lists.whatwg.org/msg23762.html
The fix is to validate the input with the “input” event handler instead of the “submit” event handler.
<!DOCTYPE html>
<html dir="ltr" lang="en">
<head>
<meta charset="utf-8"/>
<title>Validation test case</title>
</head>
<body>
<form id="testForm">
<input type="text" id="answer" pattern="[A-Za-z]+" autofocus required/>
<input type="submit" value="OK"/>
</form>
<script>
/*jslint browser: true, vars: true, white: true, maxerr: 50, indent: 4 */
(function (console)
{
"use strict";
var form = null;
var answer = null;
var isCorrectAnswer = function (value)
{
return (value === "a");
};
var closeValidation = function (element)
{
// Close the form validation error message if displayed.
element.blur();
element.focus();
};
var validateForm = function (event)
{
event.preventDefault();
event.stopPropagation();
var isValidForm = event.target.checkValidity();
if (isValidForm)
{
console.log("Correct answer.");
closeValidation(answer);
form.reset();
}
else
{
console.log("Incorrect answer.");
}
};
window.addEventListener("DOMContentLoaded", function ()
{
form = document.getElementById("testForm");
answer = document.getElementById("answer");
form.addEventListener("submit", validateForm, false);
answer.addEventListener("input", function ()
{
// Only show custom form validation error message if the value matches the pattern.
if (answer.value.match(new RegExp(answer.getAttribute("pattern"))))
{
answer.setCustomValidity(isCorrectAnswer(answer.value) ? "" : "Incorrect answer.");
}
}, false);
}, false);
}(window.console));
</script>
</body>
</html>