7

I have a text input with minlength defined. When a user enters text, the input's validity state is updated immediately. If I alter the value in code, the validity state reset to show as valid -- even with a constraint violated, validity.valid is true.

const input = document.getElementById("input");
const label = document.getElementById("label");
document.getElementById("rightButton").addEventListener("click", evt => {
  input.value = "ABCDE";
});
document.getElementById("wrongButton").addEventListener("click", evt => {
  input.value = "AB";
});

setInterval(() => label.innerHTML = input.validity.valid, 250);
<input type="text" id="input" minlength="4">
<span id="label"></span>
<hr/>
<button id="rightButton">Make It Right</button>
<button id="wrongButton">Make It Wrong</button>

Why doesn't automatic validity checking run when I assign to input.value? Is this documented somewhere? Is there a method I can call to trigger the browser's internal validation process, rather than having to do my own checks and call setCustomValidity?

4
  • Also: I've tried manually calling checkValidity() after assigning a value to input.value but it always returns true. Commented Nov 9, 2018 at 13:19
  • Instead of setting an interval, can you try "label.innerHTML = input.validity.valid" inside your callback functions for the clicks? Commented Nov 9, 2018 at 14:59
  • From your answer it looks like you figured this out, but I used the interval to be absolutely certain that it wasn't something like maybe the validation logic wouldn't run until the next render loop. I've had crazier things bite me before... Commented Nov 12, 2018 at 10:55
  • I have a similar problem with <input type="date"> fields. A JSFiddle illustrating the problem can be found here: jsfiddle.net/thetetet/rmpw7s4y/35 The "last changed by a user edit" note seems to be true for any of the constraint checks for the ValueState information, as pointed out below at stackoverflow.com/a/53261163/1337474 Commented Jul 20, 2020 at 20:58

2 Answers 2

10

Using pattern is a reasonable approach to solving my problem, and all credit to Sujil for prompting me to run down exactly what's going on here. I just wanted to clarify for any future readers with this issue.

From the spec for minlength (emphasis mine):

If an element has a minimum allowed value length, its dirty value flag is true, its value was last changed by a user edit (as opposed to a change made by a script), its value is not the empty string, and the code-unit length of the element’s value is less than the element’s minimum allowed value length, then the element is suffering from being too short.

This language ("last changed by a user edit") is also in the spec for maxlength, but not for any other constraints. That's why there is no method to "force validation", because all constraints are being applied all the time, except these two. I'm not sure why, but it's very clear and universally implemented.

Sign up to request clarification or add additional context in comments.

1 Comment

Useful information!!! To solve the issue I have to add a change event handler on the input element to set custom validity message.
4

In your case, you need to use pattern in your input element. Basically, the content of the pattern is the regular expression. In the code below, .{4,} means validate for 3 or more characters.

const input = document.getElementById("input");
const label = document.getElementById("label");
document.getElementById("rightButton").addEventListener("click", evt => {
  input.value = "ABCDE";
});
document.getElementById("wrongButton").addEventListener("click", evt => {
  input.value = "AB";
});

setInterval(() => label.innerHTML = input.validity.valid, 250);
<input type="text" pattern=".{4,}"  id="input">
<span id="label"></span>
<hr/>
<button id="rightButton">Make It Right</button>
<button id="wrongButton">Make It Wrong</button>

1 Comment

This is very interesting. It sounds like maybe my assumption was wrong -- assigning to .value does apply a validity check, in this case, but only for the pattern constraint and not the minlength constraint. Is it supposed to work this way? Is this behavior documented somewhere? Is it consistent among browsers that support minlength? I have the feeling I'm going to be submitting some bug reports. ETA: to answer my own last question, Chrome, Edge, and FF all behave the same way. I'd still like to know why, though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.