6

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!

keshinpoint
  • 1,001
  • 3
  • 14
  • 25
  • @thisOneGuy, no. `required` is a flag and `pattern` is an attribute. It could be written like: `required="true" pattern="blah"`. – Sumner Evans Mar 05 '16 at 23:56
  • @jsve thanks, haven't come across that before – thatOneGuy Mar 05 '16 at 23:56
  • Change your pattern to `(?=.*\d)(?=.*[A-Z])(.{6,})` so that there is a capture group. – 4castle Mar 05 '16 at 23:59
  • Does `checkValidity` use the pattern? It would help if you posted the code for it. – 4castle Mar 06 '16 at 00:03
  • 4castle, thanks, I'll change the pattern. Also, that really is all my relavant code. I assumed checkValidity takes the pattern into account, if not, what exactly is it checking against? The input type? – keshinpoint Mar 06 '16 at 00:32

2 Answers2

3

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>
Community
  • 1
  • 1
4castle
  • 32,613
  • 11
  • 69
  • 106
  • Thanks for the points 4Castle! I'll make the required changes. However, for point 3, I thought checkValidity() automatically checks for the validity of the input (as shown in http://www.w3schools.com/js/js_validation_api.asp). I based my function on this. Is this a seperate library that I need to link to? – keshinpoint Mar 06 '16 at 00:37
  • Woah! Sorry, those functions were new to me. It shows on that page that they have to be run on DOM objects though, so I've changed my answer now so that it is correct. Thank you very much! – 4castle Mar 06 '16 at 00:49
  • Hi 4castle, thanks for the updated answer. However, it still doesn't do the trick. Here's my code again - `$(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"); } }); });` – keshinpoint Mar 06 '16 at 01:06
  • I did some more research, and found that `.checkValidity()` isn't supported by many browsers. I also found an event called `oninvalid` that is perfect for this, and found a SO answer that uses it to do what you need. Let me know if it works for you! – 4castle Mar 06 '16 at 17:03
  • Oops, nvm it's supported. But use this JS code instead, it is much faster because it only checks the validity once per submit click instead of every time you keyup. – 4castle Mar 06 '16 at 17:12
3

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

WcPc
  • 457
  • 2
  • 11
  • Thank you so so much WcPc. The detailed solution greatly helped me understand where I went wrong! Really appreciate it! The custom validation message now appears as intended. – keshinpoint Mar 06 '16 at 16:38