Search code examples
javascripthtmlforms

How do I check the validity of a HTML form element without triggering the invalid event


In my snippet below you can see that I have a form where I wish to only enable the submit button after all input fields are correctly filled out.

I do this by adding a change event listener to the form itself and then calling the checkValidity() function on the inputs inside the form. (in this example I have only 1) If all the checkValidity() checks return true, I enable the button, if not I disable it.

However, I noticed that calling checkValidity() this also triggers the invalid event listener when the input is invalid which is not desireable. I am using the invalid event listener for other stuff like if the form gets submitted anyways via keyboard shortcuts or other means so I can display an appropriate error message for the input fields because the submit call also will check the validity and trigger the invalid event.

So is there a way to check the validity of the input without triggering the invalid event so I can keep my invalid event listener and not have to write a custom validity check function for every single input?

const form = document.getElementById("form");
const input = document.getElementById("input");
const button = document.getElementById("button");
const checkbox = document.getElementById("checkbox");

form.addEventListener("change", () => {
    if (!checkbox.checked) return;
    if (input.checkValidity()) {
        button.removeAttribute("disabled");
    } else {
        button.setAttribute("disabled", "");
    }
})

input.addEventListener("invalid", (e) => {
    e.preventDefault();
    console.log("Invalid");
});

form.addEventListener("submit", (e) => {
    e.preventDefault();
    console.log("submitted!");
});
button[disabled] {
    opacity: 0.5;
}
<form id="form">
  <input type="text" id="input" minLength="5">
  <button type="submit" id="button" disabled>Submit</button>
</form>
<br>
<label>
  <span>turn on change listener</span>
  <input type="checkbox" id="checkbox" checked>
</label>


Solution

  • Using input.validity.valid allows you to check the validity of the input without triggering the invalid event, thus keeping your existing invalid event listener functional for other scenarios like form submission attempts. hope this might help out

    form.addEventListener("change", () => {
        if (!checkbox.checked) return;
        if (input.validity.valid) {
            button.removeAttribute("disabled");
        } else {
            button.setAttribute("disabled", "");
        }
    });