<!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='{showSuccess: true}'>
<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='{showSuccess: true}'>
<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, showErrorsConfig) {
var getShowSuccess, linkFn;
getShowSuccess = function (options) {
var showSuccess;
showSuccess = showErrorsConfig.showSuccess;
if (options && options.showSuccess != null) {
showSuccess = options.showSuccess;
}
return showSuccess;
};
linkFn = function (scope, el, attrs, formCtrl) {
var blurred, inputEl, inputName, inputNgEl, options, showSuccess, toggleClasses;
blurred = false;
options = scope.$eval(attrs.showErrors);
showSuccess = getShowSuccess(options);
inputEl = el[0].querySelector('[name]');
inputNgEl = angular.element(inputEl);
inputName = inputNgEl.attr('name');
if (!inputName) {
throw 'show-errors element has no child input elements with a \'name\' attribute';
}
inputNgEl.bind('blur', function () {
blurred = true;
return toggleClasses(formCtrl[inputName].$invalid);
});
scope.$watch(function () {
return formCtrl[inputName] && formCtrl[inputName].$invalid;
}, function (invalid) {
if (!blurred) {
return;
}
return toggleClasses(invalid);
});
scope.$on('show-errors-check-validity', function () {
return toggleClasses(formCtrl[inputName].$invalid);
});
scope.$on('show-errors-reset', function () {
return $timeout(function () {
el.removeClass('has-error');
el.removeClass('has-success');
return blurred = false;
}, 0, false);
});
return toggleClasses = function (invalid) {
el.toggleClass('has-error', invalid);
if (showSuccess) {
return el.toggleClass('has-success', !invalid);
}
};
};
return {
restrict: 'A',
require: '^form',
compile: function (elem, attrs) {
if (!elem.hasClass('form-group')) {
throw 'show-errors element does not have the \'form-group\' class';
}
return linkFn;
}
};
}
);
module.provider('showErrorsConfig', function () {
var _showSuccess;
_showSuccess = false;
this.showSuccess = function (showSuccess) {
return _showSuccess = showSuccess;
};
this.$get = function () {
return { showSuccess: _showSuccess };
};
});
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;
}