more circ integration
authorBill Erickson <berick@esilibrary.com>
Thu, 12 Jun 2014 19:46:30 +0000 (15:46 -0400)
committerBill Erickson <berick@esilibrary.com>
Thu, 12 Jun 2014 19:46:30 +0000 (15:46 -0400)
Signed-off-by: Bill Erickson <berick@esilibrary.com>
Open-ILS/src/templates/staff/circ/patron/t_noncat_dialog.tt2 [deleted file]
Open-ILS/src/templates/staff/circ/share/t_event_override_dialog.tt2
Open-ILS/src/templates/staff/circ/share/t_noncat_dialog.tt2 [new file with mode: 0644]
Open-ILS/src/templates/staff/circ/share/t_transit_dialog.tt2
Open-ILS/web/js/ui/default/staff/circ/patron/app.js
Open-ILS/web/js/ui/default/staff/circ/patron/checkout.js
Open-ILS/web/js/ui/default/staff/circ/services/circ.js
Open-ILS/web/js/ui/default/staff/services/grid.js

diff --git a/Open-ILS/src/templates/staff/circ/patron/t_noncat_dialog.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_noncat_dialog.tt2
deleted file mode 100644 (file)
index 7cbadfd..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-<!-- edit bucket dialog -->
-<form class="form-validated" novalidate ng-submit="ok(count)" name="form">
-  <div class="">
-    <div class="">
-      <div class="modal-header">
-        <button type="button" class="close" 
-          ng-click="cancel()" aria-hidden="true">&times;</button>
-        <h4 class="modal-title">
-          [% l('Enter the number of {{type.name()}} circulating') %]
-        </h4>
-      </div>
-      <div class="modal-body">
-        <div class="form-group">
-          <label for="noncat-count" class="sr-only">[% l('Count') %]</label>
-          <input type="number" class="form-control" focus-me='focusMe' required
-            id="noncat-title" ng-model="count" placeholder="[% l('Count...') %]"/>
-        </div>
-      </div>
-      <div class="modal-footer">
-        <input type="submit" class="btn btn-primary" 
-            ng-disabled="form.$invalid" value="[% l('OK') %]"/>
-        <button class="btn btn-warning" 
-          ng-click="cancel()">[% l('Cancel') %]</button>
-      </div>
-    </div> <!-- modal-content -->
-  </div> <!-- modal-dialog -->
-</form>
index 7ff0a79..78f33f3 100644 (file)
@@ -1,29 +1,24 @@
-<form class="form-validated" novalidate ng-submit="ok()" name="form">
-  <div class="modal-dialog">
-    <div class="modal-content">
-      <div class="modal-header">
-        <button type="button" class="close" 
-          ng-click="cancel()" aria-hidden="true">&times;</button>
-        <h4 class="modal-title">
-          [% l('Exceptions occurred during checkout.') %]
-        </h4>
-      </div>
-      <div class="modal-body">
-        <div class="panel panel-danger">
-          <div class="panel-heading">{{evt.textcode}}</div>
-          <div class="panel-body">{{evt.desc}}</div>
-        </div>
-      </div>
-      <div class="modal-footer">
-        <i>[% |l %]
-If overridden, subsequent checkouts during this patron's session will
-auto-override this event[% END %]</i><!--'vim-->
-        <br/><br/>
-        <input type="submit" class="btn btn-primary" 
-            value="[% l('Force Checkout?') %]"/>
-        <button class="btn btn-warning" 
-            ng-click="cancel()">[% l('Cancel') %]</button>
-      </div>
-    </div> <!-- modal-content -->
-  </div> <!-- modal-dialog -->
+<form ng-submit="ok()" role="form">
+  <div class="modal-header">
+    <button type="button" class="close" 
+      ng-click="cancel()" aria-hidden="true">&times;</button>
+    <h4 class="modal-title">
+      [% l('Exceptions occurred during checkout.') %]
+    </h4>
+  </div>
+  <div class="modal-body">
+    <div class="panel panel-danger">
+      <div class="panel-heading">{{evt.textcode}}</div>
+      <div class="panel-body">{{evt.desc}}</div>
+    </div>
+  </div>
+  <div class="modal-footer">
+    <i>[% |l %]If overridden, subsequent checkouts during this patron's 
+ session will auto-override this event[% END %]</i>
+    <br/><br/>
+    <input type="submit" class="btn btn-primary" 
+        value="[% l('Force Checkout?') %]"/>
+    <button class="btn btn-warning" 
+      ng-click="cancel($event)">[% l('Cancel') %]</button>
+  </div>
 </form>
