If I understand you correctly you want to have the following behaviour for resizing - make sure each column has it's content visible first, but then also make sure that the whole grid width is filled at the least.
Unfortunately there doesn't seem to be a really straightforward way to achieve that. What I did is onGridReady
, I would use the autoSizeColumns
function to make sure that each column's content is fully visible, and then if there is an additional space left to fill the grid's width I distribute it evenly to each column. Then apply the new column state through gridApi.applyColumnState
. Here is an example in vue
that should be fairly easy to transfer to other frameworks (or vanilla js).
interface UseGridColumnResizeOptions {
// we need access to the grid container so we can calculate
// the space that is left unfilled.
gridContainerRef: Ref<null | HTMLElement>;
// for any columns that you don't want to resize for whatever reason
skipResizeColumnIds: string[];
}
export const useGridColumnResize = ({ gridContainerRef, skipResizeColumnIds }: UseGridColumnResizeOptions) => {
const handleResize = ({ columnApi }: AgGridEvent) => {
columnApi.autoSizeAllColumns();
if (!gridContainerRef.value) {
console.warn('Unable to resize columns, gridContainer ref is not provided');
return;
}
const isColumnResizable = (colDef: ColDef) => colDef.resizable && !skipResizeColumnIds.includes(colDef.colId!);
const columns = columnApi.getAllGridColumns().filter((column) => isColumnResizable(column.getColDef()));
if (columns.length === 0) {
return;
}
const lastColumn = columns[columns.length - 1];
const lastColumnLeft = lastColumn.getLeft();
const lastColumnWidth = lastColumn.getActualWidth();
const { width: gridWidth } = gridContainerRef.value.getBoundingClientRect();
const gridSpaceLeftToFill = Math.max(0, gridWidth - (lastColumnLeft! + lastColumnWidth));
if (gridSpaceLeftToFill === 0) {
return;
}
const additionalSpaceForEachColumn = gridSpaceLeftToFill / columns.length;
const columnState = columnApi.getColumnState();
columnState.forEach((column) => {
const skipResizeForColumn = !columns.some((col) => col.getColId() === column.colId);
if (skipResizeForColumn) {
return;
}
column.width = column.width! + additionalSpaceForEachColumn;
});
columnApi.applyColumnState({ state: columnState });
};
return { handleResize };
};
You can plug the handleResize
function on row-data-updated
event to resize columns whenever new data arrives in the grid or only once in grid-ready
or first-data-rendered
.
Keep in mind that this implementation plays out well in my case as columns are not movable. I am expecting the last column inside the columns array to be the last visible one in the UI, but that might not always be the case and you might end up with wrong calculation of the space that is left to fill. So you might need to change the way the last visible column in the UI is retrieved to make it work for your case.