1

I have an angularjs app that tracks household member data. One of the more important fields is DOB. I used the following overflow post to make a custom datepicker directive jQuery ui datepicker with Angularjs

here is the code

//jquery datepicker through angular
angularApp.directive('datepicker', function() {
return {
    restrict: 'A',
    require : 'ngModel',
    link : function (scope, element, attrs, ngModelCtrl) {
        $(function(){
            element.datepicker({
                dateFormat:'mm/dd/yy',
                minDate: new Date(1910,0,1),
                yearRange:'1910:+0',
                changeMonth: true,
                changeYear: true,
                onSelect:function (date) {
                    // ngModelCtrl.$setViewValue(date);
                    scope.date = date;
                    scope.$apply();
                }
            });
        });
    }
};
});

Now where my issue is different then some other posts I have found is I only get the Missing instance data for this datepicker on new household members that can be created by clicking "add new member" button. Here is a plunker link to example the bug, http://plnkr.co/edit/DdFMbNIEp39cg3yE1ar6?p=preview.

To replicate the issue, please try the DOB for household member 1 (1st set of fields). The DOB picker should work, now select "Click to add additional members of the household". THis will add new fields for household member 2, if you click the DOB field the calendar will pop up but you will not be able to select a date - also, the test field will not populate.

1 Answer 1

3

By adding a console.log() in the directive I was able to determine that the angularjs html compiler wasn't able to compile the dynamic id.

console.log("xxxxxx-1 " + $(element)[0].id);

regardless of how many household members I created they all had the same id:

xxxxxx-1 HOUSEHOLD{{ $index + 1 }}_dob

By setting the transclude flag to true and adding a time delay, we can allow the compiler to do its job before trying to select a date.

//jquery datepicker through angular
angularApp.directive('datepicker', function($timeout) {
var linker = function (scope, element, attrs, ngModelCtrl) {
    $timeout( function(){
        $(element).datepicker({
            dateFormat:'mm/dd/yy',
            minDate: new Date(1910,0,1),
            yearRange:'1910:+0',
            changeMonth: true,
            changeYear: true,
            onSelect: function (date) {
                ngModelCtrl.$setViewValue(date);
                scope.$apply();
            }
        });
    });
};

return {
    restrict: 'A',
    require : 'ngModel',
    transclude: true,
    link : linker,
};

});

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

2 Comments

So the translude pass on all the "attributes" to the underlying element, but why do we need the timeout? I thought the link function was invoked after compilation was complete. Just trying to understand the fix :)
Might also be worth noting that I had to add the following to the $timeout callback: .bind(this, scope, ngModelCtrl)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.