diff --git a/Open-ILS/src/templates/staff/circ/share/t_noncat_dialog.tt2 b/Open-ILS/src/templates/staff/circ/share/t_noncat_dialog.tt2
new file mode 100644 (file)
index 0000000..7cbadfd
--- /dev/null
@@ -0,0 +1,27 @@
+<!-- edit bucket dialog -->
+<form class="form-validated" novalidate ng-submit="ok(count)" name="form">
+  <div class="">
+    <div class="">
+      <div class="modal-header">
+        <button type="button" class="close" 
+          ng-click="cancel()" aria-hidden="true">&times;</button>
+        <h4 class="modal-title">
+          [% l('Enter the number of {{type.name()}} circulating') %]
+        </h4>
+      </div>
+      <div class="modal-body">
+        <div class="form-group">
+          <label for="noncat-count" class="sr-only">[% l('Count') %]</label>
+          <input type="number" class="form-control" focus-me='focusMe' required
+            id="noncat-title" ng-model="count" placeholder="[% l('Count...') %]"/>
+        </div>
+      </div>
+      <div class="modal-footer">
+        <input type="submit" class="btn btn-primary" 
+            ng-disabled="form.$invalid" value="[% l('OK') %]"/>
+        <button class="btn btn-warning" 
+          ng-click="cancel()">[% l('Cancel') %]</button>
+      </div>
+    </div> <!-- modal-content -->
+  </div> <!-- modal-dialog -->
+</form>
index fd09a2c..817b962 100644 (file)
           <span>{{now | date:'shortDate'}}</span>
         </div>
       </div>
+      <div ng-if="holdUser">
+        <br/>
+        <div>[% |l %]
+          Hold for patron {{holdUser.family_name()}}, 
+          {{holdUser.first_given_name()}} {{holdUser.second_given_name()}}
+          [% END %]
+        </div>
+        <div>
+          <span>[% l('Patron Barcode:') %]</span>
+          <span>{{holdUser.card().barcode()}}</span>
+        </div>
+        <br/>
+        <div>
+          <span>[% l('Request Date:') %]</span>
+          <span>{{evt.payload.hold.request_time() | date:'shortDate'}}</span>
+        </div>
+        <div>
+          <span>[% l('Slip Date:') %]</span>
+          <span>{{now | date:'shortDate'}}</span>
+        </div>
+      </div>
     </div>
     <div class="modal-footer">
       <input type="button" class="btn btn-primary"
