<!DOCTYPE html>
<html lang="en" ng-app="app">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.js"></script>
<style>
.formInput.ng-valid {border: 1px solid green;}
.formInput.ng-invalid {background-color: #FF6666;}
.formInput.ng-pristine {border: 1px solid blue; background-color: transparent;}
</style>
</head>
<body ng-controller="AppCtrl">
<script>
var app = angular.module('app', []);
app.controller('AppCtrl', function($scope) {
$scope.person = {};
});
</script>
<script src="inputEmail.js"></script>
<script src="InputEmailCtrl.js"></script>
<script src="inputName.js"></script>
<script src="InputNameCtrl.js"></script>
<script src="inputAge.js"></script>
<script src="InputAgeCtrl.js"></script>
<form name="myForm" class="form-horizontal" novalidate>
<div class="form-group">
<input-name ng-model='person.name' required></input-name>
</div>
<div class="form-group">
<input-email ng-model='person.email' required></input-email>
</div>
<div class="form-group">
<input-age ng-model='person.age' required></input-age>
</div>
<!-- Not using a directive -->
<div class="form-group">
<label class="col-sm-2 control-label">Country</label>
<div class="col-sm-4" ng-class="{'has-error': myForm.country.$invalid}">
<input type="text" name="country" ng-model="person.country" class="formInput form-control" required>
<span ng-show="myForm.country.$error.required && myForm.country.$dirty" class="help-block">Can't be blank</span>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-4">
<button class="btn btn-primary" ng-disabled="myForm.$invalid">
<span class="glyphicon glyphicon-cloud-upload"></span> Save
</button>
</div>
</div>
</form>
Person: <pre>{{person | json}}</pre>
Form $error: <pre>{{myForm.$error | json}}</pre>
<p>Is the form valid?: {{myForm.$valid}}</p>
<p>Is name valid?: {{myForm.name.$valid}}</p>
<p>Is email valid?: {{myForm.email.$valid}}</p>
<p>Is age valid?: {{myForm.age.$valid}}</p>
<p>Is country valid?: {{myForm.country.$valid}}</p>
</body>
</html>
'use strict';
app.directive('inputEmail', function() {
return {
restrict: 'E',
templateUrl: 'input-email.html',
replace: false,
controller: 'InputEmailCtrl',
require: ['^form', 'ngModel'],
// See Isolating the Scope of a Directive http://docs.angularjs.org/guide/directive#isolating-the-scope-of-a-directive
scope: {},
link: function(scope, element, attrs, ctrls) {
scope.form = ctrls[0];
var ngModel = ctrls[1];
if (attrs.required !== undefined) {
// If attribute required exists
// ng-required takes a boolean
scope.required = true;
}
scope.$watch('email', function() {
ngModel.$setViewValue(scope.email);
});
}
};
});
<label class="col-sm-2 control-label">Email</label>
<div class="col-sm-4" ng-class="{'has-error': form.email.$invalid}">
<input type="email" name="email" ng-model="email" class="form-control formInput" ng-required="required">
<span ng-show="form.email.$error.required && form.email.$dirty" class="help-block">Can't be blank</span>
<span ng-show="form.email.$error.email" class="help-block">Not a valid email</span>
</div>
'use strict';
app.controller('InputEmailCtrl', ['$scope', function($scope) {
}]);
<label class="col-sm-2 control-label">Name</label>
<div class="col-sm-4" ng-class="{'has-error': form.name.$invalid}">
<input type="text" class="formInput form-control" name="name" ng-pattern="/^[a-zA-Z]+$/" ng-model="name" ng-required="required">
<span ng-show="form.name.$error.required && form.name.$dirty" class="help-block">Can't be blank</span>
<span ng-show="form.name.$invalid && form.name.$dirty" class="help-block">Only letters are allowed</span>
</div>
'use strict';
app.directive('inputName', function() {
return {
restrict: 'E',
templateUrl: 'input-name.html',
replace: false,
controller: 'InputNameCtrl',
require: ['^form', 'ngModel'],
// See Isolating the Scope of a Directive http://docs.angularjs.org/guide/directive#isolating-the-scope-of-a-directive
scope: {},
link: function(scope, element, attrs, ctrls) {
scope.form = ctrls[0];
var ngModel = ctrls[1];
if (attrs.required !== undefined) {
// If attribute required exists
// ng-required takes a boolean
scope.required = true;
}
scope.$watch('name', function() {
ngModel.$setViewValue(scope.name);
});
}
};
});
'use strict';
app.controller('InputNameCtrl', ['$scope', function($scope) {
}]);
<label class="col-sm-2 control-label">Age</label>
<div class="col-sm-4" ng-class="{'has-error': form.age.$invalid}">
<input type="text" name="age"
min="0" max="150"
ng-pattern="/^(0|[1-9][0-9]*)$/"
ng-model="age"
class="formInput form-control" ng-required="required">
<span ng-show="form.age.$error.required && form.age.$dirty" class="help-block">Can't be blank</span>
<span ng-show="form.age.$error.min && form.age.$dirty" class="help-block">Should be ≥ 0</span>
<span ng-show="form.age.$error.max && form.age.$dirty" class="help-block">Should be ≤ 150</span>
<span ng-show="form.age.$error.pattern" class="help-block">Not a valid number !</span>
</div>
'use strict';
app.directive('inputAge', function() {
return {
restrict: 'E',
templateUrl: 'input-age.html',
replace: false,
controller: 'InputAgeCtrl',
require: ['^form', 'ngModel'],
// See Isolating the Scope of a Directive http://docs.angularjs.org/guide/directive#isolating-the-scope-of-a-directive
scope: {},
link: function(scope, element, attrs, ctrls) {
scope.form = ctrls[0];
var ngModel = ctrls[1];
if (attrs.required !== undefined) {
// If attribute required exists
// ng-required takes a boolean
scope.required = true;
}
scope.$watch('age', function() {
ngModel.$setViewValue(scope.age);
});
}
};
});
'use strict';
app.controller('InputAgeCtrl', ['$scope', function($scope) {
}]);