Custom form validation directive to compare two fields

You do not need any directive. Just assign the "min" value of max to min-value. Like:

<input name="min" type="number" ng-model="field.min"/>
<input name="max" type="number" ng-model="field.max" min=" {{ field.min }}"/>

And you do not need any customization.
More: you can do min=" {{ field.min + 1}}"


Many ways to skin a cat.

PLUNKER

app.directive('lowerThan', [
  function() {

    var link = function($scope, $element, $attrs, ctrl) {

      var validate = function(viewValue) {
        var comparisonModel = $attrs.lowerThan;

        if(!viewValue || !comparisonModel){
          // It's valid because we have nothing to compare against
          ctrl.$setValidity('lowerThan', true);
        }

        // It's valid if model is lower than the model we're comparing against
        ctrl.$setValidity('lowerThan', parseInt(viewValue, 10) < parseInt(comparisonModel, 10) );
        return viewValue;
      };

      ctrl.$parsers.unshift(validate);
      ctrl.$formatters.push(validate);

      $attrs.$observe('lowerThan', function(comparisonModel){
        // Whenever the comparison model changes we'll re-validate
        return validate(ctrl.$viewValue);
      });

    };

    return {
      require: 'ngModel',
      link: link
    };

  }
]);

Usage:

<input name="min" type="number" ng-model="field.min" lower-than="{{field.max}}" />
<span class="error" ng-show="form.min.$error.lowerThan">
  Min cannot exceed max.
</span>

Would a simple comparison suit you?

<small class="error" ng-show="field.min > field.max">

I think a directive would be an overkill if your case is just this. If you do not feel comfortable with the view containing application logic, you can export it in a function of the controller:

$scope.isMinMaxInalid = function() {
    return $scope.field.min > $scope.field.max;
};

And the template:

<small class="error" ng-show="isMinMaxInalid()">

For me, beyond a feedback message, I needed define the field as invalid, preventing submit. So I gathered some approaches, like @thestewie approach, with a view configuration to gather a solution for dates comparison. I hope can aggregate the solutions that were presented.

The code is in PLUNKER

angular.module('MyApp')
    .directive('thisEarlierThan', function () {
        return {
            require: 'ngModel',
            restrict: 'A',
            link: function (scope, elem, attrs, ctrl) {
                var startDate,
                    endDate;

                scope.$watch(attrs.ngModel, function (newVal, oldVal, scope) {
                    startDate = newVal;
                    check();
                });

                scope.$watch(attrs.thisEarlierThan, function (newVal, oldVal, scope) {
                    endDate = newVal;
                    check();
                });

                var check = function () {
                    if (typeof startDate === 'undefined' || typeof endDate === 'undefined') {
                        return;
                    }

                    if (!validate(startDate)) {
                        startDate = new Date(startDate);
                        if (!validate(startDate)) {
                            return;
                        }
                    }

                    if (!validate(endDate)) {
                        endDate = new Date(endDate);
                        if (!validate(endDate)) {
                            return;
                        }
                    }

                    if (startDate < endDate) {
                        ctrl.$setValidity('thisEarlierThan', true);
                    }
                    else {
                        ctrl.$setValidity('thisEarlierThan', false);
                    }

                    return;
                };

                var validate = function (date) {
                    if (Object.prototype.toString.call(date) === '[object Date]') {
                        if (isNaN(date.getTime())) {
                            return false;
                        }
                        else {
                            return true;
                        }
                    }
                    else {
                      return false;
                    }
                };
            }
        };
    })
;