Why does my "oninvalid" attribute let the pattern fail?
Asked Answered
C

5

39

This little HTML5 password field works perfectly WITHOUT the oninvalid attribute (the pattern say: minimum 6 characters):

<form>
    <input type="password" name="user_password_new" pattern=".{6,}" required />      
    <input type="submit"  name="register" value="Register" />
</form>

See the jsFiddle here.

But when I add an oninvalid attribute that gives out a custom error message when user's input does not fit the pattern, the entire field NEVER becomes valid, see the code here:

<form>
    <input type="password" name="user_password_new" pattern=".{6,}" oninvalid="setCustomValidity('Minimum length is 6 characters')" required />      
    <input type="submit"  name="register" value="Register" />
</form>

See the jsFiddle here.

Can you spot the mistake ?

Caudle answered 31/5, 2013 at 23:27 Comment(0)
F
119

If you set a value with setCustomValidity() then the field is invalid. That is setting a non-zero length string causes the browser to consider the field invalid. In order to allow for the effects of any other validations you have to clear the custom validity:

<input type="password" name="user_password_new" pattern=".{6,}" required
   oninvalid="setCustomValidity('Minimum length is 6 characters')" 
   oninput="setCustomValidity('')" />
Fanya answered 2/6, 2013 at 0:54 Comment(5)
You Sir, are my hero! Perfect answer. Thanks a lot!Caudle
A good explanation. A simpler solution to the problem is to remove the oninvalid attribute and use the value attribute instead to contain a short explanation of the expected data format. This is the way recommended in HTML5 CR. The attribute value="Minimum length is 6 characters" would work both as clarifying the error message and as a tooltip on mouseover.Gaussmeter
@JukkaK.Korpela: I think you mean the title attribute.Cymene
@TimYates, you’re right. Read both occurrences of value in my comment as title.Gaussmeter
Note, I thought this wasn't working for radio buttons but it was because I only did it on the first one and it happened to be disabled in this case. It seems, at least in Chrome, the error message is taken from the first enabled radio button. So in order to make sure the custom message is always used it needs to be set on every radio input, unfortunately. Probably better to just do in JS depending on amount of radio buttons.Accountable
A
19

Since I stumbled on the same problem, here is my solution – tested and working with FF, Chrome, IE 10, Edge (Feb 2017).

<form>
<input pattern="1234" oninput="setCustomValidity(''); checkValidity(); setCustomValidity(validity.valid ? '' :'please enter 1234');">
<input type="email" required>
<input type="submit">
</form>

Explanation:

setCustomValidity(''); removes the custom error string which otherwise would always result in an invalid field at the validation process.

checkValidity(); does a manual validation – the same as it is happening at the form submisson. The result is stored in validity.valid.

The second setCustomValidity(validity.valid ? '' :'please enter 1234'); now sets the error string according to the validation result. If the field is valid it needs to be empty, otherwise the custom error string can be set.

Autoerotism answered 23/2, 2017 at 17:11 Comment(1)
This does fit my needs and it removes the 'You must use this format:' message. Thanks and +1Kell
M
4

I like to use like this:

<input type="email" name="Email" required oninvalid="setCustomValidity('ErrorMessage')"/>

And unplugged for all of valid input data

UPD, one more thing for better work:

    $("input").attr("onblur", "setCustomValidity('')");
    $("input").attr("oninput", "setCustomValidity(' ')");
Mecklenburg answered 18/5, 2017 at 11:48 Comment(1)
I think this is the simplest solution +1Mccracken
A
1

Although the answers for this question had good information, they weren't sufficient for my needs. I need to display different messages depending on which validity rule failed. In the other examples, the same validation failure message is used for all valiation failures.

The "validity" property of a form object holds the key to creating more than one validation failure message.

You can review all of the different "validity" property properties at this web site.

https://www.w3schools.com/js/js_validation_api.asp

This example shows how to display two different validation messages. If you uncomment the console.log() line below you can watch the validity property change as you type in a field.

<label for="user_password_new">New Password:</label>
<input type="password" name="user_password_new" id="user_password_new"
    pattern=".{6,}"
    value=""
    required
    oninput="
        setCustomValidity('');
        checkValidity();
        // console.log(validity);
        if (validity.patternMismatch) {
            setCustomValidity('Please enter at least six characters.');
        }
        else if (validity.valueMissing) {
            setCustomValidity('This field is required.');
        }
        else if (validity.valid) {
            setCustomValidity('');
        }
        // allow default validation message to appear for other validation failures
    "
>

NOTE: Some validity checks are "type" specific. For example, the "rangeOverflow", "rangeUnderflow", and "stepMismatch" attributes get set if type uses them; type="number".

Aidaaidan answered 5/11, 2018 at 19:22 Comment(0)
R
0

You can use title as long as you don't mind having 'You must use this format:' before your message. If you want a full custom message, the setCustomValidity() worked for me.

Rafferty answered 13/5, 2015 at 14:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.