-1

I have these custom validation directives which work as intended. Problems is I want to trigger validation of the input when the other input that is used to compare with is changed.. Is this solvable in the watch block?

Lets say i have

<input afterOtherDate="dateB" ng-model="dateA" value="2014"/>

<input beforeOtherDate="dateA" ng-model="dateB" value="2013"/>

If i then set dateA to be after dateB, dateA will become invalid, but dateB wont know. Same the other way around, if i have

<input afterOtherDate="dateB" ng-model="dateA" value="2013"/>

<input beforeOtherDate="dateA" ng-model="dateB" value="2014"/>

Both inputs need to be re-validated when the other one changes. So both become valid.

validationHelpers.directive('afterOtherDate', function () {
return {
    restrict: 'A',
    require: 'ngModel',
    link: function (scope, elm, attrs, ctrl) {
        var doValidation = function () {
            ctrl.$parsers.unshift(function (viewValue) {
                if (viewValue <= compareTo) {
                    ctrl.$setValidity('afterOtherDate', false);
                    return viewValue;
                } else {
                    ctrl.$setValidity('afterOtherDate', true);
                    return viewValue;
                }
            });
        };

        var scopeHierarchy = attrs["afterOtherDate"].split('.');
        var compareTo = scope;
        for (var k = 0; k < scopeHierarchy.length; k++) {
            compareTo = compareTo[scopeHierarchy[k]];
        }

        scope.$watch(attrs["afterOtherDate"], function (val) {

        });

        doValidation();
    }
};
});

validationHelpers.directive('beforeOtherDate', function () {
return {
    restrict: 'A',
    require: 'ngModel',
    link: function (scope, elm, attrs, ctrl) {
        var doValidation = function () {
            ctrl.$parsers.unshift(function (viewValue) {
                if (viewValue <= compareTo) {
                    ctrl.$setValidity('beforeOtherDate', true);
                    return viewValue;
                } else {
                    ctrl.$setValidity('beforeOtherDate', false);
                    return viewValue;
                }
            });
        };

        var scopeHierarchy = attrs["beforeOtherDate"].split('.');
        var compareTo = scope;
        for (var k = 0; k < scopeHierarchy.length; k++) {
            compareTo = compareTo[scopeHierarchy[k]];
        }

        scope.$watch(attrs["beforeOtherDate"], function (val) {

        });

        doValidation();
    }
};
});

Would be cool to solve it inside the custom directives!

BR twd

twDuke
  • 927
  • 1
  • 8
  • 22
  • 1
    It's not clear whether you're operating on years only (e.g. "2014") or on actual dates (e.g. "01/16/2014")? Also, you shouldn't really be using a `value` attribute when using `ng-model`. Take a look at this similar question: [Custom form validation directive to compare two fields](http://stackoverflow.com/questions/20982751/custom-form-validation-directive-to-compare-two-fields/20984017#20984017). – Stewie Jan 16 '14 at 16:18
  • Its real dates, dont have values in the real code. The samples was kinda psuedo. – twDuke Jan 16 '14 at 18:11
  • Works perfect. Feel free to add the plunker as an answer and i will mark it. – twDuke Jan 16 '14 at 22:25

1 Answers1

0

What I do in my directive, that I get the controller of ngModel of the field which I'm trying to compare to:

var compareModel = scope.$eval([formCtrl.$name, attr.dateAfter].join("."));

I'm passing the model name in the attribute. Then you can access its parsers and push a method that would fire a validation in your model.

 compareModel.$parsers.push(function (value) {

I force the compareModel to revalidate by using $setViewValue:

compareModel.$parsers.push(function (value) {
    checkBefore(value);
    model.$setViewValue(model.$viewValue);
    return value;
});
kvetis
  • 6,682
  • 1
  • 28
  • 48