Password validation as you type

Password validates on each criteria as you type. Once all items are valid, you can submit.

HTML

<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css">
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script>
<div id="page">
    <div class="row">
      <div class="col-sm-6 col-sm-offset-3 col-lg-4 col-lg-offset-4">
          <div class="pod">
            <h3>Create a password</h3>
            <form class="validate-password" method="post" action="#">
              <fieldset class="fieldset-password">
                <div id="alert-invalid-password" class="alert alert-danger hide">Please enter a valid password</div>
                <p>All checkmarks must turn green in order to proceed</p>
                <div id="password-info">
                  <ul>
                    <li id="length" class="invalid clearfix">
                      <span class="icon-container">
                       
                      </span>
                      At least 8 characters
                    </li>
                    <li id="capital" class="invalid clearfix">
                      <span class="icon-container">
                        <i class="fa fa-check" aria-hidden="true"></i>
                      </span>
                      At least 1 uppercase letter
                    </li>
                    <li id="lowercase" class="invalid clearfix">
                      <span class="icon-container">
                        <i class="fa fa-check" aria-hidden="true"></i>
                      </span>
                      At least 1 lowercase letter
                    </li>
                    <li id="number-special" class="invalid clearfix">
                      <span class="icon-container">
                        <i class="fa fa-check" aria-hidden="true"></i>
                      </span>
                    ...

SCSS

@import url(http://fonts.googleapis.com/css?family=Lobster);

body {
    margin: 0;
    background: #ececec;
}

#page {
  margin: 0 15px;
  padding-top: 30px;
}

label {
    font-size: 0.875em;
}

.btn-primary {
    background-color: #fa1954;
    border: 0;
    margin: 10px 0;
    &:hover {
        background-color: darken(#fa1954, 10%);   
    }
}

// Error Messages - front end validation
.form-group.error {
    input {
        border-color: #ee4141;
        box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(238,65,65,.4)
    }
    label.error {
        margin-top: 5px;
        color: #ee4141;   
    }
}

// Pod
// --------------------------------------------------
.pod {
  padding: 25px;
  background: #fff;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  h3 {
      text-align: center;
      margin: 10px 0 30px;
      font-family: 'Lobster', cursive;
  }
}

// Password Creation Info Box
// --------------------------------------------------
#password-info {
	margin: 20px 0;
	overflow: hidden;
	text-shadow: 0 1px 0 #fff;
	ul {
		list-style: none;
		margin: 0;
        padding: 0;
		li {
			padding: 10px 10px 10px 50px;
            margin-bottom: 1px;
            background: #f4f4f4;
			font-size: 12px;
			transition: 250ms ease;
            position: relative;
			.icon-container {
				display: block;
				width: 40px;
				background: lighten(#428bca, 20%);
				position: absolute;
                top: 0;
                bottom: 0;
                left: 0;
                text-align: center;
				.fa {
					color: white;
                    padding-top: 10px;
                    position: relative;
                    top: 2px;
				}
			}
			.tip {
				color: #5ca6d5;
				text-decoration: underline;
			}
			&.valid {
				.icon-container {
					background-color: #18c36b;
				}
				color: darken(#18c36b, 10%);
			}
			span.invalid {
				color: #ff642e;
			}
		}
	}
}

JavaScript

// Tooltips
// -----------------------------------------

// Only initialise tooltips if devices is non touch
if (!('ontouchstart' in window)) {
    $('.tip').tooltip();
}

// Password Validation
// -----------------------------------------

$(function passwordValidation() {

    var pwdInput = $('#input-password');
    var pwdInputText = $('#input-password-text'); // This is the input type="text" version for showing password
    var pwdValid = false;

    function validatePwdStrength() {

        var pwdValue = $(this).val(); // This works because when it's called it's called from the pwdInput, see end

        // Validate the length
        if (pwdValue.length > 7) {
            $('#length').removeClass('invalid').addClass('valid');
            pwdValid = true;
        } else {
            $('#length').removeClass('valid').addClass('invalid');
        }

        // Validate capital letter
        if (pwdValue.match(/[A-Z]/)) {
            $('#capital').removeClass('invalid').addClass('valid');
            pwdValid = pwdValid && true;
        } else {
            $('#capital').removeClass('valid').addClass('invalid');
            pwdValid = false;
        }

        // Validate lowercase letter
        if (pwdValue.match(/[a-z]/)) {
            $('#lowercase').removeClass('invalid').addClass('valid');
            pwdValid = pwdValid && true;
        } else {
            $('#lowercase').removeClass('valid').addClass('invalid');
            pwdValid = false;
        }

        // Validate number or special character
        if (pwdValue.match(/[\d`~!@#$%\^&*()+=|;:'",.<>\/?\\\-]/)) {
            $('#number-special').removeClass('invalid').addClass('valid');
            pwdValid = pwdValid && true;
        } else {
            $('#number-special').removeClass('valid').addClass('invalid');
            pwdValid = false;
        }
    }

    function validatePwdValid(form, event) {
        if (pwdValid === true) {
            form.submit();
        } else {
          ...