Column panel, toolbar, and saved views
The column panel manages visibility, pinning, and order; the toolbar surfaces grouping, sorting, quick filter, views, and export as opt-in sections; saved views capture the whole layout under application-owned persistence.
- React
- Angular
- Core TypeScript
const [views, setViews] = useState<SavedGridView[]>(loadViews);
<Grid
rowData={rows}
columnDefs={columns}
columnPanel={{ trigger: "toolbar" }}
toolbar={{ grouping: true, sorting: true, quickFilter: true, views: true, export: true }}
savedViews={{
views,
onChange: (next) => {
setViews(next);
localStorage.setItem("grid-views", JSON.stringify(next));
},
}}
/>
views: SavedGridView[] = loadViews();
<awb-grid
[rowData]="rows"
[columnDefs]="columns"
[columnPanel]="{ trigger: 'toolbar' }"
[toolbar]="{ grouping: true, sorting: true, quickFilter: true, views: true, export: true }"
[savedViews]="{ views, onChange: persistViews }"
/>
persistViews = (next: SavedGridView[]) => {
this.views = next;
localStorage.setItem("grid-views", JSON.stringify(next));
};
const core = new GridCore(measurer, {
columnDefs,
columnPanel: { trigger: "toolbar", width: 320 },
toolbar: { grouping: true, sorting: true, quickFilter: true, views: true, export: true },
savedViews: {
views: loadViews(),
onChange: (next) => localStorage.setItem("grid-views", JSON.stringify(next)),
},
});
// Or capture/apply view state directly:
const state = api.captureViewState();
api.applyViewState(state, { columns: "merge" });
Column panel
const options = {
columnPanel: {
trigger: "rail",
defaultOpen: false,
width: 320,
},
} satisfies GridOptions;
Change trigger to "header", "menu", "footer", or "toolbar". The
drawer provides search, show/hide, pinning, pointer/keyboard ordering, bulk
visibility, nested groups, and reset. Opt a column out with
suppressColumnPanel: true.
Set availability: "pivot" to mount the panel only while pivot mode is on.
Since a pivoted panel is the pivot setup and nothing else, this gives an app
that manages columns its own way the grid's pivot customizer without the column
management drawer:
const options = {
columnPanel: { availability: "pivot" },
} satisfies GridOptions;
Columns with pivot roles (row group, pivot column, aggregate) show removable role chips under their rows, and while pivot mode is on the panel becomes the pivot setup: the column list gives way to three ordered, drag-reorderable role wells.
Toolbar sections
const options = {
toolbar: {
grouping: true,
sorting: true,
quickFilter: true,
views: true,
export: true,
},
columnPanel: { trigger: "toolbar" },
} satisfies GridOptions;
Every section is independently opt-in. The toolbar observes the grid container and automatically collapses labels and moves secondary commands into an overflow menu as space shrinks — resize the demo's window to see it adapt.
Application-owned saved views
let views: SavedGridView[] = loadViews();
let activeViewId: string | null = null;
const options = {
toolbar: { views: true },
savedViews: {
views,
activeViewId,
onChange: (nextViews) => {
views = nextViews;
localStorage.setItem("grid-views", JSON.stringify(nextViews));
},
onActiveViewChange: (id) => {
activeViewId = id;
},
},
} satisfies GridOptions;
The application owns persistence; the grid supplies picker and CRUD behavior. A
view contains column layout, column-group expanders (which groups are open or
closed), grouping, sorting, filters, the quick filter (its text, match mode,
match case and filter-or-find behavior), the footer's aggregate scope (None /
Current page / Entire dataset), rows pinned at runtime (api.setRowPinned or
the row menu's Pin, by row id), and group expansion. The row selection and the
sheets list are deliberately not part of a view. A column group is matched by
its colId, so give groups an explicit one for their expander state to survive
a reload. (The live demo above persists its views to
localStorage — shape the grid, open or close a group, save a view, and reload
the page.)
Capture and apply view state directly
const state = api.captureViewState();
localStorage.setItem("orders-view", JSON.stringify(state));
api.applyViewState(state); // exact column restore
api.applyViewState(state, { columns: "merge" }); // retain later columns
Fields added after a view was saved are optional: a view captured before
quickFilterSettings, aggregateScope or rowPinning existed applies its
quick-filter text alone and leaves the live match settings, aggregate scope and
runtime pins as they are. A present rowPinning replaces every runtime pin
(an empty list unpins them all); rows pinned by an isRowPinned callback or
supplied as pinnedTopRowData / pinnedBottomRowData are configuration, not
view state, and are never captured. On a server-side grid without a server
aggregation source a saved "all" scope applies as "page".