index 29ccfac..00f6888 100644 (file)
@@ -967,7 +967,7 @@ function($scope , $q , $routeParams,  egCore , $modal , patronSvc) {
 
 
 /**
- * Manages edit
+ * Link to patron edit UI
  */
 .controller('PatronEditCtrl',
        ['$scope','$routeParams','egCore',
index dfde72a..20ac649 100644 (file)
@@ -5,29 +5,28 @@
 angular.module('egPatronApp').controller('PatronCheckoutCtrl',
 
        ['$scope','$q','$modal','$routeParams','egCore','egUser','patronSvc',
-        'egGridDataProvider','$location',
+        'egGridDataProvider','$location','egCirc',
 
 function($scope , $q , $modal , $routeParams , egCore , egUser , patronSvc , 
-         egGridDataProvider , $location) {
+         egGridDataProvider , $location , egCirc) {
 
     $scope.initTab('checkout', $routeParams.id);
     $scope.focusMe = true;
     $scope.checkouts = patronSvc.checkouts;
     $scope.checkoutArgs = {noncat_type : 'barcode'};
+    $scope.gridDataProvider = egGridDataProvider.instance({
+        get : function(offset, count) {
+            return this.arrayNotifier($scope.checkouts, offset, count);
+        }
+    });
 
-    // Grid Provider -------------------
-    var provider = egGridDataProvider.instance({});
-    provider.get = function(offset, count) {
-        return provider.arrayNotifier($scope.checkouts, offset, count);
-    }
-
-    function addCheckout(co) {
-        $scope.checkouts.push(co);
-        provider.refresh();
-    }
+    egCirc.get_circ_mods().then(function(list) {
+        $scope.circModifiers = list;
+    });
 
-    $scope.gridDataProvider = provider;
-    // -----------------------------
+    egCirc.get_noncat_types().then(function(list) {
+        $scope.nonCatTypes = list;
+    });
 
     $scope.selectedNcType = function() {
         if (!egCore.env.cnct) return null; // too soon
@@ -35,275 +34,83 @@ function($scope , $q , $modal , $routeParams , egCore , egUser , patronSvc ,
         return type ? type.name() : null;
     }
 
-    if (egCore.env.cnct) {
-        $scope.nonCatTypes = egCore.env.cnct.list;
-    } else {
-        egCore.pcrud.search('cnct', 
-            {owning_lib : egCore.org.fullPath(egCore.auth.user().ws_ou(), true)},
-            null, {atomic : true}
-        ).then(function(list) { 
-            egCore.env.absorbList(list, 'cnct');
-            $scope.nonCatTypes = list 
-        });
-    }
-
-    egCore.pcrud.retrieveAll('ccm', null, {atomic : true}).then(
-        function(list) { $scope.circModifiers = list });
-
-    // TODO: apply correct response order
     $scope.checkout = function(args) {
-        var type = args.type;
-        var coArgs = angular.copy(args);
-
-        if (coArgs.noncat_type == 'barcode') {
+        var params = angular.copy(args);
+        params.patron_id = patronSvc.current.id();
 
+        if (params.noncat_type == 'barcode') {
             if (!args.copy_barcode) return;
-            args.copy_barcode = ''; // reset UI
 
-            delete coArgs.noncat_type;
-            performCheckout(coArgs);
+            args.copy_barcode = ''; // reset UI input
+            params.noncat_type = ''; // "barcode"
+            send_checkout(params);
 
         } else {
-            console.debug('noncat..');
-            openNoncatDialog(coArgs);
+            egCirc.noncat_dialog(params).then(function() {
+                send_checkout(params)
+            });
         }
 
         $scope.focusMe; // return focus to barcode input
     }
 
-    var index = 0;
-    function performCheckout(args, override) {
-        console.debug('checkout: ' + js2JSON(args));
-
-        var method = 'open-ils.circ.checkout.full';
-        if (override) method += '.override';
-
-        args.patron_id = $scope.patron_id;
-
-        egCore.net.request(
-            'open-ils.circ', method, egCore.auth.token(), args
-        ).then(function(evt) {
-
-            if (!evt) { 
-                console.error('no checkout response received');
-                return;
-            }
-
-            // TODO: how best to handle multiple response events?
-            if (angular.isArray(evt)) evt = evt[0];
-            evt.id = index++;
-            evt.copy_barcode = args.copy_barcode;
-            handleCheckoutResponse(evt, args, override)
-        });
-    }
-
-    function handleCheckoutResponse(evt, args, override) {
-
-        if (evt.payload) {
-            if (args.precat) {
-                evt.payload.record = {
-                    title  : args.dummy_title,
-                    author : args.dummy_author,
-                    isbn   : args.dummy_isbn
-                };
-            } else if (args.noncat) {
-                evt.payload.record = {
-                    title : egCore.env.cnct.map[args.noncat_type].name()
-                };
-                evt.noncat_count = args.noncat_count;
-                evt.payload.circ = new egCore.idl.circ();
-                evt.payload.circ.due_date(evt.payload.noncat_circ.duedate());
-            }
-        }
-
-        console.debug('checkout: ' + JSON.stringify(evt, null, 2));
-
-        switch (evt.textcode) {
-            case 'SUCCESS':
-                // keep the global patron object in sync with reality
-                addCheckout(evt);
-                if (!args.noncat)
-                    patronSvc.patron_stats.checkouts.out++;
-                break;
-
-            case 'ITEM_NOT_CATALOGED':
-                openPrecatDialog(evt.copy_barcode);
-                break;
-
-            case 'PATRON_EXCEEDS_FINES':
-            case 'PATRON_EXCEEDS_CHECKOUT_COUNT':
-                if (!override) {
-                    if (patronSvc.checkout_overrides[evt.textcode]) {
-                        performCheckout(args, true);
-                    } else {
-                        openOverrideConfirmDialog(evt, args);
-                    }
-                }
-                break;
-
-            case 'OPEN_CIRCULATION_EXISTS':
-                openCircExistsDialog(args, evt);
-                break;
-
-            /* stuff to consider 
-            PERM_FAILURE
-            PATRON_EXCEEDS_OVERDUE_COUNT
-            PATRON_BARRED
-            CIRC_EXCEEDS_COPY_RANGE
-            PATRON_ACCOUNT_EXPIRED
-            ITEM_DEPOSIT_REQUIRED
-            ITEM_RENTAL_FEE_REQUIRED
-            ITEM_DEPOSIT_PAID
-            PATRON_EXCEEDS_LOST_COUNT
-            ACTION_CIRCULATION_NOT_FOUND
-            PATRON_EXCEEDS_CHECKOUT_COUNT
-            COPY_CIRC_NOT_ALLOWED
-            COPY_NOT_AVAILABLE
-            COPY_IS_REFERENCE
-            COPY_NEEDED_FOR_HOLD
-            MAX_RENEWALS_REACHED
-            CIRC_CLAIMS_RETURNED
-            COPY_ALERT_MESSAGE
-            PATRON_EXCEEDS_FINES
-            */
-
-            default:
-                console.warn('unhandled circ response : ' + evt.textcode);
-                // push it on the list so the user can at least see 
-                // something happened.
-                addCheckout(evt);
-        }
-    }
-
-    // define our modal dialogs
-
-    function openNoncatDialog(coArgs) {
-        coArgs.noncat = true;
-        var type = egCore.env.cnct.map[coArgs.noncat_type];
-
-        $modal.open({
-            templateUrl: './circ/patron/t_noncat_dialog',
-            controller: 
-                ['$scope', '$modalInstance',
-                function($scope, $modalInstance) {
-                $scope.focusMe = true;
-                $scope.type = type;
-                $scope.count = 1;
-                $scope.ok = function(count) { $modalInstance.close(count) }
-                $scope.cancel = function () { $modalInstance.dismiss() }
-            }],
-        }).result.then(
-            function(count) {
-                $scope.focusMe = true; // main barcode input
-                if (count) {
-                    // TODO: sanity check
-                    coArgs.noncat_count = count;
-                    performCheckout(coArgs);
-                }
-            }
-        );
-    }
-
-    function openCircExistsDialog(coArgs, evt) {
-        $modal.open({
-            templateUrl: './circ/patron/t_circ_exists_dialog',
-            controller: 
-                       ['$scope','$modalInstance','openCirc',
-                function($scope , $modalInstance , openCirc) {
-                $scope.circDate = openCirc.xact_start();
-                $scope.ok = function() { $modalInstance.close() }
-                $scope.cancel = function($event) { 
-                    $modalInstance.dismiss();
-                    $event.preventDefault(); // form: prevent ok() from firing
-                }
-            }],
-            resolve : {
-                openCirc : function() {
-                    return egCore.pcrud.search('circ', 
-                        {target_copy : evt.payload.copy.id()},
-                        {order_by : {circ : 'xact_start desc' }, limit : 1}
-                    );
-                }
-            }
-        }).result.then(
-            function() {
-                egCore.net.request(
-                    'open-ils.circ', 
-                    'open-ils.circ.checkin',
-                    egCore.auth.token(), 
-                    {barcode :coArgs.copy_barcode, noop : true}
-
-                ).then(function(resp) {
-
-                    if (evt = egCore.evt.parse(resp)) {
-                        if (evt.textcode == 'SUCCESS') {
-                            performCheckout(coArgs);
-                        } else {
-                           alert(evt); // FIXME 
-                        }
-                    }
-                })
-            }
-        );
-    }
-
-
-    function openPrecatDialog(copy_barcode) {
-        $modal.open({
-            templateUrl: './circ/patron/t_precat_dialog',
-            controller: 
-                ['$scope', '$modalInstance', 'circMods',
-                function($scope, $modalInstance, circMods) {
-                $scope.focusMe = true;
-                $scope.precatArgs = {
-                    copy_barcode : copy_barcode,
-                    circ_modifier : circMods.length ? circMods[0].code() : null
-                };
-                $scope.circModifiers = circMods;
-                $scope.ok = function(args) { $modalInstance.close(args) }
-                $scope.cancel = function () { $modalInstance.dismiss() }
-            }],
-            // pass the circ mod list into the modal environment
-            // the angular way. 
-            resolve : {
-                circMods : function() { return $scope.circModifiers }
-            }
-        }).result.then(
-            function(args) {
-                $scope.focusMe = true; // main barcode input
-                if (!args || !args.dummy_title) return;
-                args.precat = true;
-                performCheckout(args);
+    function send_checkout(params) {
+
+        params.noncat_type = params.noncat ? params.noncat_type : '';
+
+        // populate the grid row before we send the request so that the
+        // order of actions is maintained and so the user gets an 
+        // immediate reaction to their barcode input action.
+        var row_item = {
+            index : $scope.checkouts.length,
+            copy_barcode : params.copy_barcode,
+            noncat_type : params.noncat_type
+        };
+
+        $scope.checkouts.unshift(row_item);
+        $scope.gridDataProvider.refresh();
+
+        egCirc.checkout(params).then(
+            function(co_resp) {
+                // update stats locally so we don't have to fetch them w/
+                // each checkout.
+                patronSvc.patron_stats.checkouts.out++
+    
+                munge_checkout_resp(co_resp);
+    
+                // copy the response event into the original grid row item
+                angular.copy(co_resp.evt, row_item);
             },
             function() {
-                // dialog was closed without action
-                $scope.focusMe = true;
+                // Circ was rejected somewhere along the way.
+                // Remove the copy from the grid since there was no action.
+                $scope.checkouts.splice(row_item.index, 1);
+                $scope.gridDataProvider.refresh();
             }
         );
     }
 
-    function openOverrideConfirmDialog(evt, args) {
-        $modal.open({
-            templateUrl: './circ/patron/t_event_override_dialog',
-            controller: 
-                ['$scope', '$modalInstance', 
-                function($scope, $modalInstance) {
-                $scope.evt = evt;
-                $scope.ok = function() { $modalInstance.close() }
-                $scope.cancel = function () { $modalInstance.dismiss() }
-            }]
-        }).result.then(
-            function() {
-                $scope.focusMe = true; // main barcode input
-                patronSvc.checkout_overrides[evt.textcode] = true;
-                performCheckout(args, true);
-            },
-            function() {
-                // dialog was closed without action
-                $scope.focusMe = true;
-            }
-        );
+    // move some stuff around so it will play nice w/ the template
+    function munge_checkout_resp(co_resp) {
+        var payload = co_resp.evt.payload;
+        var params = co_resp.params;
+
+        if (!payload) return;
+
+        if (params.precat) {
+            payload.record = {
+                title  : params.dummy_title,
+                author : params.dummy_author,
+                isbn   : params.dummy_isbn
+            };
+        } else if (params.noncat) {
+            payload.record = {
+                title : egCore.env.cnct.map[params.noncat_type].name()
+            };
+            co_resp.evt.noncat_count = params.noncat_count;
+            payload.circ = new egCore.idl.circ();
+            payload.circ.due_date(payload.noncat_circ.duedate());
+        }
     }
-
 }])
 
index 4270da7..2fd18a7 100644 (file)
@@ -37,7 +37,7 @@ function($modal , $q , egCore , egAlertDialog , egConfirmDialog) {
         ).then(function(evt) {
 
             if (angular.isArray(evt)) evt = evt[0];
-            return service.handle_checkout_resp(evt, args, override);
+            return service.handle_checkout_resp(evt, params, options);
         });
     }
 
@@ -59,7 +59,7 @@ function($modal , $q , egCore , egAlertDialog , egConfirmDialog) {
         ).then(function(evt) {
 
             if (angular.isArray(evt)) evt = evt[0];
-            return service.handle_checkout_resp(evt, args, options);
+            return service.handle_checkout_resp(evt, params, options);
         });
     }
 
@@ -148,19 +148,34 @@ function($modal , $q , egCore , egAlertDialog , egConfirmDialog) {
         }
     }
 
-    // fetch the list of circ modifiers, from cache if available
+    // returns a promise resolved with the list of circ mods
     service.get_circ_mods = function() {
-        if (egCore.env.ccm) {
+        if (egCore.env.ccm) 
             return $q.when(egCore.env.ccm.list);
-        } else {
-            return egCore.pcrud.retrieveAll('ccm', null, {atomic : true})
-            .then(function(list) { 
-                egCore.env.absorbList(list, 'ccm');
-                return list;
-            });
-        }
+
+        return egCore.pcrud.retrieveAll('ccm', null, {atomic : true})
+        .then(function(list) { 
+            egCore.env.absorbList(list, 'ccm');
+            return list;
+        });
     };
 
+    // returns a promise resolved with the list of noncat types
+    service.get_noncat_types = function() {
+        if (egCore.env.cnct) 
+            return $q.when(egCore.env.cnct.list);
+
+        return egCore.pcrud.search('cnct', 
+            {owning_lib : 
+                egCore.org.fullPath(egCore.auth.user().ws_ou(), true)}, 
+            null, {atomic : true}
+        ).then(function(list) { 
+            egCore.env.absorbList(list, 'cnct');
+            return list;
+        });
+    }
+
+
     // fetch/cache for org unit addresses
     service.get_org_addr = function(org_id, addr_type) {
         if (service.org_addr_cache[org_id]) {
@@ -187,7 +202,10 @@ function($modal , $q , egCore , egAlertDialog , egConfirmDialog) {
                 function($scope, $modalInstance) {
                 $scope.evt = evt;
                 $scope.ok = function() { $modalInstance.close() }
-                $scope.cancel = function () { $modalInstance.dismiss() }
+                $scope.cancel = function ($event) { 
+                    $modalInstance.dismiss();
+                    $event.preventDefault();
+                }
             }]
         }).result.then(
             function() {
@@ -198,8 +216,47 @@ function($modal , $q , egCore , egAlertDialog , egConfirmDialog) {
         );
     }
 
+    // Opens a dialog allowing the user to fill in the desired non-cat count.
+    // Unlike other dialogs, which kickoff circ actions internally
+    // as a result of events, this dialog does not kick off any circ
+    // actions. It just collects the count and and resolves the promise.
+    //
+    // This assumes the caller has already handled the noncat-type
+    // selection and just needs to collect the count info.
+    service.noncat_dialog = function(params, options) {
+        
+        // the caller should presumably have fetched the noncat_types via
+        // our API already, but fetch them again (from cache) to be safe.
+        return service.get_noncat_types().then(function() {
+
+            params.noncat = true;
+            var type = egCore.env.cnct.map[params.noncat_type];
+
+            return $modal.open({
+                templateUrl: './circ/share/t_noncat_dialog',
+                controller: 
+                    ['$scope', '$modalInstance',
+                    function($scope, $modalInstance) {
+                    $scope.focusMe = true;
+                    $scope.type = type;
+                    $scope.count = 1;
+                    $scope.ok = function(count) { $modalInstance.close(count) }
+                    $scope.cancel = function () { $modalInstance.dismiss() }
+                }],
+            }).result.then(
+                function(count) {
+                    if (count && count > 0 /* && count < x (TODO) */) {
+                        params.noncat_count = count;
+                        return $q.when(params);
+                    } else {
+                        return $q.reject();
+                    }
+                }
+            );
+        });
+    }
 
-    // opens a dialog allowing the user to fill in pre-cat copy info
+    // Opens a dialog allowing the user to fill in pre-cat copy info.
     service.precat_dialog = function(params, options) {
 
         return $modal.open({
@@ -232,14 +289,17 @@ function($modal , $q , egCore , egAlertDialog , egConfirmDialog) {
     }
 
     service.circ_exists_dialog = function(evt, params, options) {
-        $modal.open({
+        return $modal.open({
             templateUrl: './circ/share/t_circ_exists_dialog',
             controller: 
                        ['$scope','$modalInstance','openCirc',
                 function($scope , $modalInstance , openCirc) {
                 $scope.circDate = openCirc.xact_start();
                 $scope.ok = function() { $modalInstance.close() }
-                $scope.cancel = function() { $modalInstance.dismiss() }
+                $scope.cancel = function($event) { 
+                    $modalInstance.dismiss();
+                    $event.preventDefault(); // form, avoid calling ok();
+                }
             }],
             resolve : {
                 // fetch the conflicting open circulation
index e7553a2..08da5c7 100644 (file)
@@ -27,21 +27,6 @@ angular.module('egGridMod',
             idField : '@',
 
             // Reference to externally provided egGridDataProvider
-            // BEWARE: the grid removes everything from its scope that
-            // is not needed within the template.  "=" sets up a two-way
-            // binding between the grid and the calling scope.  After
-            // grid initiation, the itemsProvider attribute within the 
-            // shared scope space will be set to undefined.  
-            //
-            // In other words:
-            //
-            // template   => items-provider="myProvider"
-            //
-            // controller => $scope.myProvider === undefined
-            //
-            // Storing the provider in the local scope just uses 
-            // resources, anyway.
-            //
             itemsProvider : '=',
 
             // comma-separated list of supported or disabled grid features
@@ -122,7 +107,6 @@ angular.module('egGridMod',
                 delete $scope.idField;
 
                 grid.dataProvider = $scope.itemsProvider;
-                delete $scope.itemsProvider;
 
                 var features = ($scope.features) ? 
                     $scope.features.split(',') : [];