<!DOCTYPE html>
<html ng-app="emailAddressesExample">
<head>
<meta charset="utf-8" />
<title>AngularJS test</title>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js" data-semver="1.2.16" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
<script data-require="lodash.js@*" data-semver="2.4.1" src="http://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<div>
<label>Email addresses</label>
<email-address-list data-ng-model="emailAddresses" required></email-address-list>
</div>
<p>The email address list contents: {{emailAddresses}}</p>
</body>
</html>
(function(angular, _) {
angular.module('emailAddressesExample', [])
.controller('MainCtrl', function($scope) {
$scope.emailAddresses = [];
})
.directive('emailAddressList', function() {
return {
templateUrl: 'emailaddresslist.html',
restrict: 'E',
require: 'ngModel',
scope: {}, // This signifies an isolate scope
link: function(scope, element, attributes, ngModelCtrl) {
ngModelCtrl.$render = function() {
if (ngModelCtrl.$viewValue.length === 0) {
// If an array is provided without items, a single item is
// added by default
scope.emailAddresses = [undefined];
} else {
scope.emailAddresses = ngModelCtrl.$viewValue;
}
};
scope.$watch('emailAddresses', function() {
ngModelCtrl.$setViewValue(scope.emailAddresses);
}, true);
ngModelCtrl.$formatters.push(function(modelValue) {
return _.compact(modelValue);
});
ngModelCtrl.$parsers.push(function(viewValue) {
var compactedValue = _.compact(viewValue);
// If 'required' is passed in via the element, at least one
// valid email address must be entered for the element to be valid
if (attributes.required) {
if (compactedValue.length) {
ngModelCtrl.$setValidity('emailAddresses', true);
} else {
ngModelCtrl.$setValidity('emailAddresses', false);
}
}
return compactedValue;
});
},
controller: function($scope) {
$scope.add = function() {
$scope.emailAddresses.push(undefined);
};
$scope.remove = function(index) {
$scope.emailAddresses.splice(index, 1);
};
}
};
});
})(angular, _);
/* Styles go here */
<div>
<input data-ng-model="emailAddresses[0]" type="email">
</div>
<div data-ng-repeat="emailAddress in emailAddresses track by $index" data-ng-if="!$first">
<input data-ng-model="emailAddresses[$index]" type="email">
<span>
<button type="button" data-ng-click="remove($index)">x</button>
</span>
</div>
<p><button type="button" data-ng-click="add()">Add another email address</button></p>