0

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
};
4
  • Can you make a JSFiddle or Plunker, please? Commented Mar 3, 2014 at 17:51
  • Much clearer code here : http://plnkr.co/edit/9fojEhcxoBEbUkrtGGnQ?p=preview Please notice that Plunker automatically display opened datepicker in this Plunker, I have no idea why... Commented Mar 4, 2014 at 8:45
  • I made a few changes. 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. Is this what you're looking for? plnkr.co/edit/5213zUvnqyv0ARqc11aU?p=preview Commented Mar 4, 2014 at 15:41
  • Yeah, that's fine ! You made my day, Thank you ! Can you post your answer ? I'll vote for this. Commented Mar 4, 2014 at 15:54

1 Answer 1

1

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
        };

    }
);
Sign up to request clarification or add additional context in comments.

8 Comments

I've got another question about this solution. You're applying datepicker directive to a <div>. What if I want to apply it to an <input> in the same way of first example ?
Any idea ? It could be awesome if I could declare my directive on an <input> instead of a <div>
I'm not sure I understand. Your first example already worked on an <input>. What do you want done differently?
In your working example, you used the "datepickerx" directive on a <div> element. I would like to change this by an <input>, but it doesn't works.
If you remove the template and change element.find('input').datepicker() to element.datepicker() then I think it would work.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.