var ngSelectionProvider = function (grid, $scope, $parse) { var self = this; self.multi = grid.config.multiSelect; self.selectedItems = grid.config.selectedItems; self.selectedIndex = grid.config.selectedIndex; self.lastClickedRow = undefined; self.ignoreSelectedItemChanges = false; // flag to prevent circular event loops keeping single-select var in sync self.pKeyParser = $parse(grid.config.primaryKey); // function to manage the selection action of a data item (entity) self.ChangeSelection = function (rowItem, evt) { // ctrl-click + shift-click multi-selections if (evt && !evt.ctrlKey && !evt.shiftKey && evt.originalEvent.constructor.name == "MouseEvent") { self.toggleSelectAll(false, true); } if (evt && evt.shiftKey && !evt.keyCode && self.multi && grid.config.enableRowSelection) { if (self.lastClickedRow) { var rowsArr; if ($scope.configGroups.length > 0) { rowsArr = grid.rowFactory.parsedData.filter(function(row) { return !row.isAggRow; }); } else { rowsArr = grid.filteredRows; } var thisIndx = rowItem.rowIndex; var prevIndx = self.lastClickedRow.rowIndex; self.lastClickedRow = rowItem; if (thisIndx == prevIndx) { return false; } if (thisIndx < prevIndx) { thisIndx = thisIndx ^ prevIndx; prevIndx = thisIndx ^ prevIndx; thisIndx = thisIndx ^ prevIndx; thisIndx--; } else { prevIndx++; } var rows = []; for (; prevIndx <= thisIndx; prevIndx++) { rows.push(rowsArr[prevIndx]); } if (rows[rows.length - 1].beforeSelectionChange(rows, evt)) { for (var i = 0; i < rows.length; i++) { var ri = rows[i]; var selectionState = ri.selected; ri.selected = !selectionState; if (ri.clone) { ri.clone.selected = ri.selected; } var index = self.selectedItems.indexOf(ri.entity); if (index === -1) { self.selectedItems.push(ri.entity); } else { self.selectedItems.splice(index, 1); } } rows[rows.length - 1].afterSelectionChange(rows, evt); } return true; } } else if (!self.multi) { if (self.lastClickedRow == rowItem) { self.setSelection(self.lastClickedRow, grid.config.keepLastSelected ? true : !rowItem.selected); } else { if (self.lastClickedRow) { self.setSelection(self.lastClickedRow, false); } self.setSelection(rowItem, !rowItem.selected); } } else if (!evt.keyCode) { self.setSelection(rowItem, !rowItem.selected); } self.lastClickedRow = rowItem; return true; }; self.getSelection = function (entity) { var isSelected = false; if (grid.config.primaryKey) { var val = self.pKeyParser(entity); angular.forEach(self.selectedItems, function (c) { if (val == self.pkeyParser(c)) { isSelected = true; } }); } else { isSelected = self.selectedItems.indexOf(entity) !== -1; } return isSelected; }; // just call this func and hand it the rowItem you want to select (or de-select) self.setSelection = function (rowItem, isSelected) { if(grid.config.enableRowSelection){ rowItem.selected = isSelected; if (rowItem.clone) { rowItem.clone.selected = isSelected; } if (!isSelected) { var indx = self.selectedItems.indexOf(rowItem.entity); if(indx != -1){ self.selectedItems.splice(indx, 1); } } else { if (self.selectedItems.indexOf(rowItem.entity) === -1) { if(!self.multi && self.selectedItems.length > 0){ self.toggleSelectAll(false, true); rowItem.selected = isSelected; if (rowItem.clone) { rowItem.clone.selected = isSelected; } } self.selectedItems.push(rowItem.entity); } } rowItem.afterSelectionChange(rowItem); } }; // @return - boolean indicating if all items are selected or not // @val - boolean indicating whether to select all/de-select all self.toggleSelectAll = function (checkAll, bypass) { if (bypass || grid.config.beforeSelectionChange(grid.filteredRows)) { var selectedlength = self.selectedItems.length; if (selectedlength > 0) { self.selectedItems.length = 0; } for (var i = 0; i < grid.filteredRows.length; i++) { grid.filteredRows[i].selected = checkAll; if (grid.filteredRows[i].clone) { grid.filteredRows[i].clone.selected = checkAll; } if (checkAll) { self.selectedItems.push(grid.filteredRows[i].entity); } } if (!bypass) { grid.config.afterSelectionChange(grid.filteredRows); } } }; };