Last active
August 15, 2018 16:47
-
-
Save nite/dea82d184411a51fc6bc6adc7edaa422 to your computer and use it in GitHub Desktop.
Typescript ag-Grid Range selection directive which selects & highlights rows for any selected cell & emits a 'rangeSelectionRowsChanged' with a rows property of selected rows.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {Directive, EventEmitter, Output} from '@angular/core'; | |
import {AgGridNg2} from 'ag-grid-angular'; | |
import {GridApi} from 'ag-grid'; | |
/*** | |
* Range selection directive which selects & highlights rows for any selected cell | |
* (ctrl+click for multiple ranges) and emits a 'rangeSelectionRowsChanged' with a | |
* rows property of selected rows. | |
* | |
* NOTE: this only currently supports client-side grids. | |
*/ | |
@Directive({ | |
selector: '[gridRangeRowSelection]', | |
}) | |
export class AgGridSelectionDirective { | |
@Output('gridRangeRowSelection') onChangeEvent = new EventEmitter(); | |
constructor(grid: AgGridNg2) { | |
grid.rangeSelectionChanged.subscribe(event => { | |
const api: GridApi = event.api; | |
// deselect previous rows | |
this.clearPreviousSelections(api); | |
const selectedRows = this.getSelectedRows(api); | |
this.onChangeEvent.emit({rows: selectedRows}); | |
}); | |
} | |
public getSelectedRows(api: GridApi) { | |
// get all range selections (ctrl+click/drag for multiple selections) | |
const rangeSelections = api.getRangeSelections(); | |
const selectedRows = rangeSelections ? rangeSelections | |
.map(rangeSelection => { | |
let start = rangeSelection.start.rowIndex; | |
let end = rangeSelection.end.rowIndex; | |
if (start > end) { | |
[start, end] = [end, start]; | |
} | |
// Equivalent of _.range(startRowIndex, endRowIndex).map(api.getDisplayedRowAtIndex) | |
const selectedRowsInRange = []; | |
for (let index = start; index <= end; index++) { | |
const selectedRow = api.getDisplayedRowAtIndex(index); | |
if (selectedRow) { | |
selectedRowsInRange.push(selectedRow); | |
} | |
} | |
return selectedRowsInRange; | |
}).reduce((a, b) => a.concat(b), []) : []; | |
// Unique selectedRows - as we can have multiple range selections, they may overlap rows. | |
const selectedRowSet = Array.from(new Set(selectedRows)); | |
const selectedRowData = selectedRowSet.map(row => { | |
// note we cant use row.setSelected(true), as this will override copy to clipboard | |
// for cells to the whole row. | |
row.selected = true; | |
return row.data; | |
}); | |
// update all newly selected and previously unselected rows | |
api.updateRowData({update: selectedRowData}); | |
return selectedRowData; | |
} | |
private clearPreviousSelections(api: GridApi) { | |
// note this is side-effecting selection so we only do 1 pass. | |
const previousSelected = api['rowModel'].rowsToDisplay | |
.filter(row => row.selected) | |
.map(row => { | |
row.selected = false; | |
return row.data; | |
}); | |
api.updateRowData({update: previousSelected}); | |
return previousSelected; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Is there any instruction how to configure in angular 5?