Angular UI Bootstrap datepicker: ng-readonly support


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, 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 $;

    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 ($ && 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?

Problem courtesy of: Vasily Redkin


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?

Solution courtesy of: SebastianRiemer



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

Discussion courtesy of: Lars Johannesson

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"/>
Discussion courtesy of: Vaibu

This recipe can be found in it's original form on Stack Over Flow.