angularjsjquery-uiangularjs-directivedatepickerisolate-scope

Isolating scopes with multiple jquery ui date pickers in angular


I'm having some problems isolating the scopes of the date-picker-search directive below.

(function(){
'use strict';

angular.module('ganeshaApp')
.directive('datePickerSearch', function(){
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attrs, ngModelCtrl){
            $(function(){
                element.datepicker({
                    dateFormat: 'd/m/yy',
                    onSelect: function(date){
                        scope.date = date;
                        scope.$apply();
                    }
                })
            });         
        }
    }
})
})();

In my first attempt I tried using this code, but as expected changing one input with ng-model="date" updates all the inputs referencing the directive with the same ng-model.

                    <tr>
                        <td>Publication Date:</td>
                        <td greyed-dates>
                            between
                            <div class="start inner-addon right-addon">
                                <i class="glyphicon glyphicon-calendar"></i>
                                <input type="text" ng-model="date"
                                       date-picker-search placeholder="dd/mm/yyyy"/>

                            </div>
                            <span>and</span>
                            <div class="end inner-addon right-addon">
                                <i class="glyphicon glyphicon-calendar"></i>
                                <input type="text" ng-model="date"
                                       date-picker-search placeholder="dd/mm/yyyy"/>
                            </div>
                        </td>
                    </tr>
                    <tr>
                        <td>Enactment Date:</td>
                        <td greyed-dates>
                            between
                            <div class="start inner-addon right-addon">
                                <i class="glyphicon glyphicon-calendar"></i>
                                <input type="text" ng-model="date"
                                       date-picker-search placeholder="dd/mm/yyyy"/>

                            </div>
                            <span>and</span>
                            <div class="end inner-addon right-addon">
                                <i class="glyphicon glyphicon-calendar"></i>
                                <input type="text" ng-model="date"
                                       date-picker-search placeholder="dd/mm/yyyy"/>
                            </div>
                        </td>
                    </tr>

All models update by clicking or typing

I figured isolating the scopes in the directive would solve the problem. It does to a degree, when you are just clicking on the calendar to input the dates, but when you try to type the dates in manually, again all the inputs that reference the directive are updated.

Models update by clicking only

The only way I was able to sort of resolve this problem is by changing the ng-models on each of the elements by giving them a random parent reference (a.data, b.data, c.data, d.data). While this allows changes to be made to each date picker in isolation, it's clearly a very bad solution. If anyone has any idea what the problem might be here, I'd really appreciate any help. It's something to do with isolating the scopes, right?


Solution

  • According to me, your second solution is the only way.

    Even if you achieved isolating of scope Using $scope.date as the only variable, it will bring inconsistency. (What if you want to use $scope.date in some controller, how would AJS will know which date-picker value you are talking about).

    AJS changing the value all the date-picker is the expected behavior.

    Using different variable is what I would have done. i.e a.date, b.date ..


    You can use it like this

     link: function(scope, element, attrs, ngModelCtrl){
                $(function(){
                    element.datepicker({
                        dateFormat: 'd/m/yy',
                        onSelect: function(date){
                            scope.$apply(function () {
                            ngModelCtrl.$setViewValue(date);
                        });
                        }
                    })
                });         
            }
    


    And In HTML

    <input type="text" ng-model="a.date" date-picker-search placeholder="dd/mm/yyyy"/>
    
    <input type="text" ng-model="b.date" date-picker-search placeholder="dd/mm/yyyy"/> 
    

    and so on.


    Here is a codepen reference. Hope it helps.