15
votes

Angular UI Bootstrap datepicker does not honors ng-readonly attribute. If ng-readonly expression is true, text input field is greyed and can not be modified, but datepicker's calendar pops up, allowing modification of form field.

So far i tryed 3 approaches (see http://plnkr.co/edit/KHrbbI6W1pWG5ewSsE9r?p=preview), both of which are rather hackish and ugly:

  • Disabling of all dates in datepicker if it should be readonly.

    <input type="text" datepicker-popup="dd.MM.yyyy" ng-model="dt" ng-readonly="ro" date-disabled="disabled(date, mode)" />
    

    in html file and

    $scope.$watch('ro', function(ro) {
      $scope.dt = new Date($scope.dt); // force datepicker div refresh
    });
    $scope.disabled = function(date, mode) {
      return $scope.ro;
    };
    

    in controller.

  • Not allowing datepicker popup div to pop up.

    <input type="text" datepicker-popup="dd.MM.yyyy" ng-model="dt" ng-readonly="ro" is-open="opened" />
    

    in html file and

    $scope.$watch('opened', function(v1, v2, v3) {
      if ($scope.ro && v1) {
        $timeout(function() {
          $scope.opened = false;
        });
      }
    });
    

    in controller. Blinking datepicker looks terrible.

  • Replacing datepicker's text input with another readonly input field without datepicker attached.

    <datepicker-ro-fix datepicker-popup="dd.MM.yyyy" ng-model="dt" ng-readonly="ro" />
    

    in html file and

    m.directive('datepickerRoFix', function() {
      return {
        restrict: 'E',
        require: 'ngModel',
        scope: {
          ngModel: '=',
          ngReadonly: '=',
        },
        template: '<span>'
          + '<input ng-hide="ngReadonly" type="text" datepicker-popup="dd.MM.yyyy" ng-model="ngModel" />'
          + '<input ng-show="ngReadonly" type="text" readonly="true" value="{{ ngModel | date:\'dd.MM.yyyy\'}}" />'
          + '</span>',
      };
    });
    

    in js file. This seems to be the best solution so far, but the downside is that now there are two input elements instead of one, both have some hardcoded properties.

First and second approaches require me to add a bunch of code into form controller per each date input field, Third is much harder to customise.

I am new to angular and should be missing something. Is there some better way to make input fields with datepicker really read-only?

3
why not just display date as text and hide input so it is still available for angular validation purposescharlietfl
@charlietfl, how it differs from my 3rd approach?Vasily Redkin
meaning no input displayed to user...jest text and a buttoncharlietfl
For me this was a "feature" so I could disable manual text input and only allow user to pick with the datepicker. :)cen

3 Answers

2
votes

Your third approach is quite nice, imho.

Given that the datepicker itself obviously does not support readonly property, I don't see another way how to make it read-only (and you even created a directive for it)

Your second approach sometimes results in minor flickering when clicking on the input (is it just me?)

As to customization, could you elaborate why it is difficult to do do? You'd have to pipe all the possible attributes of the original directive through to your directive, I guess?

11
votes

ng-disabled="true"

worked for me. Angularjs: 1.2.9 and ui-boostrap: 0.8.0

Unfortunately I do not have reputation enough to comment on the original answer

0
votes

Use ng-disabled="true"

<input type="text" class="form-control" datepicker-popup="{{format}}" ng-model="date" min="minDate" max="maxDate" ng-disabled="true" readonly="true"/>