javascripthtmldom

How change default tooltip after form validity checking to display until the error is fixed?


After filling out the form and clicking on "submit", the first field with an error has the tooltip "Value not filled in!".

It automatically disappears after the focus is changed or the page scrolls somewhere and does not appear again, except if you press "submit" again.

I would like to know if there are any ways to keep this tooltip from doing anything except when the user finally fixes the value in the field, for example, starts typing something into it.

So far the only thing I've found is controlling the text of the tooltip in the "oninvalid" event :

<form action="" method="get">
    <input type="text" name="name" required oninvalid="this.setCustomValidity('Wow!')" />
    <input type="submit" value="Submit!" />
</form>

I can also apply the same method of changing text on the "oninput" event. The text won't disappear while the user is typing something, but that's not what I'd like.....

And the main question is how to keep the tooltip, once it appears, does not disappear until you start typing text into it.


Solution

  • You are on the right track, mentioning the invalid and input events. But you cannot control the error message, so that is stays visible. You can only change the text that is displayed. You need to create your own DOM element, and display that instead.

    When the invalid event is fired, you can stop the default behavior (showing the error message), and, like in this example, change the class name of the input, so that the .invalidmessage shows. Notice that I both use the e.preventDefault() and the useCapture parameter (set to true) on the addEventListener() method.

    When the user write something in the form field the input event is fired. This can be used for testing if the input value is valid, and if so, remove the class name from the input element again.

    document.forms.form01.addEventListener('invalid', e => {
      e.preventDefault();
      e.target.classList.add('invalid');
    }, true);
    
    document.forms.form01.addEventListener('input', e => {
      if (e.target.validity.valid) {
        e.target.classList.remove('invalid');
      }
    });
    .invalidmessage {
      visibility: hidden;
    }
    
    input.invalid~.invalidmessage {
      visibility: visible;
    }
    <form name="form01" action="" method="get">
      <input type="text" name="name" required />
      <input type="submit" value="Submit!" />
      <div class="invalidmessage">Wow!</div>
    </form>