web-dev-qa-db-fra.com

Angular UI Bootstrap datepicker: support de ng-readonly

Interface utilisateur angulaire Bootprap datepicker ne respecte pas l'attribut ng-readonly. Si l'expression ng-readonly est true, le champ de saisie de texte est grisé et ne peut pas être modifié, mais le calendrier de datepicker s'affiche, permettant ainsi de modifier le champ de formulaire.

Jusqu'ici, j'ai essayé 3 approches (voir http://plnkr.co/edit/KHrbbI6W1pWG5ewSsE9r?p=preview ), les deux étant plutôt féroces et laides:

  • Désactivation de toutes les dates dans datepicker si elle doit être en lecture seule.

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

    en fichier html et

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

    dans le contrôleur.

  • Ne pas autoriser le pop-date datepicker à apparaître.

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

    en fichier html et

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

    dans le contrôleur. Datepicker clignotant semble terrible.

  • Remplacement de l'entrée de texte de datepicker par un autre champ en lecture seule sans datepicker attaché.

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

    en fichier html et

    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>',
      };
    });
    

    dans le fichier js. Cela semble être la meilleure solution jusqu'à présent, mais l'inconvénient est que maintenant, il y a deux éléments d'entrée au lieu d'un, les deux ayant des propriétés codées en dur.

La première et la deuxième approche nécessitent l’ajout d’un tas de code dans le contrôleur de formulaire pour chaque champ de saisie de la date. Troisièmement, il est beaucoup plus difficile de le personnaliser.

Je suis novice dans angular et il devrait manquer quelque chose. Existe-t-il un meilleur moyen de rendre les champs de saisie avec datepicker vraiment en lecture seule?

14
Vasily Redkin

Votre troisième approche est assez gentille, à mon humble avis. 

Etant donné que datepicker lui-même ne prend évidemment pas en charge la propriété en lecture seule, je ne vois pas d'autre moyen de le rendre en lecture seule (et vous avez même créé une directive pour cela)

Votre deuxième approche entraîne parfois un léger scintillement lorsque vous cliquez sur l'entrée (est-ce juste moi?)

Pour ce qui est de la personnalisation, pourriez-vous expliquer pourquoi il est difficile de le faire? Vous auriez à canaliser tous les attributs possibles de la directive d'origine à travers votre directive, je suppose?

1
SebastianRiemer

ng-disabled="true"

a travaillé pour moi. Angularjs: 1.2.9 et ui-bootstrap: 0.8.0

Malheureusement, je n'ai pas assez de réputation pour commenter la réponse originale

11
Lars Johannesson

Utilisez ng-disabled="true"

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