HTML codes:
<!DOCTYPE html> <html> <head> <script src="https://code.angularjs.org/1.4.0-beta.6/angular.js"></script> <script src="https://code.angularjs.org/1.3.15/angular-messages.js"></script> <script src="script.js"></script> </head> <body ng-app="validationExample"> <div ng-controller="MyCtrl as vm"> <form name="myForm" novalidate="" ng-submit="vm.submitted(myForm, vm.input)"> <span class="input-label">Start Date</span> <input type="date" name="startDate" ng-model="vm.input.startDate" required /> <span ng-messages="myForm.startDate.$error" ng-messages-include="errors-template.html"></span> <br /> <span class="input-label">End Date</span> <input type="date" name="endDate" ng-model="vm.input.endDate" start-date="{{vm.input.startDate.yyyymmdd()}}" compare-with-start-date /> <span ng-messages="myForm.endDate.$error" ng-messages-include="errors-template.html"></span> <br /> <button>submit</button> </form> </div> <!-- error messages template --> <script id="errors-template.html" type="text/ng-template"> <span ng-message="required">* required!</span> <span class="form-error" ng-message="checkEndDate">* end date cannot be earlier than start date</span> </script> </body> </html>
JavaScript codes:
var myApp = angular.module('validationExample', ['ngMessages']) myApp.controller('MyCtrl', [function () { var vm = this; vm.submitted = function(form, input) { if(form.$valid) { alert('submitted'); } } } ]); myApp.directive("compareWithStartDate", function () { return { restrict: "A", require: "?ngModel", link: function (scope, element, attributes, ngModel) { validateEndDate = function (endDate, startDate) { if (endDate && startDate) { startDate = new Date(startDate); startDate.setHours(0, 0, 0, 0); endDate = new Date(endDate); endDate.setHours(0, 0, 0, 0); return endDate >= startDate; } else { return true; } } // use $validators.validation_name to do the validation ngModel.$validators.checkEndDate = function (modelValue) { var startdate = Date.parse(attributes.startDate); var enddate = modelValue; return validateEndDate(enddate, startdate); }; // use $observe if we need to keep an eye for changes on a passed value attributes.$observe('startDate', function (value) { var startdate = Date.parse(value); var enddate = Date.parse(ngModel.$viewValue); // use $setValidity method to determine the validation result // the first parameter is the validation name, this name is the same in ng-message template as well // the second parameter sets the validity (true or false), we can pass a function returning a boolean ngModel.$setValidity("checkEndDate", validateEndDate(enddate, startdate)); }); } }; }); // function to parse date time object into yyyy-mm-dd format string Date.prototype.yyyymmdd = function () { var yyyy = this.getFullYear().toString(); var mm = (this.getMonth() + 1).toString(); // getMonth() is zero-based var dd = this.getDate().toString(); return yyyy + '-' + (mm[1] ? mm : "0" + mm[0]) + '-' + (dd[1] ? dd : "0" + dd[0]); };
See the example in Plunker.