0

I have an ASP.NET Core project and I'm trying to set custom text for the validation tooltip for the HTML form input field. By default, it shows "Please fill out this field". I tried to add event listeners for input, change and mouseenter events like this.

<!DOCTYPE html>
<html>
<body>
    <form>
        <label for="field1">Field1:</label>
        <input id="field1" type="text" class="validate" data-error-message="You must fill in field1!" required
               oninput="this.setCustomValidity('');this.reportValidity()" onchange="validateInputElement(this)" onmouseenter="validateInputElement(this)" />
        <label for="field2">Field1:</label>
        <input id="field2" type="text" class="validate" data-error-message="You forgot to fill in field2!" required
               oninput="this.setCustomValidity('');this.reportValidity()" onchange="validateInputElement(this)" onmouseenter="validateInputElement(this)" />
    </form>
    <script>
        function validateInputElement(element)
        {
            let validationMessage = "";
            if(element.validity !== ValidityState.valid)
            {
                validationMessage = element.dataset["errorMessage"];
            }
            else if(document.querySelector("input#field1")?.value === document.querySelector("input#field2")?.value)
            {
                validationMessage = "You must enter different values!"
            }
            element.setCustomValidity(validationMessage);
            element.reportValidity();
        }
    </script>
</body>
</html>

In this case, my custom validation messages are displayed, but the default validation messages are also displayed. How to disable default validation messages?

Solved

by adding form attribute "novalidate" and change validation function code from
if(element.validity !== ValidityState.valid)

to

if(!element.validity.valid)

The resulting code snippet is

<!DOCTYPE html>
<html>
<body>
    <form novalidate>
        <label for="field1">Field1:</label>
        <input id="field1" type="text" class="validate" data-error-message="You must fill in field1!" required
               oninput="this.setCustomValidity('');this.reportValidity()" onchange="validateInputElement(this)" onmouseenter="validateInputElement(this)" />
        <label for="field2">Field1:</label>
        <input id="field2" type="text" class="validate" data-error-message="You forgot to fill in field2!" required
               oninput="this.setCustomValidity('');this.reportValidity()" onchange="validateInputElement(this)" onmouseenter="validateInputElement(this)" />
    </form>
    <script>
        function validateInputElement(element)
        {
            let validationMessage = "";
            if(!element.validity.valid)
            {
                validationMessage = element.dataset["errorMessage"];
            }
            else if(document.querySelector("input#field1")?.value === document.querySelector("input#field2")?.value)
            {
                validationMessage = "You must enter different values!"
            }
            element.setCustomValidity(validationMessage);
            element.reportValidity();
        }
    </script>
</body>
</html>

But I also want that invalid field is not automatically receive focus on moseenter.

Modified

to remove focus from invalid input field onmouseleave and also to hide validation message after timeout expired.
Resulting code snippet:

<!DOCTYPE html>
<html>
<body>
    <form novalidate>
        <label for="field1">Field1:</label>
        <input id="field1" type="text" class="validate" data-error-message="You must fill in field1!" required />
        <label for="field2">Field1:</label>
        <input id="field2" type="text" class="validate" data-error-message="You forgot to fill in field2!" required />
    </form>
    <script>
        let validMsgTimeouts = {};
        function validateInputElement(element)
        {
            let validationMessage = "";
            if(!element.validity.valid || document.querySelector("input#field1")?.value?.trim() === document.querySelector("input#field2")?.value?.trim())
            {
                validationMessage = element.dataset["errorMessage"];
            }
            element.setCustomValidity(validationMessage);
            element.reportValidity();
            if(validationMessage?.trim()?.length > 0)
            {
                validMsgTimeouts[element.id] = setTimeout(function()
                {
                    element.setCustomValidity(" ");
                    element.reportValidity();
                    if(validMsgTimeouts[element.id] > 0)
                    {
                        clearTimeout(validMsgTimeouts[element.id]);
                    }
                }, 1000);
            }
        }
        let nodeList = document.querySelectorAll("input.validate");
        for(curElem of nodeList)
        {
            curElem.addEventListener("input", function(event) 
            {
                event.target.setCustomValidity("");
                event.target.reportValidity();
            });
            curElem.addEventListener("change", function(event) 
            {
                validateInputElement(event.target);
            });
            curElem.addEventListener("mouseenter", function(event)
            {
                validateInputElement(event.target);
            });
            curElem.addEventListener("mouseleave", function(event)
            {
                let activeElement = document.activeElement;
                if(activeElement === event.target && activeElement.validationMessage?.trim()?.length > 0)
                {
                    if(validMsgTimeouts[event.target.id] > 0)
                    {
                        clearTimeout(validMsgTimeouts[event.target.id]);
                    }
                    activeElement.blur();
                }
            });
        }
    </script>
</body>
</html>

0

3 Answers 3

1

If I understand your question I assume you want to remove the browser validation that show tooltip with the text "Please fill out this field".

In this case you just need to add the "novalidate" attribute to the form.

<!DOCTYPE html>
<html>
<body>
    <form novalidate>
        <label for="field1">Field1:</label>
        <input id="field1" type="text" class="validate" data-error-message="You must fill in field1!" required
               oninput="this.setCustomValidity('');this.reportValidity()" onchange="validateInputElement(this)" onmouseenter="validateInputElement(this)" />
        <label for="field2">Field1:</label>
        <input id="field2" type="text" class="validate" data-error-message="You forgot to fill in field2!" required
               oninput="this.setCustomValidity('');this.reportValidity()" onchange="validateInputElement(this)" onmouseenter="validateInputElement(this)" />
    </form>
    <script>
        function validateInputElement(element)
        {
            let validationMessage = "";
            if(element.validity !== ValidityState.valid)
            {
                validationMessage = element.dataset["errorMessage"];
            }
            else if(document.querySelector("input#field1")?.value === document.querySelector("input#field2")?.value)
            {
                validationMessage = "You must enter different values!"
            }
            element.setCustomValidity(validationMessage);
            element.reportValidity();
        }
    </script>
</body>
</html>

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

1 Comment

Ok. The "novalidate" attribute disables default validation messages. But validation doesn't work after the field changes. If the field becomes valid, the error message is still displayed. How to correctly remove / display validation messages on field changed?
1

Change your if statement to

 if(element.validity.valid)
            {
                validationMessage = element.dataset["errorMessage"];
            }

You're checking an object, you want to check the property value of valid on validity

source: https://developer.mozilla.org/en-US/docs/Web/API/HTMLObjectElement/validity

1 Comment

Your answer solved my second problem with displaying / remove validation messages after a field is changed.
1

If you would like your custom massage to show up as a tooltip when the mouse hover the input, you can use the title attribute. This is obviously not the same as the message showing when the input is invalidated.

<form name="form01">
  <label for="field1">Field1:</label>
  <input id="field1" name="field1" type="text" class="validate"
    title="You must fill in field1!" required>
  <label for="field2">Field2:</label>
  <input id="field2" name="field2" type="text" class="validate"
    title="You forgot to fill in field2!" required>
</form>

Comments

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.