Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is setCustomValidity('') ignored on input (Chrome 65)

Note: to the best of my knowledge this question is not a duplicate question of the following:

  • HTML5: Why does my “oninvalid” attribute let the pattern fail?
  • HTML5 form required attribute. Set custom validation message?
  • How can I change or remove HTML5 form validation default error messages?

Overview

Given a field that:

  • Has pattern attribute set for validation, for example "[a-f,0-9]{4}" for a 4 character hex string input.
  • Has oninvalid set with setCustomValidity('...some message...') to define a custom validation message
  • Has oninput set with setCustomValidity('') to reset on input

Here is an example showing this:

/* jshint esnext: true */
const form   = document.querySelector("#form");
const field  = document.querySelector("#field");
const output = document.querySelector("#output");

form.addEventListener('submit', (e) => {
  console.log("SUBMIT");
  output.textContent = field.value;
  e.preventDefault(); // Prevent default POST request
});

field.oninvalid = (event) => {
  console.log("INVALID");
  event.target.setCustomValidity('must be valid 4 hex characters');
}

field.oninput = (event) => {
  console.log("INPUT");
  event.target.setCustomValidity('');
}
Output: <span id="output">No output</span>
<form id="form">
  <label for="field">Enter 4 character hex code: </label>
  <input id="field" type="text" pattern="[a-f,0-9]{4}" autocomplete=off>
</form>

Validation works almost as desired, except when the user enters an invalid entry and then proceeds to try and edit it, where their following input states are still invalid:

enter image description here

At this point, neither the custom setCustomValidity message defined in oninvalid is used, nor the empty one defined in onInput.

Instead, as long as the field is in an invalid state and not blurred, the default Please match the requested format. message appears.


Question

What is going on here? Looking at the console, the oninput event is called each time, and therefore event.target.setCustomValidity(''); is called each time.

So why is it that we are still seeing the generic default validation message? Shouldn't setCustomValidity('') disable that?

An acceptable answer here should exhibit the following:

  • The parameter field is respected for validation.
  • Any validation message appears if and only if the user attempts to submit an invalid field and not when they modify the input immediately afterward.
  • The default Please match the requested format. message never appears at all.
like image 757
Johannes Avatar asked Apr 08 '18 23:04

Johannes


1 Answers

It appears that this is a bug with Chrome 65 in windows.

using setCustomValidity('') in oninput should disable the default validation messages appearing on input.

The following workaround works for me:

/* jshint esnext: true */
const form   = document.querySelector("#form");
const field  = document.querySelector("#field");
const output = document.querySelector("#output");

const pattern = field.getAttribute("pattern");

form.addEventListener('submit', (e) => {
  console.log("SUBMIT");
  output.textContent = `User submitted: ${field.value}`;
  e.preventDefault(); // Prevent default POST request
});

field.oninvalid = (event) => {
  console.log("INVALID");
  event.target.setCustomValidity('must be valid 4 hex characters');
}

field.oninput = (event) => {
  console.log("INPUT");
  event.target.setCustomValidity('');
  event.target.removeAttribute("pattern");
}

field.onchange = (event) => {
  console.log("CHANGE");
  event.target.setAttribute("pattern", pattern);
}
  Output: <span id="output">No output</span>
  <form id="form">
    <label for="field">Enter 4 character hex code: </label>
    <input id="field" type="text" pattern="[a-f,0-9]{4}" autocomplete=off>
  </form>
like image 147
Johannes Avatar answered Nov 14 '22 06:11

Johannes