Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JQuery and HTML5 custom validation not working as intended

I just started learning JS, Jquery and HTML online. I have a question, and have tried doing things which were told in the answers of similar questions on SO, but it won't help.

I have a password form which only accepts input which have atleast 6 characters, one uppercase letter and one number. I wish to show a custom validation message which could just state these conditions again.

Here's my HTML code -

<div class="password">
     <label for="password"> Password </label>
         <input type="password" class="passwrdforsignup" name="password" required pattern="(?=.*\d)(?=.*[A-Z]).{6,}"> <!--pw must contain atleast 6 characters, one uppercase and one number-->
    </div>

I'm using JS to set the custom validation message.

JS code

$(document).ready(function () {

    $('.password').on('keyup', '.passwrdforsignup', function () {
        var getPW = $(this).value();
        if (getPW.checkValidity() === false) {
            getPW.setCustomValidity("This password doesn't match the format specified");
        }

    });

});

However, the custom validation message doesn't show. Please help. Thank you so much in advance! :)

UPDATE 1

I changed the password pattern to (?=.*\d)(?=.*[A-Z])(.{6,}). Based on 4castle's advise, I realized there were a few errors in my javascript, and changed them accordingly. However, the custom validation message still doesn't show.

JavaScript:

$(document).ready(function () {

    $('.password').on('keyup', '.passwrdforsignup', function () {
       var getPW =  $(this).find('.passwrdforsignup').get();       
        if (getPW.checkValidity() === false) {
            getPW.setCustomValidity("This password doesn't match the format specified");
        }

    });

});

Again, than you all in advance!

like image 765
keshinpoint Avatar asked Mar 05 '16 23:03

keshinpoint


2 Answers

First, update this:

var getPW =  $(this).find('.passwrdforsignup').get();

to this:

var getPW =  $(this).get(0);

...because $(this) is already the textbox .passwrdforsignup, you can't find it in itself!

The problem with setCustomValidity is, that it does only work once you submit the form. So there is the option to do exactly that:

$(function () {
    $('.password').on('keyup', '.passwrdforsignup', function () {
       var getPW =  $(this).get(0);    
       getPW.setCustomValidity("");
        if (getPW.checkValidity() === false) {
            getPW.setCustomValidity("This password doesn't match the format specified");
            $('#do_submit').click();
        }
    });
});

Please note the getPW.setCustomValidity(""); which resets the message which is important because if you do not do this, getPW.checkValidity() will always be false!

For this to work the textbox (and the submit-button) must be in a form.

Working JSFiddle

like image 163
WcPc Avatar answered Sep 30 '22 15:09

WcPc


There are several issues going on here.

  1. The pattern doesn't have a capture group, so technically nothing can ever match it. Change the pattern to (?=.*\d)(?=.*[A-Z])(.{6,})
  2. $(this).value() doesn't refer to the value of the input tag, it's referring to the value of .password which is the container div.
  3. getPW.checkValidity() and getPW.setCustomValidity("blah") are getting run on a string, which doesn't have definitions for those functions, only DOM objects do.

Here is what you should do instead (JS code from this SO answer)

$(document).ready(function() {
  $('.passwrdforsignup').on('invalid', function(e) {
    var getPW = e.target;
    getPW.setCustomValidity("");
    if (!getPW.checkValidity())
      getPW.setCustomValidity("This password doesn't match the format specified");
  }).on('input', function(e) {
    $(this).get().setCustomValidity("");
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
  <div class="password">
    <label for="password">Password</label>
    <input type="password" class="passwrdforsignup" name="password" 
           required pattern="(?=.*\d)(?=.*[A-Z])(.{6,})" />
  </div>
  <input type="submit" />
</form>
like image 43
4castle Avatar answered Sep 30 '22 14:09

4castle