Leantraxxx
Leantraxxx

Reputation: 4606

Detect ng-model change into directive

I'm doing a custom validation (directive) to compare two dates and show error if start_date is greater than end_date... I'm passing start_date through ng-model

ng-model="start_date"

and end_date with my directive:

lower-than-date="{{end_date.toISOString()}}" //ignore the toISOString()

The input where I'm using my directive...

<input type="text" ng-model="start_date"
datepicker-popup="yyyy-MM-dd" min="today" show-weeks="false"
lower-than-date="{{end_date.toISOString()}}"/>

The directive...

.directive("lowerThanDate", ['$parse', function($parse) {
    return {
        require: 'ngModel',

        link: function (scope, element, attrs, ctrl) {

            var lowerThan = null;
            function revalidate(_val) {
                var valid = _val && lowerThan ? _val < lowerThan : true;
                ctrl.$setValidity('lowerThanDate', valid);
            }

            attrs.$observe('lowerThanDate', function(_value) {
                //Here I'm detecting when end_date change
                lowerThan = new Date(_value);
                revalidate(ctrl.$modelValue);
            });

            ctrl.$parsers.unshift(function(_value) {
                revalidate(_value);
                return _value;
            });
        }
    };
}])

This code is working fine, but the validation is triggered only when I change the end_date. I want to validate when I change start_date too.

So, the question is: How can I "observe" the ng-model value to trigger the validation when start_date change.

Note: This is a generic directive to compare dates. Keep this on mind.

Upvotes: 1

Views: 3119

Answers (2)

Valentyn Shybanov
Valentyn Shybanov

Reputation: 19401

You should a formatter: "Array of functions to execute, as a pipeline, whenever the model value changes".

So just do something like:

        function revalidate(_val) {
            var valid = _val && lowerThan ? _val < lowerThan : true;
            ctrl.$setValidity('lowerThanDate', valid);
            return _val;
        }
        ....
        ctrl.$formatters.unshift(revalidate);
        ctrl.$parsers.unshift(revalidate);

As the reason could be that the model changed from some other place, not directly in DOM element.

Upvotes: 0

thesamet
thesamet

Reputation: 6582

Set up binding to ngModel inside your link function:

var modelValue = $parse(attr.ngModel);

scope.$watch(modelValue, function(value) {
  // validate value against endDate.
});

Upvotes: 5

Related Questions