'Ag-Grid: How to save and reload column order
Using Ag-Grid, users can drag columns to order them the way they like. I need to allow the user to save their column order (to an SQL backend) so that it becomes the default column order for them. I was trying to get the column names like this:
var cols = schedGridOptions.columnApi.getAllColumns();
for (col in cols) {
var colDef = col.getColDef();
console.log(colDef.headerName);
}
This was an example I found for setting the header name, so I tried to adapt it to getting the header name. But I get this error:
JavaScript runtime error: Object doesn't support property or method 'getColDef'
Perhaps I'm not doing this correctly? I'm fairly new at using Ag-Grid. Looking for suggestions.
Solution 1:[1]
You are looking for setColumnState() and getColumnState(). See the docs at https://www.ag-grid.com/javascript-grid-column-api/
In your grid options, set up event handlers for gridReady and columnMoved. https://www.ag-grid.com/javascript-grid-events/
Something like:
gridOptions = {
rowData: myRowDataSource,
columnDefs: myColumns,
onGridReady: onGridReady,
onColumnMoved: onColumnMoved,
}
On the column moved event, save the columnState. Here's an example saved to local storage. Change it to save to your database.
onColumnMoved(params) {
var columnState = JSON.stringify(params.columnApi.getColumnState());
localStorage.setItem('myColumnState', columnState);
}
On the grid ready event, get and restore the grid State. Again, change this to pull from your database.
onGridReady(params) {
var columnState = JSON.parse(localStorage.getItem('myColumnState'));
if (columnState) {
params.columnApi.setColumnState(columnState);
}
}
Solution 2:[2]
onColumnMoved
will fire every time the column is moving but the drag didn't stopped.
Using onColumnMoved
is not performant at all.
If you care about performance you should use onDragStopped
gridOptions.onDragStopped = function (params) {
const colIds = params.columnApi.getAllDisplayedColumns().map(col => col.colId)
console.log(colIds) // all visible colIds with the visible order
}
Solution 3:[3]
My answer is a small improvement of @roli's answer. The event will only be fired if the column order has been changed after the operation. If the user drags and decides to stop and drops the column at the same index as before, the event will not be fired.
The code below is the implementation in react
. The idea is simple: Store the column order as a list of colId when the drag started and compare it to the final column order when the drag stopped. The event will only be fired when there is a different between the 2 order.
function useDragColumnChange(cb: (e: DragStoppedEvent) => void) {
const columnOrderRef = React.useRef<string[]>([])
const onDragStarted = (e: DragStartedEvent) => {
columnOrderRef.current = e.columnApi.getColumnState().map(c => c.colId);
}
const onDragStopped = (e: DragStoppedEvent) => {
const newColumnOrder = e.columnApi.getColumnState().map(c => c.colId);
const sameOrder = columnOrderRef.current.every(
(c, i) => c === newColumnOrder[i]
);
if (!sameOrder) {
cb(e);
}
}
return { onDragStarted, onDragStopped };
}
Usage
// in render()
const { onDragStarted, onDragStopped } = useDragColumnChange(e => console.log('Saving new column order!'))
return (
<AgGridReact
...
onDragStarted={onDragStarted}
onDragStopped={onDragStopped}
/>
);
Live Demo
Solution 4:[4]
- Hi the below code worked for me. Working Stackblitz Repo. https://stackblitz.com/edit/angular-ivy-eyhjfn
gridOptions: GridOptions ={
onDragStopped:(
event: DragStoppedEvent
) => this.test(event)
}
test(params){
let columnDragState = params.columnApi.getColumnState();
console.log(columnDragState, "columnDragState")
const colIds = params.columnApi.getAllDisplayedColumns().map(e=>{
return e.colDef
});
console.log(colIds)
let arr3 = colIds.map((item, i) => Object.assign({}, item, columnDragState[i]));
console.log(arr3)
}
<ag-grid-angular
style="width: 1500px; height: 750px; padding-top: 10px;"
class="ag-theme-alpine"
[columnDefs]="columnDefs"
(gridReady)="onGridReady($event)"
[rowDragManaged]="true"
[gridOptions]="gridOptions"
[rowData]="rowData"
>
</ag-grid-angular>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Alien Technology |
Solution 2 | Roland |
Solution 3 | |
Solution 4 |