<!DOCTYPE html>
<html>
<head>
<link data-require="bootstrap-css@3.0.1" data-semver="3.0.1" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.1/css/bootstrap.min.css" />
<script src="http://code.angularjs.org/1.2.5/angular.js" data-semver="1.2.5" data-require="angular.js@1.2.5"></script>
<script data-require="jquery@*" data-semver="2.0.3" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script data-require="bootstrap@3.0.1" data-semver="3.0.1" src="//netdna.bootstrapcdn.com/bootstrap/3.0.1/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-app="app" ng-controller="NewUserController">
<h1>Add New User</h1>
<form name="userForm" novalidate>
<div class="form-group" show-errors>
<label class="control-label">Name</label>
<input type="text" class="form-control" name="name" ng-model="user.name" required placeholder="Name" />
<p class="help-block" ng-if="userForm.name.$error.required">The user's name is required</p>
</div>
<div class="form-group" show-errors>
<label class="control-label">Email</label>
<input type="email" class="form-control" name="email" ng-model="user.email" required placeholder="Email" />
<p class="help-block" ng-if="userForm.email.$error.required">The user's email is required</p>
<p class="help-block" ng-if="userForm.email.$error.email">The email address is invalid</p>
</div>
<button class="btn btn-primary" ng-click="save()">Add User</button>
<button class="btn btn-link" ng-click="reset()">Reset</button>
</form>
</body>
</html>
module = angular.module('app', []);
module.directive('showErrors', function($timeout) {
return {
restrict: 'A',
require: '^form',
link: function (scope, el, attrs, formCtrl) {
// find the text box element, which has the 'name' attribute
var inputEl = el[0].querySelector("[name]");
// convert the native text box element to an angular element
var inputNgEl = angular.element(inputEl);
// get the name on the text box
var inputName = inputNgEl.attr('name');
// only apply the has-error class after the user leaves the text box
var blurred = false;
inputNgEl.bind('blur', function() {
blurred = true;
el.toggleClass('has-error', formCtrl[inputName].$invalid);
});
scope.$watch(function() {
return formCtrl[inputName].$invalid
}, function(invalid) {
// we only want to toggle the has-error class after the blur
// event or if the control becomes valid
if (!blurred && invalid) { return }
el.toggleClass('has-error', invalid);
});
scope.$on('show-errors-check-validity', function() {
el.toggleClass('has-error', formCtrl[inputName].$invalid);
});
scope.$on('show-errors-reset', function() {
$timeout(function() {
el.removeClass('has-error');
}, 0, false);
});
}
}
});
module.controller('NewUserController', function($scope) {
$scope.save = function() {
$scope.$broadcast('show-errors-check-validity');
if ($scope.userForm.$valid) {
alert('User saved');
$scope.reset();
}
};
$scope.reset = function() {
$scope.$broadcast('show-errors-reset');
$scope.user = { name: '', email: '' };
}
});
/* Styles go here */
body {
padding: 10px;
}
.form-group .help-block {
display: none;
}
.form-group.has-error .help-block {
display: block;
}