Angular Bootstrap Date Picker validation fix

The Angular Bootstrap date picker is very helpful for UI look/feel. But its validation is inadequate.

  • Javascript is used to determine the date. So I enter 1/1/1, it’s parsed as a valid date even though it’s likely a user error.
  • Any errors (for example, the user enters “xyz”) are not reflected in the control $errors, so the form is still considered valid.

Fortunately, we can solve both of the above problems with a simple directive.

//designed to work with the angular bootstrap date control. 
//sets an error invalidDate when user types the date. 
.directive('validDate', function () {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, element, attrs, control) {
            control.$parsers.push(function (viewValue) {
                var newDate = model.$viewValue;
                control.$setValidity("invalidDate", true);  
                if (typeof newDate === "object" || newDate == "") return newDate;  // pass through if we clicked date from popup
                if (!newDate.match(/^\d{1,2}\/\d{1,2}\/((\d{2})|(\d{4}))$/))
                    control.$setValidity("invalidDate", false);
                return viewValue;

My HTML looks like this:

<form name="myForm">
     <input valid-date datepicker-popup="MM/dd/yyyy" type="text" ng-model="myStartDate" class="form-control" name="startDate" ng-required="true" />
     <span ng-show="myForm.startDate.$error.invalidDate">Invalid start date.</span>
     <span ng-show="myForm.startDate.$error.required">Start date is required.</span>

The regex (hard coded into my directive) should match the one in the date picker control, but that is not required. The one I’m using limits the user to slashes / between components. It’s also a bit limited. 99/99/9999 is still a valid value. But you can get as sophisticated as you want here.