staff web: grid shift-click
authorBill Erickson <berick@esilibrary.com>
Thu, 27 Mar 2014 22:03:46 +0000 (18:03 -0400)
committerBill Erickson <berick@esilibrary.com>
Thu, 27 Mar 2014 22:03:46 +0000 (18:03 -0400)
Signed-off-by: Bill Erickson <berick@esilibrary.com>
Open-ILS/web/js/ui/default/staff/services/grid.js
Open-ILS/web/js/ui/default/staff/services/list.js

index 16b7d22..adc655c 100644 (file)
@@ -310,10 +310,42 @@ angular.module('egGridMod', ['egCoreMod', 'egListMod', 'egUiMod', 'ui.bootstrap'
 
             $scope.handleRowClick = function($event, item) {
                 var index = $scope.list.indexValue(item);
+
                 if ($event.ctrlKey || $event.metaKey /* mac command */) {
-                    $scope.list.toggleOneSelection(index);
+                    // control-click
+                    if ($scope.list.toggleOneSelection(index)) 
+                        self.lastSelectedRowIndex = index;
+
+                } else if ($event.shiftKey) { 
+                    // shift-click
+                    if (!self.lastSelectedRowIndex) {
+                        // no source row, just do a simple select
+                        $scope.list.selectOne(index);
+                        self.lastSelectedRowIndex = index;
+                        return;
+                    }
+
+                    var selecting = false;
+                    var ascending = 
+                        $scope.list.comesBefore(self.lastSelectedRowIndex, item);
+                    var startPos = 
+                        $scope.list.indexOf(self.lastSelectedRowIndex);
+
+                    // update to new last-selected
+                    self.lastSelectedRowIndex = index;
+
+                    while (true) {
+                        startPos += ascending ? 1 : -1;
+                        var curItem = $scope.list.items[startPos];
+                        if (!curItem) break;
+                        var curIdx = $scope.list.indexValue(curItem);
+                        $scope.list.selected[curIdx] = true;
+                        if (curIdx == index) break; // all done
+                    }
+                        
                 } else {
                     $scope.list.selectOne(index);
+                    self.lastSelectedRowIndex = index;
                 }
             }
 
index 6181db6..f100f6f 100644 (file)
@@ -52,6 +52,8 @@ angular.module('egListMod', ['egCoreMod'])
 
         this.indexValue = function(item) {
             if (!item) return null;
+            // assumes non-object's are bare indexes
+            if (typeof item != 'object') return item;
             if (this.indexFieldAsFunction) {
                 return item[this.indexField]();
             } else {
@@ -59,6 +61,32 @@ angular.module('egListMod', ['egCoreMod'])
             }
         }
 
+        // returns true if item1 appears in the list before item2;
+        // false otherwise.  this is slightly more efficient that
+        // finding the position of each then comparing them.
+        // item1 / item2 may be an item or an item index
+        this.comesBefore = function(itemOrIndex1, itemOrIndex2) {
+            var idx1 = this.indexValue(itemOrIndex1);
+            var idx2 = this.indexValue(itemOrIndex2);
+
+            // use for() for early exit
+            for (var i = 0; i < this.items.length; i++) {
+                var idx = this.indexValue(this.items[i]);
+                if (idx == idx1) return true;
+                if (idx == idx2) return false;
+            }
+            return false;
+        }
+
+        this.indexOf = function(item) {
+            var idx = this.indexValue(item);
+            for (var i = 0; i < this.items.length; i++) {
+                if (this.indexValue(this.items[i]) == idx)
+                    return i;
+            }
+            return -1;
+        }
+
         // returns item objects
         this.selectedItems = function() {
             var items = [];
@@ -124,11 +152,13 @@ angular.module('egListMod', ['egCoreMod'])
         }
 
         // selects or deselects a row, without affecting the others
+        // returns true if the row is selected; false if de-selected.
         this.toggleOneSelection = function(index) {
             if (this.selected[index]) {
                 delete this.selected[index];
+                return false;
             } else {
-                this.selected[index] = true;
+                return this.selected[index] = true;
             }
         }