How to create an angularJs wrapper directive for a ui-bootstrap datepicker? How to create an angularJs wrapper directive for a ui-bootstrap datepicker? angularjs angularjs

How to create an angularJs wrapper directive for a ui-bootstrap datepicker?


To be honest, I'm not quite sure why it's caused and what's causing your date to be "toString-ed" before showing it in the input.

However, I did find places to restructure your directive, and remove much unnecessary code, such as $compile service, attributes changes, scope inheritance, require in the directive, etc.. I used isolated scope, since I don't think every directive usage should know the parent scope as this might cause vicious bugs going forward. This is my changed directive:

angular.module('ui.bootstrap.demo').directive('myDatepicker', function() {  return {      restrict: 'A',      scope: {          model: "=",          format: "@",          options: "=datepickerOptions",          myid: "@"      },      templateUrl: 'datepicker-template.html',      link: function(scope, element) {          scope.popupOpen = false;          scope.openPopup = function($event) {              $event.preventDefault();              $event.stopPropagation();              scope.popupOpen = true;          };          scope.open = function($event) {            $event.preventDefault();            $event.stopPropagation();            scope.opened = true;          };      }  };});

And your HTML usage becomes:

<div my-datepicker model="container.two"                    datepicker-options="dateOptions"                    format="{{format}}"                     myid="myDP"></div>

Edit: Added the id as a parameter to the directive. Plunker has been updated.

Plunker


Your directive will work when you add these 2 lines to your directive definition:

return {    priority: 1,    terminal: true,    ... }

This has to do with the order in which directives are executed.

So in your code

<input my-datepicker="" type="text" ng-model="container.two" id="myDP" />

There are two directives: ngModel and myDatepicker. With priority you can make your own directive execute before ngModel does.


I think the answer from @omri-aharon is the best, but I'd like to point out some improvements that haven't been mentioned here:

Updated Plunkr

You can use the config to uniformly set your options such as the format and text options as follows:

angular.module('ui.bootstrap.demo', ['ui.bootstrap']).config(function (datepickerConfig, datepickerPopupConfig) {  datepickerConfig.formatYear='yy';  datepickerConfig.startingDay = 1;  datepickerConfig.showWeeks = false;  datepickerPopupConfig.datepickerPopup = "shortDate";  datepickerPopupConfig.currentText = "Heute";  datepickerPopupConfig.clearText = "Löschen";  datepickerPopupConfig.closeText = "Schließen";});

I find this to be clearer and easier to update. This also allows you to vastly simplify the directive, template and markup.

Custom Directive

angular.module('ui.bootstrap.demo').directive('myDatepicker', function() {  return {      restrict: 'E',      scope: {          model: "=",          myid: "@"      },      templateUrl: 'datepicker-template.html',      link: function(scope, element) {          scope.popupOpen = false;          scope.openPopup = function($event) {              $event.preventDefault();              $event.stopPropagation();              scope.popupOpen = true;          };          scope.open = function($event) {            $event.preventDefault();            $event.stopPropagation();            scope.opened = true;          };      }  };});

Template

<div class="row">    <div class="col-md-6">        <p class="input-group">          <input type="text" class="form-control" id="{{myid}}" datepicker-popup ng-model="model" is-open="opened" ng-required="true"  />          <span class="input-group-btn">            <button type="button" class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button>          </span>        </p>    </div></div> 

How to Use It

<my-datepicker model="some.model" myid="someid"></my-datepicker>

Further, if you want to enforce the use of a German locale formatting, you can add angular-locale_de.js. This ensures uniformity in the use of date constants like 'shortDate' and forces the use of German month and day names.