1

Trying to do a password change page with password, new_password and confirm_password.

I have two problems:

  1. The password validator strength fiield is being triggered by input to all three password fields whereas I only want it to apply to the new_password field where the user chooses their new password.
  2. The validation isn't appending the text error messages, it changes the class to be checked or unchecked fine so a cross or tick is displayed but doesn't give the user a message saying why a field has failed validation.

I'm using jQuery 1.8.3, jquery.validate and jquery.validate.password from bassistance.

Any ideas gratefully received.

HTML and jQuery below:

<form novalidate="novalidate" method="POST" action="/frontend_dev.php/profile/change-password" name="change_account_data_form" id="change_account_password_form">

                    <table cellspacing="0">
                        <tbody><tr>
                            <td colspan="3">
                                                                </td>
                        </tr>
                      <tr>
                        <td><label for="current_password">Current password:</label></td>
                        <td><input style="display: none;" name="change_password[password]" id="password" class="text" type="password"><input class="text" type="text"></td>
                        <td></td>
                      </tr>
                      <tr>
                        <td><label for="password">New password:</label></td>
                        <td><input style="display: none;" name="change_password[new_password]" id="new_password" class="text password" type="password"><input class="text password" type="text"></td>
                        <td><div class="password-meter">
                                                            <div class="password-meter-message"> </div>
                                                            <div class="password-meter-bg">
                                                                    <div class="password-meter-bar"></div>
                                                            </div>
                                                    </div>

                                                        </td>
                      </tr>
                      <tr>
                        <td><label for="password_confirm">Confirm password:</label></td>
                        <td><input style="display: none;" name="change_password[password_confirm]" id="password_confirm" class="text" type="password"><input class="text" type="text"></td>
                        <td></td>
                      </tr>

                    </tbody></table>
        <input name="change_password[id]" value="2" id="change_password_id" type="hidden"><input name="change_password[_csrf_token]" value="66dbd4dc532ad1c9dd668e5e86235136" id="change_password__csrf_token" type="hidden">                       
                <div class="submitBlock">
            <input class="buttonSubmit" value="" type="submit">
                </div>

        </form>

JQUERY:

$(document).ready(function() {
// validate signup form on keyup and submit
var validator = $("#change_account_password_form").validate({
        debug:true,
        errorClass: 'jqueryError',
    rules: {

        password: {
            required: true,
            minlength: 8
        },
        new_password: {
            password: "#new_password",
                            minlength: 8
        },
        password_confirm: {
            required: true,
            equalTo: "#new_password"
        }
    },
    messages: {
        password: {
            required: "Enter your current password",
            minlength: jQuery.format("Enter at least {0} characters")
        },
        new_password: {
            required: "Enter your new password",
            minlength: jQuery.format("Enter at least {0} characters")
        },
        password_confirm: {
            required: "Repeat your password",
            minlength: jQuery.format("Enter at least {0} characters"),
            equalTo: "Enter the same password as above"
        }
    },
    // the errorPlacement has to take the table layout into account
    errorPlacement: function(error, element) {
        error.prependTo( element.parent().next() );
    },
    // specifying a submitHandler prevents the default submit, good for the demo
    submitHandler: function() {
        alert("submitted!");
    },
    // set this class to error-labels to indicate valid fields
    success: function(label) {
        // set &nbsp; as text for IE
        label.html("&nbsp;").addClass("jqueryChecked");
    }
});
});

1 Answer 1

4

You have a list of issues...

1) You must target the input fields by name and not id. Since your input name contains brackets, you must surround with quotes.

"change_password[password]": {
     required: true,
     minlength: 8
},

2) Your target fields all have style="display: none;", so they would never be seen, contain data, or be validated. And you also have another input right next to it without any name where the data is actually entered. This setup will never work and I have no idea why you've done this.

<input style="display: none;" name="change_password[password]" id="password" class="text" type="password">
<input class="text" type="text">

3) You have a rule called password on the second input field, yet its corresponding message is for the required rule. (Simply keep class="password" on the second input field if you want to use jquery.validate.password... See edit below.1

<input class="text password" name="change_password[new_password]" id="new_password" type="password">

Demo does not contain jquery.validate.password simply because there is no CDN for it. However, it's usage is straightforward as per this link.) See edit below.1

4) On the third input field, you have two rules and three messages... minlength message is superfluous since you only need to match second input field.

5) You don't need jQuery.format() around the minlength messages... they'll work fine by themselves.

6) You forgot to pass form into the submitHandler: function, like this: submitHandler: function(form) {

Working Demo: http://jsfiddle.net/kJxZB/

Working Demo #2 (see answer edit below): http://jsfiddle.net/4JEUx/

$(document).ready(function () {
    $("#change_account_password_form").validate({
        errorClass: 'jqueryError',
        rules: {
            "change_password[password]": {
                required: true,
                minlength: 8
            },
            "change_password[new_password]": {
                required: true,
                minlength: 8
            },
            "change_password[password_confirm]": {
                required: true,
                equalTo: "#new_password"
            }
        },
        messages: {
            "change_password[password]": {
                required: "Enter your current password",
                minlength: "Enter at least {0} characters"
            },
            "change_password[new_password]": {
                required: "Enter your new password",
                minlength: "Enter at least {0} characters"
            },
            "change_password[password_confirm]": {
                required: "Repeat your password",
                equalTo: "Enter the same password as above"
            }
        },
        errorPlacement: function (error, element) {
            error.prependTo(element.parent().next());
        },
        submitHandler: function (form) { // for demo
            alert("submitted!"); // for demo
            return false;  // for demo
        },
        success: function (label) {
            // set &nbsp; as text for IE
            label.html("&nbsp;").addClass("jqueryChecked");
        }
    });
});

Documentation: http://docs.jquery.com/Plugins/Validation


1EDIT:

This is the same Demo as above, except that the jquery.validate.password plugin's JavaScript and CSS code was manually added to the jsFiddle since it's not hosted on a CDN.

Demo #2: http://jsfiddle.net/4JEUx/

In order to have the password plugin ignore any input fields with type="password", you must use password: false as the rule on those two input fields...

         rules: {
            "change_password[password]": {
                required: true,
                minlength: 8,
                password: false  // <-- to ignore password plugin
            },
            "change_password[new_password]": {
                required: true,
                minlength: 8,
                password: true  // <-- to use password plugin
            },
            "change_password[password_confirm]": {
                required: true,
                equalTo: "#new_password",
                password: false  // <-- to ignore password plugin
            }
        },

You can then remove class="password" from the second input field as it's now superfluous.

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

5 Comments

Thanks for looking at this. The form is being generated by symfony 1.4 and tbh tiredness meant I just hadn't noticed the wierd display:none and empty textfield things. Never seen it do this before and can't find a reason for it either. I have just bypassed symfony forms to get this working. The fiddle doesn't use the jquery.validate.password plugin, is this a mistake? I'm still working on getting your fix working but am making progress thanks to yo8ur pointer about targetting names not ids.
@Tofuwarrior, I misread the first part of your OP. I've fixed your code and edited my answer accordingly. Please don't forget to accept my answer. Thanks.
Thanks for your help sparky, still trying to track down why those wierd additional fields and display:none happening but your stuff works great. If you have time can you explain to me the issues around not putting 'form' in the submit handler, I'm pretty novice at javascript and jquery.
@Tofuwarrior, submitHandler: function(form) {} is the default submitHandler function as per the plugin documentation. Leaving out form will only break it whenever you'd need to use form within the function.
thanks for clarification and help, got it all working thanks to your advice

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.