Timmy O'Mahony
Timmy O'Mahony

Reputation: 53971

Creating dependant custom validators for form inputs?

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);
            }   
        };
    }
})();

Upvotes: 0

Views: 58

Answers (1)

Petr Averyanov
Petr Averyanov

Reputation: 9476

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

Upvotes: 1

Related Questions