0

I have two date inputs to track the start and end of a trip. I want to write a custom validator to make sure the end date is within X days of the start date.

I have already written a single validator to check future dates, but I don't know if it's possible to create a validator that is dependant on another field? From my understanding ngModel gives me access to the current model variable, but is there a way to get access to other variables?

<input type="date" future-date name="startDate" ng-model="startDate" required /> 
<div ng-messages="form.startDate.$error">
    <p ng-message="required">Please select a start date</p> 
    <p ng-message="futureDate">Must be in future</p> 
</div>

<input type="date" future-date name="endDate" ng-model="endDate" required /> 
<div ng-messages="form.endDate.$error">
    <p ng-message="required">Please select a start date</p> 
    <p ng-message="futureDate">Must be in future</p> 
</div>

and the directive:

(function(){
    'use strict';

    angular
        .module('app')
        .directive('futureDate', autocomplete);

    function autocomplete() {
        return {
            restrict: 'A',
            require : 'ngModel',
            link: function(scope, element, attrs, ngModel) {    
                var validator = function(date) {
                    if(!date || date.length === 0) return;
                    var valid = (new Date() > now);
                    ngModel.$setValidity('futureDate', valid);
                    return date;
                };
                ngModel.$parsers.push(validator);
            }   
        };
    }
})();

1 Answer 1

1

note: your inputs have same name... not good. You do not need another ng-model since you can access data, not view control:

<input type="date" future-date name="startDate" ng-model="startDate" required /> 
<input type="date" future-date name="endDate" ng-model="endDate" later-than="startDate" required /> 

Directive to check that end date is later than start, you can change it to X days ofc.:

(function(){
    'use strict';

    angular
        .module('app')
        .directive('laterThan', laterThan);

    function laterThan($parse) {
        return {
            restrict: 'A',
            require : 'ngModel',
            link: function(scope, element, attrs, ngModel) {    
                var validator = function(date) {
                    var laterThan = $parse(attrs.laterThan)(scope);
                    if(!date || !laterThan) return;
                    var valid = (date > laterThan);
                    ngModel.$setValidity('laterThan', valid);
                    return date;
                };
                ngModel.$parsers.push(validator);
            }   
        };
    }
})();

http://plnkr.co/edit/uZNJZBVefVpbMoaPLUSP?p=preview

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. The inputs name was a typo. This looks like what I need but the only problem is that it won't revalidate when the startDate changes. Can I simply put a $watch in the directive to wait for changes and then revalidate?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.