11

Pretty simple set up:

<input id="Input" type="text" minlength="8" required />
<script>
    const input = window.document.getElementById('Input');
    input.value = "foobar"
    console.log(input.checkValidity());
</script>

The following returns true when it should be false. See https://jsbin.com/huqowesewu/edit?html,output

Why in the world is this? The input has a length of 6, which is less than 8, ergo, it should be invalid. But it's not. Is this attribute broken? Or is checkValidity() broken? I'm baffled to say the least.

Devildude4427
  • 892
  • 1
  • 8
  • 28

2 Answers2

11

This should work. As per WHATWG it should work. As per caniuse.com it should work.

However, it appears to only work when the value was edited by the user, not set from JavaScript. I did not find anything on WHATWG or MDN regarding that behavior (perhaps it is there, and I don't know where to look).

It is documented on WHATWG. Both minlength and maxlength require user interaction. To be more precise, when the user modifies the input value a "dirty value flag" is set, which is taken into account in the validation. See Limiting user input length: the maxlength attribute:

Constraint validation: 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 length of the element's API value is less than the element's minimum allowed value length, then the element is suffering from being too short.


Things I tested but do not make it work: Listening to the "invalid" event. Triggering an "input" event. Removing focus from the input with blur() before checking. Checking from queueMicrotask(function). Checking from requestAnimationFrame(function). Checking from double requestAnimationFrame(function). Checking with a valid value and then checking with an invalid value. Setting either a valid or an non-empty invalid default value via HTML attribute. Setting the value with setAttribute from JavaScript. Setting defaultValue.

I tested on Chromium Edge and Firefox.

I also found the question How can I trigger the minlength validation when field is set programmatically? which provided no solution.


Anyway, you can use pattern to mimic this validation constraint. And yes, that one will trigger from JavaScript correctly, as most validation constraints do. See https://stackoverflow.com/a/10294291/402022

Theraot
  • 31,890
  • 5
  • 57
  • 86
  • Ah, okay, glad I'm not doing something horribly wrong. I came across `pattern` which I swapped to but I really wanted to know why this wasn't working. Broken spec is beyond my control though. Thanks for all your time. – Devildude4427 Mar 31 '21 at 23:35
  • @Devildude4427 found and added the spec. – Theraot Apr 01 '21 at 00:21
  • Thanks for sharing your efforts @Devildude4427 I've been testing it for hours to understand what I've done wrong. Seems like it's not a bug, it's a feature... – Cihad Turhan Mar 06 '23 at 21:19
-1

This is a better way to get false.

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <input type="text" minlength="8" id="Input" required />
  <button onclick = "myfunction()">TRY</button>
  <p id="demo"></p>
  <script>

    function myfunction(){
      var iny = document.getElementById("Input");
       document.getElementById("demo").innerHTML = iny.checkValidity();
    }
    
  </script>
</body>
</html>
  • That'll still return `true` when it should `false`. All you're doing is moving the console log into the DOM. – Devildude4427 Mar 31 '21 at 23:33
  • Change function to this: function myfunction(){ var iny = document.getElementById("Input"); console.log(iny.checkValidity()); } – user15525969 Mar 31 '21 at 23:38
  • 1
    You're forgetting to set the input content. You need to do that or your "solution" is just ignoring the problem. – Devildude4427 Mar 31 '21 at 23:39
  • 1
    The `required` constraint works. The issue is with `minlength`. We, of course, use them together because if the input is not required, it does not have to be valid. To reiterate, when the `input` is empty, we get `false` as expected. For which `required` is sufficient. But when the `input` is not empty, but its contents is shorter than `minlength` we get `true`, meaning that `minlength` wasn't checked. We of course want `false` in that situation. To reiterate again, we want `false` when the `input` is not empty and its contents is shorter than `minlength`. – Theraot Mar 31 '21 at 23:50