AngularJS - Simple Directive Use

by apohl

HTML

<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css">
<script src="http://code.angularjs.org/1.0.0/angular-1.0.0.js"></script>
<script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
<div ng-app="app" ng-controller="appCtrl">
    <div class="ui-content">
        <div errors="bizDetails"></div>
        <form id="bizDetails" name="bizDetails" novalidate>
            <div data-role="fieldcontain">
                <label>Name<span class="red">*</span></label>
                <!-- doesn't work -->
                <textarea error-message="You must enter a name" name="name" ng-model="profile.name" required></textarea>
            </div>
            <div data-role="fieldcontain">
                <label>Phone</label>
                <!-- works -->
                <input type="text" name="npi" ng-model="profile.phone"/>
                <!-- doesn't work -->
                <!--<input error-message="Phone must be a number" type="text" name="npi" ng-model="profile.phone"/>-->
            </div>
        </form>
    </div>
</div>

CSS

.red{color:red;}

.errorMessageBox {
    margin-bottom: 15px;
    padding: 4px 7px;
    font-size: 14px;
    color: #bb0000;
    border: 2px solid #ff9999;
    border-radius: 5px;
    background: #ffdddd;
    .errorMessageHeader, li {
        padding: 4px 0;
        i {
            margin-right: 8px;
        }
    }
}

JavaScript

var module = angular
        .module('app', [])
        .directive("errors", function () {
        //Display custom error messages
        return {
            replace: true,
            scope: {
                //form id to display errors for
                errors: "@"
            },
            template: '<div class="errorMessageBox" ng-show="hasError">'+
                        '<div class="errorMessageHeader">' +
                            '<i class="icon-warning-sign"></i>' +
                            'Please fix these errors' +
                        '</div>' +
                        '<ul>' +
                            '<li ng-repeat="error in errors">{{error.errorMessage}}</li>' +
                        '</ul>' +
                    '</div>',
            link: function (scope, element, iAttrs) {
                //scope has two properties
                //hasError: if any error on the form controller is dirty and invalid
                //errors: a list of the custom error messages for any dirty and invalid form element

                var formId = iAttrs.errors;
                var formScope = angular.element("#" + formId).scope();

                //watch the form's FormController
                //it is on the form's scope with the same property as the formId
                formScope.$watch(formId + ".$error", function (errors) {
                    scope.hasError = false;
                    scope.errors = [];

                    _.each(errors, function (errorType) {
                        _.each(errorType, function (error) {
                            if (error.$dirty && error.$invalid) {
                                scope.errors.push({errorMessage: error.errorMessage});
                                scope.hasError = true;
                            }
                        });
                    });
                }, true);
            }
        };
    })
.directive("errorMessage", function () {
        //Ability to add a custom...