Search code examples
angularjsdatepickerangular-ngmodelbootstrap-datepicker

using bootstrap-datepicker with angularjs. Need to find a way to update ng-model when a date is chosen


In short, I need to find a way to update ng-model when using bootstrap-datepicker. Here is a plunker I made to demonstrate what is going on http://plnkr.co/edit/nNTEM25I2xX2zRKOWbD1?p=preview. I've tried searching around and am fairly positive that I need to use a directive to pass a value to the model. Typing something in the text box will update the selected date model, but just using the datepicker does nothing. The below directive seemed like it should work but unfortunately it doesn't seem to have much of an effect.

app.directive('datepicker', function() {
    return {
        restrict : 'A',
        require : 'ngModel',
        link : function(scope, element, attrs, ngModelCtrl) {
            $(function() {
                element.datepicker({
                    dateFormat : 'dd/mm/yy',

                    onSelect : function(date) {

                        ngModelCtrl.$setViewValue(date);

                        element.datepicker("setDate", date);

                        scope.$apply();

                    }
                });
            });
        }
    }
});

An easy solution would be to just use another datepicker, but unfortunately due to restrictions on how many external libraries I can use this is the datepicker I have to use. Any insight would be greatly appreciated!!!


Solution

  • I strongly recommend using UI-Bootstrap or something similar.

    But for those that need to use Bootstraps date-picker for whatever reason here is a starting place using your directive, with a few changes:

    app.directive('datepicker', function() {
       return {
          restrict: 'A',
          require: 'ngModel',
          compile: function() {
             return {
                pre: function(scope, element, attrs, ngModelCtrl) {
                   // Initialize the date-picker
                   $(element).datepicker({
                      format: 'dd/mm/yyyy'
                   }).on('changeDate', function(ev) {
                      // Binds the changes back to the controller
                      // I also found that event.format() returns the string
                      // I wasn't aware of that. Sure beats using the date object and formatting yourself.
                      ngModelCtrl.$setViewValue(ev.format('dd/mm/yyyy'));
    
                      // I HATE using $apply, but I couldn't get it to work without
                      scope.$apply();
                   });
                }
             }
          }
       }
    });
    

    HTML:

    <input type="text" datepicker="" ng-model="date" />
    

    Very simple and straightforward and allows you to reuse, here is a working plunker