Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

validate: first prototype for password validation including password …

…strength meter

git-svn-id: http://jqueryjs.googlecode.com/svn/trunk/plugins/validate.password@5832 c715fcbe-d12f-0410-84c4-316a508785bb
  • Loading branch information...
commit 7d428f10d1c12961d403c3d0e0b7cb9b34b65761 0 parents
joern.zaefferer authored
BIN  demo/bg.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  demo/checked.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
166 demo/index.html
@@ -0,0 +1,166 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<title>jQuery Validation Plugin Password Extension demo</title>
+
+<link rel="stylesheet" type="text/css" media="screen" href="milk.css" />
+
+<script type="text/javascript" src="../../validate/lib/jquery.js"></script>
+<script type="text/javascript" src="../../validate/jquery.validate.js"></script>
+<script type="text/javascript" src="../jquery.validate.password.js"></script>
+
+<style type="text/css">
+.password-meter {
+ position:relative;
+ top: 20px;
+ background: #e0e0e0;
+ width: 180px;
+}
+.password-meter-bar {
+ height: 4px;
+}
+.password-meter-weak {
+ background: red;
+ width: 20px;
+}
+.password-meter-good {
+ background: blue;
+ width: 140px;
+}
+.password-meter-strong {
+ background: green;
+ width: 180px;
+}
+
+</style>
+
+<script id="demo" type="text/javascript">
+$(document).ready(function() {
+ // validate signup form on keyup and submit
+ var validator = $("#signupform").validate({
+ rules: {
+ username: {
+ required: true,
+ minlength: 2
+ },
+ password: {
+ required: true,
+ password: true
+ },
+ password_confirm: {
+ required: true,
+ equalTo: "#password"
+ }
+ },
+ messages: {
+ username: {
+ required: "Enter a username",
+ minlength: jQuery.format("Enter at least {0} characters")
+ },
+ password: {
+ required: "Provide a password",
+ rangelength: 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.appendTo( 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("checked");
+ }
+ });
+
+ // propose username by combining first- and lastname
+ $("#username").focus(function() {
+ var firstname = $("#firstname").val();
+ var lastname = $("#lastname").val();
+ if(firstname && lastname && !this.value) {
+ this.value = firstname + "." + lastname;
+ }
+ });
+
+});
+</script>
+
+</head>
+<body>
+
+<h1 id="banner"><a href="http://bassistance.de/jquery-plugins/jquery-plugin-validation/">jQuery Validation Plugin Password Extension </a> Demo</h1>
+<div id="main">
+
+<div id="content">
+
+<div id="header">
+ <div id="headerlogo"><img src="milk.png" alt="Remember The Milk" /></div>
+</div>
+<div style="clear: both;"><div></div></div>
+
+
+<div class="content">
+ <div id="signupbox">
+ <div id="signuptab">
+ <ul>
+ <li id="signupcurrent"><a href=" ">Signup</a></li>
+ </ul>
+ </div>
+ <div id="signupwrap">
+ <form id="signupform" autocomplete="off" method="get" action="">
+ <table>
+ <tr>
+ <td class="label"><label id="lusername" for="username">Username</label></td>
+ <td class="field"><input id="username" name="username" type="text" value="" maxlength="50" /></td>
+ <td class="status"></td>
+ </tr>
+ <tr>
+ <td class="label"><label id="lpassword" for="password">Password</label></td>
+ <td class="field"><input id="password" name="password" type="password" maxlength="50" value="" /></td>
+ <td class="status">
+ <div class="password-meter">
+ <div class="password-meter-bar"></div>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td class="label"><label id="lpassword_confirm" for="password_confirm">Confirm Password</label></td>
+ <td class="field"><input id="password_confirm" name="password_confirm" type="password" maxlength="50" value="" /></td>
+ <td class="status"></td>
+ </tr>
+ <tr>
+ <td class="label"><label id="lsignupsubmit" for="signupsubmit">Signup</label></td>
+ <td class="field" colspan="2">
+ <input id="signupsubmit" name="signup" type="submit" value="Signup" />
+ </td>
+ </tr>
+
+ </table>
+ </form>
+ </div>
+ </div>
+</div>
+
+</div>
+
+</div>
+
+<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+_uacct = "UA-2623402-1";
+urchinTracker();
+</script>
+
+</body>
+</html>
BIN  demo/left_white.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
236 demo/milk.css
@@ -0,0 +1,236 @@
+/* GENERAL ELEMENTS */
+
+* { margin: 0; padding: 0; }
+
+body, input, select, textarea { font-family: verdana, arial, helvetica, sans-serif; font-size: 11px; }
+body { color: #333; background-color: #fff; text-align: center; }
+
+a:link { color:#0060BF; text-decoration: underline; }
+a:visited { color:#0060BF; text-decoration: underline; }
+a:active { color:#0060BF; text-decoration: underline; }
+a:hover { color:#000000; text-decoration: underline; }
+
+h1, h2, h3, h4, h5, h6 { font-family: "Lucida Grande", "Lucida Sans Unicode", geneva, verdana, arial, helvetica, sans-serif; font-weight: bold; color: #666; }
+h1 { font-size: 1.8em; margin: 0em 0em 0.6em 0em; color: #EC5800; }
+h2 { font-size: 1.5em; margin: 1.2em 0em 0.4em 0em; }
+h3 { font-size: 1.4em; margin: 1.2em 0em 0.4em 0em; color: #EC5800; }
+h4 { font-size: 1.2em; margin: 1.2em 0em 0.4em 0em; }
+h5 { font-size: 1.0em; margin: 1.2em 0em 0.4em 0em; }
+h6 { font-size: 0.8em; margin: 1.2em 0em 0.4em 0em; }
+
+img { border: 0px; }
+
+p { font-size: 1.0em; line-height: 1.3em; margin: 1.2em 0em 1.2em 0em; }
+li > p { margin-top: 0.2em; }
+pre { font-family: monospace; font-size: 1.0em; }
+strong, b { font-weight: bold; }
+
+/* PAGE ELEMENTS */
+
+/* Content */
+
+#content { margin: 0em auto; width: 765px; padding: 10px 0 10px 0; text-align: left; /* Win IE5 */ }
+.content { margin-left: 4.5em; margin-right: 4.5em; }
+.content ol, .content ul, .content li { font-size: 1.0em; line-height: 1.3em; margin: 0.2em 0 0.1em 1.5em; }
+.content ol.terms li { margin-bottom: 1em; }
+
+/* Header */
+
+#header { padding-bottom: 10em; }
+#headerlogo { float: left; }
+#headerlogo img { width: 188px; height: 83px; }
+#headernav { float: right; }
+
+label { font-weight: bold; }
+#reminders label { font-weight: normal; }
+
+table.tabbedtable { padding-left: 3em; }
+table.tabbedtable td { padding-bottom: 5px; }
+table.tabbedtable label { text-align: right; padding-right: 9px; }
+.hiddenlabel { visibility: hidden; }
+.largelink { border: 1px solid #cacaca; padding: 10px; background-color: #E8EEF7; font-size: 1.2em; font-weight: bold; }
+.largelinkwrap { padding-top: 10px; padding-bottom: 10px; }
+
+
+
+#signuptab {
+ float:left;
+ width:100%;
+ background:#fff url("bg.gif") repeat-x bottom;
+ font-size: 1.0em;
+ line-height: normal;
+}
+#signuptab ul {
+ margin:0;
+ padding: 0px 10px 0px 10px;
+ list-style:none;
+}
+#signuptab li {
+ float:left;
+ background:url("left_white.png") no-repeat left top;
+ margin:0;
+ padding:0 3px 0 9px;
+ border-bottom:1px solid #CACACA;
+}
+#signuptab a {
+ float:left;
+ display:block;
+ width:.1em;
+ background:url("right_white.png") no-repeat right top;
+ padding:2px 15px 0px 6px;
+ text-decoration:none;
+ font-weight:bold;
+ color:#fff;
+ white-space: nowrap;
+}
+#signuptab > ul a {width:auto;}
+/* Commented Backslash Hack hides rule from IE5-Mac \*/
+#signuptab a {float:none;}
+/* End IE5-Mac hack */
+#signuptab a:hover {
+ color:#333;
+}
+#signuptab #signupcurrent {
+ background-position:0 -150px;
+ border-width:0;
+}
+#signuptab #signupcurrent a {
+ background-position:100% -150px;
+ padding-bottom:1px;
+ color:#000;
+}
+#signuptab li:hover, #signuptab li:hover a {
+ background-position:0% -150px;
+ color:#000;
+}
+#signuptab li:hover a {
+ background-position:100% -150px;
+}
+
+/* Signup box */
+
+#signupbox {
+ width: 100%;
+ text-align: center;
+ margin: 0em auto;
+}
+
+#signupwrap {
+ border: 1px solid #CACACA;
+ border-top: 0;
+ text-align: left;
+ padding: 35px 10px 20px 30px;
+ clear: both;
+}
+
+/* Unsupported browsers */
+
+.orange_rbcontent { padding: 0.4em; }
+.orange_rbroundbox { width: 100%; }
+
+#unsupported {
+ font-weight: bold;
+ text-align: left;
+}
+
+/*#content {
+ padding-top: 15px;
+}*/
+
+/* Signup form */
+
+#signupform table {
+ border-spacing: 0px;
+ border-collapse: collapse;
+ empty-cells: show;
+}
+
+#signupform .label {
+ padding-top: 2px;
+ padding-right: 8px;
+ vertical-align: top;
+ text-align: right;
+ width: 125px;
+ white-space: nowrap;
+}
+
+#signupform .field {
+ padding-bottom: 10px;
+ white-space: nowrap;
+}
+
+#signupform .status {
+ padding-top: 2px;
+ padding-left: 8px;
+ vertical-align: top;
+ width: 246px;
+ white-space: nowrap;
+}
+
+#signupform .textfield {
+ width: 150px;
+}
+
+#signupform label.error {
+ background:url("unchecked.gif") no-repeat 0px 0px;
+ padding-left: 16px;
+ padding-bottom: 2px;
+ font-weight: bold;
+ color: #EA5200;
+}
+
+#signupform label.checked {
+ background:url("checked.gif") no-repeat 0px 0px;
+}
+
+#signupform .success_msg {
+ font-weight: bold;
+ color: #0060BF;
+ margin-left: 19px;
+}
+
+#signupform #dateformatStatus, #signupform #termsStatus {
+ margin-left: 6px;
+}
+
+#signupform #dateformat_eu {
+ vertical-align: middle;
+}
+
+#signupform #ldateformat_eu {
+ font-weight: normal;
+ vertical-align: middle;
+}
+
+#signupform #dateformat_am {
+ vertical-align: middle;
+}
+
+#signupform #ldateformat_am {
+ font-weight: normal;
+ vertical-align: middle;
+}
+
+#signupform #termswrap {
+ float: left;
+}
+
+#signupform #terms {
+ vertical-align: middle;
+ float: left;
+ display: block;
+ margin-right: 5px;
+}
+
+#signupform #lterms {
+ font-weight: normal;
+ vertical-align: middle;
+ float: left;
+ display: block;
+ width: 350px;
+ white-space: normal;
+}
+
+#signupform #lsignupsubmit {
+ visibility: hidden;
+}
BIN  demo/milk.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  demo/right_white.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  demo/unchecked.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
69 jquery.validate.password.js
@@ -0,0 +1,69 @@
+(function($) {
+
+ var LOWER = /[a-z]/,
+ UPPER = /[A-Z]/,
+ DIGIT = /[0-9]/,
+ DIGITS = /[0-9].*[0-9]/,
+ SPECIAL = /[^a-zA-Z0-9]/,
+ SAME = /^(.)\1+$/;
+
+ function rating(rate, message) {
+ return {
+ rate: rate,
+ messageKey: message
+ };
+ }
+
+ function uncapitalize(str) {
+ return str.substring(0, 1).toLowerCase() + str.substring(1);
+ }
+
+ $.validator.passwordRating = function(password, username) {
+ if (!password || password.length < 8)
+ return rating(0, "too-short");
+ if (username && password.toLowerCase().match(username.toLowerCase()))
+ return rating(0, "similar-to-username");
+ if (SAME.test(password))
+ return rating(1, "very-weak");
+
+ var lower = LOWER.test(password),
+ upper = UPPER.test(uncapitalize(password)),
+ digit = DIGIT.test(password),
+ digits = DIGITS.test(password),
+ special = SPECIAL.test(password);
+
+ if (lower && upper && digit || lower && digits || upper && digits || special)
+ return rating(4, "strong");
+ if (lower && upper || lower && digit || upper && digit)
+ return rating(3, "good");
+ return rating(2, "weak");
+ }
+
+ $.validator.passwordRating.messages = {
+ "too-short": "Too short",
+ "very-weak": "Weak",
+ "weak": "Fair",
+ "good": "Good",
+ "strong": "Strong"
+ }
+
+ $.validator.addMethod("password", function(value, element, usernameField) {
+ // use untrimmed value
+ var password = element.value,
+ // get username for comparison, if specified
+ username = $(typeof usernameField != "boolean" ? usernameField : []);
+
+ var rating = $.validator.passwordRating(password, username.val());
+ // update message for this field
+ $.extend(this.settings.messages[element.name] || (this.settings.messages[element.name] = {}), {
+ password: $.validator.passwordRating.messages[rating.messageKey]
+ })
+ $(".password-meter-bar").removeClass().addClass("password-meter-bar").addClass("password-meter-" + rating.messageKey);
+ // display process bar instead of error message
+
+ return rating.rate > 2;
+ }, "");
+ // manually add class rule, to make username param optional
+ $.validator.classRuleSettings.password = { password: true };
+
+})(jQuery);
Please sign in to comment.
Something went wrong with that request. Please try again.