Password Strength

Angular JS Login validations Forked from : https://scotch.io/tutorials/password-strength-meter-in-angularjs

by Yashwanth M

HTML

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular.min.js"></script>
<script src="https://rawgit.com/dropbox/zxcvbn/master/dist/zxcvbn.js"></script>
<!DOCTYPE html>
<html class="no-js" ng-app="PasswordStrength">

    <body>
        <div class="main-container">
            <div class="form-container">

                <form action="" method="POST" name="joinTeamForm" role="form" ng-controller="FormController">
                    <legend class="form-label">Join the Team</legend>

                    <div class="form-group">
                        <label for="fullname">Fullname</label>

                        <div class="error form-hint" ng-show="joinTeamForm.fullname.$dirty && joinTeamForm.fullname.$error.required" ng-cloak>{{"This field is required."}}</div>

                        <input type="text" class="form-control" ng-class="(joinTeamForm.fullname.$dirty && joinTeamForm.fullname.$invalid) ? 'error' : ''" id="fullname" name="fullname" placeholder="Enter Fullname" ng-required="true" ng-model="fullname">
                    </div>

                    <div class="form-group">
                        <label for="email">Email</label>

                        <div class="error form-hint" ng-show="joinTeamForm.email.$dirty && joinTeamForm.email.$error.required" ng-cloak>{{"This field is required."}}</div>

                        <div class="error form-hint" ng-show="joinTeamForm.email.$dirty && joinTeamForm.email.$error.email" ng-cloak>{{"Email is invalid."}}</div>

                        <input type="email" class="form-control" ng-class="(joinTeamForm.email.$dirty && joinTeamForm.email.$invalid) ? 'error' : ''" id="email" name="email"...

CSS

[ng\:cloak],
[ng-cloak],
[data-ng-cloak],
[x-ng-cloak],
.ng-cloak,
.x-ng-cloak {
    display: none !important;
}

body {
    background: white;
    margin: 0;
    padding: 0;
}

.main-container {
    display: table;
    width: 400px;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
}

.form-container {
    position: relative;
    bottom: 0;
    display: table-cell;
    vertical-align: middle;
}

.form-container form > div {
    padding: 0 15px;
}

.form-container form > button {
    margin-left: 15px;
}

legend.form-label {
    font-size: 24pt;
    padding: 0 15px;
}

.form-control.error {
    border-color: red;
}

.form-hint {
    font-size: 7pt;
    line-height: 9pt;
    margin: -5px auto 5px;
    color: #999;
}

.form-hint.error {
    color: #C00;
    font-weight: bold;
    font-size: 8pt;
}

.password-count {
    float: right;
    position: relative;
    bottom: 24px;
    right: 10px;
}

.strength-meter {
    position: relative;
    height: 3px;
    background: #DDD;
    margin: 10px auto 20px;
    border-radius: 3px;
}

.strength-meter:before,
.strength-meter:after {
    content: '';
    height: inherit;
    background: transparent;
    display: block;
    border-color: #FFF;
    border-style: solid;
    border-width: 0 5px 0 5px;
    position: absolute;
    width: 80px;
    z-index: 10;
}

.strength-meter:before {
    left: 70px;
}

.strength-meter:after {
    right: 70px;
}

.strength-meter-fill {
    background: transparent;
    height: inherit;
    position: absolute;
    width: 0;
    border-radius: inherit;
    transition: width 0.5s ease-in-out, background 0.25s;
}

.strength-meter-fill[data-strength='0'] {
    background: darkred;
    width: 20%;
}

.strength-meter-fill[data-strength='1'] {
    background: orangered;
    width: 40%;
}

.strength-meter-fill[data-strength='2'] {
    background: orange;
    width: 60%;
}

.strength-meter-fill[data-strength='3'] {
    background: yellowgreen;
    width:...

JavaScript

(function() {

    angular.module('PasswordStrength', [])

    .controller('FormController', function($scope) {})

    .filter('passwordCount', [function() {
        return function(value, peak) {
            value = angular.isString(value) ? value : '';
            peak = isFinite(peak) ? peak : 7;

            return value && (value.length > peak ? peak + '+' : value.length);
        };
    }])

    .factory('zxcvbn', [function() {
        return {
            score: function() {
                var compute = zxcvbn.apply(null, arguments);
                return compute && compute.score;
            }
        };
    }])

    .directive('okPassword', ['zxcvbn', function(zxcvbn) {
        return {
            // restrict to only attribute and class
            restrict: 'AC',

            // use the NgModelController
            require: 'ngModel',

            // add the NgModelController as a dependency to your link function
            link: function($scope, $element, $attrs, ngModelCtrl) {
                $element.on('blur change keydown', function(evt) {
                    $scope.$evalAsync(function($scope) {
                        // update the $scope.password with the element's value
                        var pwd = $scope.password = $element.val();

                        // resolve password strength score using zxcvbn service
                        $scope.passwordStrength = pwd ? (pwd.length > 7 && zxcvbn.score(pwd) || 0) : null;

                        // define the validity criterion for okPassword constraint
                        ngModelCtrl.$setValidity('okPassword', $scope.passwordStrength >= 2);
                    });
                });
            }
        };
    }]);

})();