Skip to content

Instantly share code, notes, and snippets.

@nite
Last active August 15, 2018 16:47
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nite/dea82d184411a51fc6bc6adc7edaa422 to your computer and use it in GitHub Desktop.
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.
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;
}
}
@nite
Copy link
Author

nite commented Feb 15, 2018

grid config:

enableRangeSelection: true,
rowSelection: 'multiple',
suppressCellSelection: false,

@AjitkSa
Copy link

AjitkSa commented Aug 15, 2018

Is there any instruction how to configure in angular 5?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment