LP1904036 Grid rowSelectionChange Output
authorBill Erickson <berickxx@gmail.com>
Thu, 13 Aug 2020 15:44:34 +0000 (11:44 -0400)
committerGalen Charlton <gmc@equinoxOLI.org>
Fri, 28 Oct 2022 00:13:22 +0000 (20:13 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Signed-off-by: Jane Sandberg <js7389@princeton.edu>
Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
Open-ILS/src/eg2/src/app/share/grid/grid-body.component.html
Open-ILS/src/eg2/src/app/share/grid/grid.component.ts
Open-ILS/src/eg2/src/app/share/grid/grid.ts

index 8cf795f..55c7fef 100644 (file)
@@ -14,7 +14,9 @@
 
     <ng-container *ngIf="!context.disableSelect">
       <div class="eg-grid-cell eg-grid-checkbox-cell eg-grid-cell-skinny">
-        <input type='checkbox' [(ngModel)]="context.rowSelector.indexes[context.getRowIndex(row)]"
+        <input type='checkbox' 
+          [ngModel]="context.rowSelector.indexes[context.getRowIndex(row)]"
+          (ngModelChange)="context.rowSelector.toggle(context.getRowIndex(row))"
           i18n-aria-label="e.g. Row 13" attr.aria-label="Row {{context.pager.rowNumber(idx)}}"
           #rowContextMenu="ngbPopover"
           popoverTitle="Actions for Selected Rows" i18n-popoverTitle
index 23d4261..dc8ac87 100644 (file)
@@ -127,6 +127,9 @@ export class GridComponent implements OnInit, AfterViewInit, OnDestroy {
     @Output() onRowActivate: EventEmitter<any>;
     @Output() onRowClick: EventEmitter<any>;
 
+    // Emits an array of grid row indexes on any row selection change.
+    @Output() rowSelectionChange: EventEmitter<string[]>;
+
     @ViewChild('toolbar', { static: true }) toolbar: GridToolbarComponent;
 
     constructor(
@@ -139,6 +142,7 @@ export class GridComponent implements OnInit, AfterViewInit, OnDestroy {
             new GridContext(this.idl, this.org, this.store, this.format);
         this.onRowActivate = new EventEmitter<any>();
         this.onRowClick = new EventEmitter<any>();
+        this.rowSelectionChange = new EventEmitter<string[]>();
     }
 
     ngOnInit() {
@@ -204,6 +208,10 @@ export class GridComponent implements OnInit, AfterViewInit, OnDestroy {
                 return '';
             };
 
+        this.context.rowSelector.selectionChange.subscribe(
+            keys => this.rowSelectionChange.emit(keys)
+        );
+
         if (this.showLinkSelectors) {
             console.debug(
                 'showLinkSelectors is deprecated and no longer has any effect');
@@ -217,6 +225,7 @@ export class GridComponent implements OnInit, AfterViewInit, OnDestroy {
     }
 
     ngOnDestroy() {
+        this.context.rowSelector.selectionChange.unsubscribe();
         this.context.destroy();
     }
 
index 6f7191e..3c46df8 100644 (file)
@@ -430,6 +430,13 @@ export interface GridCellTextGenerator {
 export class GridRowSelector {
     indexes: {[string: string]: boolean};
 
+    // Track these so we can emit the selectionChange event
+    // only when the selection actually changes.
+    previousSelection: string[] = [];
+
+    // Emits the selected indexes on selection change
+    selectionChange: EventEmitter<string[]> = new EventEmitter<string[]>();
+
     constructor() {
         this.clear();
     }
@@ -445,25 +452,40 @@ export class GridRowSelector {
         return true;
     }
 
+    emitChange() {
+        const keys = this.selected();
+
+        if (keys.length === this.previousSelection.length &&
+            this.contains(this.previousSelection)) {
+            return; // No change has occurred
+        }
+
+        this.previousSelection = keys;
+        this.selectionChange.emit(keys);
+    }
+
     select(index: string | string[]) {
         const indexes = [].concat(index);
         indexes.forEach(i => this.indexes[i] = true);
+        this.emitChange();
     }
 
     deselect(index: string | string[]) {
         const indexes = [].concat(index);
         indexes.forEach(i => delete this.indexes[i]);
+        this.emitChange();
+    }
+
+    toggle(index: string) {
+        if (this.indexes[index]) {
+            this.deselect(index);
+        } else {
+            this.select(index);
+        }
     }
 
-    // Returns the list of selected index values.
-    // In some contexts (template checkboxes) the value for an index is
-    // set to false to deselect instead of having it removed (via deselect()).
-    // NOTE GridRowSelector has no knowledge of when a row is no longer
-    // present in the grid.  Use GridContext.getSelectedRows() to get
-    // list of selected rows that are still present in the grid.
-    selected() {
-        return Object.keys(this.indexes).filter(
-            ind => Boolean(this.indexes[ind]));
+    selected(): string[] {
+        return Object.keys(this.indexes);
     }
 
     isEmpty(): boolean {
@@ -472,6 +494,7 @@ export class GridRowSelector {
 
     clear() {
         this.indexes = {};
+        this.emitChange();
     }
 }