Edit in JSFiddle

var app = angular.module('app', []);

app.controller('appCtrl', function ($scope) {

});


app.directive('validate', function () {
    return {
        restrict: 'A',
        require: 'ngModel', // require:  '^form',
        link: function (scope, element, attrs, ctrl) {
            var elementErrors = element.next();
            var errorsList = '',
                errorItem;
            var errorMessages = {
                //defaultMsg: 'Please add error message for {0}',
                required: 'This field is required',
                number: 'Please enter a valid number',
                min: 'Please enter the minimum number of {0}',
                max: 'Please enter the maximum number of {0}',
                url: 'Please enter a valid URL in the format of http(s)://wwww.google.com',
                email: 'Please enter a valid email address',
                minlength: 'Please enter at least {0} characters',
                maxlength: 'You have entered more than the maximum {0} characters',
                date: 'Please enter a valid date',
                time: 'Please enter a valid time',
                pattern: 'Please ensure the entered information adheres to this pattern {0}',
                minmodel: 'Should be at least as big as {0}',
                positiveInteger: 'Please enter positive integer number'
            };
            element.bind('keyup', function () {
                console.log('======================');
                console.log(scope);
                console.log(element);
                console.log(attrs);
                console.log(ctrl);
                console.log('------------------------');
                if (ctrl.$dirty && ctrl.$invalid) {
                    errorsList = '';
                    angular.forEach(ctrl.$error, function (value, key) {
                        if (value && errorMessages[key]) { // show only truthy errors
                            errorItem = errorMessages[key];
                            errorItem = errorItem.replace(/\{0\}/g, attrs[key]);
                            errorsList = errorsList + '<li>' + key + ' == ' + errorItem + '</li>';
                        }
                    });
                    elementErrors.html('<ul>' + errorsList + '</ul>')
                    elementErrors.show();
                } else {
                    elementErrors.hide();
                    elementErrors.html('');
                }
            })
        }
    };
});


app.directive('positiveInteger', function () {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, element, attrs, ctrl) {
            ctrl.$parsers.unshift(function (viewValue) {
                var INTEGER_REGEXP = /^\d+$/;
                if (INTEGER_REGEXP.test(viewValue)) { // it is valid
                    ctrl.$setValidity('positiveInteger', true);
                    return viewValue;
                } else { // it is invalid, return undefined (no model update)
                    ctrl.$setValidity('positiveInteger', false);
                    return undefined;
                }
            });
        }
    };
});


app.directive('positiveFloat', function () {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, element, attrs, ctrl) {
            ctrl.$parsers.unshift(function (viewValue) {
                var FLOAT_REGEXP = /^(?:[1-9]\d*|0)?(?:\.\d+)?$/;
                if (FLOAT_REGEXP.test(viewValue)) { // it is valid
                    ctrl.$setValidity('positiveInteger', true);
                    return viewValue;
                } else { // it is invalid, return undefined (no model update)
                    ctrl.$setValidity('positiveInteger', false);
                    return undefined;
                }
            });
        }
    };
});

app.directive('minModel', function () {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, element, attrs, ctrl) {
            ctrl.$parsers.unshift(function (viewValue) {
                if (viewValue > scope[attrs.minModel]) { // it is valid
                    ctrl.$setValidity('minModel', true);
                    return viewValue;
                } else { // it is invalid, return undefined (no model update)
                    ctrl.$setValidity('minModel', false);
                    return undefined;
                }
            });

        }
    };
});
<section ng-app="app">
    <article ng-controller="appCtrl" class="container">
        <form class="form-horizontal well" name="form" novalidate>
            <div class="form-group">
                <label class="col-sm-6 control-label">Number; min="5" max="500"</label>
                <div class="col-sm-6">
                    <input type="number" min="5" max="500" ng-model="number" name="number" class="form-control" positive-integer validate required />
                    <div class="form-errors">form-errors</div>
                </div>{{ form.number.$error }}</div>
            <div class="form-group">
                <label class="col-sm-6 control-label">Number2 - should be greater than MinNumber; min="5" max="500"</label>
                <div class="col-sm-6">
                    <input type="number" min="5" max="500" ng-model="number2" name="number2" class="form-control" min-model="minnumber" min-model-name="Min Number" positive-integer validate required />
                    <div class="form-errors">form-errors</div>
                </div>{{ form.number2.$error }}</div>
            <div class="form-group">
                <label class="col-sm-6 control-label">MinNumber; positive float</label>
                <div class="col-sm-6">
                    <input type="number" ng-model="minnumber" name="minnumber" class="form-control" positive-float validate required />
                    <div class="form-errors">form-errors</div>
                </div>{{ form.minnumber.$error }}</div>
            <div class="form-group">
                <label class="col-sm-6 control-label">Email - minlength="5", maxlength="15"</label>
                <div class="col-sm-6">
                    <input type="email" ng-minlength="5" ng-maxlength="15" ng-model="email" name="email" class="form-control" validate required />
                    <form-errors></form-errors>
                </div>{{ form.email.$error }}</div>
            <div class="form-group">
                <div class="col-sm-offset-2 col-sm-6">
                    <button ng-click="submit()" ng-disabled="form.$invalid" class="btn btn-primary">submit</button>
                </div>
            </div>
        </form>
    </article>
</section>
input.ng-invalid.ng-dirty {
    border-color: red;
    color: red;
}
input.ng-valid.ng-dirty {
    border-color: green;
    color: green;
}
.form-errors {
    border: 1px solid red;
    display: none;
}

External resources loaded into this fiddle: