Question

I'm using JQuery bootstrap datepicker (eternicode.github.io/bootstrap-datepicker/) in an angular application.

I've wrote my own directive to wrap this datepicker and do some date formatting. Datepicker works fine and display an appropriate date format.

Currently, I want to show a formatted date value and put a timestamp formatted value in ngModel.

My code is okay when I'm not trying to use template in my directive :

cosyApp.directive("datepicker", ['moment',
    function(moment) {

        function link($scope, element, attrs, ctrl) {    
            // Init JQuery datepicker
            element.datepicker();

            ctrl.$parsers.push(function(valueFromInput) {
                // Format displayed value in timestamp format
                return moment(valueFromInput).format('X');
            });

        }
        return {
            restrict: 'A',
            require: 'ngModel',
            link: link
        };
    }
]);

But when I use template attribute, ngModel and displayed value are the same :

return {
    restrict: 'A',
    replace: true,
    require: 'ngModel',
    template: "<div class='input-group date'> {{ngModel}}" +
                "<input class='form-control' ng-model='ngModel'>" +
                "<span class='input-group-addon'><i class='glyphicon glyphicon-calendar'></i></span>" +
            "</div>",
    link: link
};
Was it helpful?

Solution

I made a few changes to your plunker. I didn't try to figure out why the calendar is showing up right away, I instead just bound the datepicker to the input field.

Instead of trying to use ngModel on the input ng-mode directly as you were doing, I created an intermediate model object, then adding a function to watch for changes to the input and pass those changes to the ngModelController directly.

Side note, I believe if you plan on updating your model value outside the UI and want it to update the view, you will have to add a $watch to update the intermediate model object.

http://plnkr.co/edit/5213zUvnqyv0ARqc11aU?p=preview

cosyApp.directive("datepickerx",
    function($window) {

        function link($scope, element, attrs, ctrl) {    
            $scope.model = ctrl.$viewValue;
            // Init JQuery datepicker
            element.find('input').datepicker({
                autoclose: true,
                clearBtn: true,
            });  

            $scope.changed = function() {
              ctrl.$setViewValue($scope.model);
            }

            ctrl.$parsers.push(function(valueFromInput) {
                // Format displayed value in timestamp format and store it to ngModel
                return $window.moment(valueFromInput).format('X');
            });

        }

        /* ********** This part of code doesn't works ********** */

        return {
          restrict: 'A',
          replace: true,
          require: 'ngModel',
          scope: {
              ngModel: '='
          },
          template: '<div class="input-group date">' +
                        '<input class="form-control" ng-model="model" ng-change="changed()"/>' +
                        '<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>' +
                    '</div>',
          link: link
        };

    }
);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top