The Grid Menu (also known as the "Hamburger Menu") is enabled by default in the project (it's possible to disable it too).
Technically, it's automatically enabled so just enjoy it, you could optionally disable it though. You could also customize the content of the Grid Menu, see below for more details.
The Grid Menu includes, by default, the "Column Picker" list. This brings an easy way to show/hide certain column(s) from the grid. This functionality implementation comes from the Column Picker Plugin and brought over to the Grid Menu.
For very large data grid with lots of columns to scroll, you could optionally skip the creation of the Column Picker and only keep the "Commands" section.
this.gridOptions: {
gridMenu: {
hideColumnPickerSection: true,
}
}The Grid Menu also comes, by default, with a list of built-in custom commands (all their positionOrder are in the reserved range of 40 to 60)
- Clear all Filters (you can hide it with
hideClearAllFiltersCommand: true) - Clear all Sorting (you can hide it with
hideClearAllSortingCommand: true) - Toggle the Filter Row (you can hide it with
hideToggleFilterCommand: true) - Export to CSV (you can hide it with
hideExportCsvCommand: true) - Export to Text Delimited (you can hide it with
hideExportTextDelimitedCommand: true) - Refresh Dataset, only shown when using Backend Service API (you can hide it with
hideRefreshDatasetCommand: true)
Note: all
hide...andpositionOrderproperties were deprecated in v10 and will be removed in v11, prefer the use ofhideCommandsor thecommandListBuilderinstead (see below).
This section is called Custom Commands because you can also customize this section with your own commands. To do that, you need to fill in 2 properties (an array of commandItems and define onGridMenuCommand callback) in your Grid Options. For example, Slickgrid-Universal is configured by default with these settings (you can overwrite any one of them):
this.gridOptions = {
enableAutoResize: true,
enableGridMenu: true,
enableFiltering: true,
gridMenu: {
commandTitle: 'Custom Commands',
columnTitle: 'Columns',
iconCssClass: 'mdi mdi-dots-vertical',
menuWidth: 17,
resizeOnShowHeaderRow: true,
commandItems: [
{
iconCssClass: 'mdi mdi-filter-remove-outline',
title: 'Clear All Filters',
disabled: false,
command: 'clear-filter'
},
{
iconCssClass: 'mdi-flip-vertical',
title: 'Toggle Filter Row',
disabled: false,
command: 'toggle-filter'
},
// you can add sub-menus by adding nested `commandItems`
{
// we can also have multiple nested sub-menus
command: 'export', title: 'Exports', positionOrder: 99,
commandItems: [
{ command: 'exports-txt', title: 'Text (tab delimited)' },
{
command: 'sub-menu', title: 'Excel', cssClass: 'green', subMenuTitle: 'available formats', subMenuTitleCssClass: 'text-italic orange',
commandItems: [
{ command: 'exports-csv', title: 'Excel (csv)' },
{ command: 'exports-xlsx', title: 'Excel (xlsx)' },
]
}
]
},
],
onCommand: (e, args) => {
if (args.command === 'toggle-filter') {
this.gridObj.setHeaderRowVisibility(!this.gridObj.getOptions().showHeaderRow);
} else if (args.command === 'clear-filter') {
this.filterService.clearFilters();
this.dataviewObj.refresh();
}
}
}
};For more advanced use cases where you need to dynamically build the command list, use commandListBuilder. This callback receives the built-in commands and allows you to filter, sort, or modify the list before it's rendered in the UI, giving you full control over the final command list. This function is executed after commandItems is processed and is the last call before rendering the menu in the DOM.
When to use commandListBuilder:
- You want to append/prepend items to the built-in commands
- You need to filter commands based on runtime conditions
- You want to sort or reorder commands dynamically
- You need access to both built-in and custom commands to manipulate the final list
Note: You would typically use commandListBuilder instead of commandItems (not both), since the builder gives you full control over the final command list.
gridOptions: {
gridMenu: {
// Build the command list dynamically
commandListBuilder: (builtInItems) => {
// Example 1: Append custom commands to built-in ones
return [
...builtInItems,
'divider',
{
command: 'help',
title: 'Help',
iconCssClass: 'mdi mdi-help-circle',
positionOrder: 99,
action: () => window.open('https://example.com/help', '_blank')
},
];
},
onCommand: (e, args) => {
if (args.command === 'help') {
// command handled via action callback above
}
}
}
}Example: Filter commands based on user permissions
gridOptions: {
gridMenu: {
commandListBuilder: (builtInItems) => {
// Remove export commands if user doesn't have export permission
if (!this.userHasExportPermission) {
return builtInItems.filter(item =>
item !== 'divider' &&
!item.command?.includes('export')
);
}
return builtInItems;
}
}
}Example: Reorder and customize the command list
gridOptions: {
gridMenu: {
commandListBuilder: (builtInItems) => {
// Add custom commands at the beginning
const customCommands = [
{
command: 'refresh-cache',
title: 'Refresh Cache',
iconCssClass: 'mdi mdi-cached',
action: () => this.refreshCache()
},
'divider'
];
// Sort built-in items by title
const sortedBuiltIn = builtInItems
.filter(item => item !== 'divider')
.sort((a, b) => (a.title || '').localeCompare(b.title || ''));
return [...customCommands, ...sortedBuiltIn];
}
}
}There are multiple events/callback hooks which are accessible from the Grid Options
onBeforeMenuShowonAfterMenuShowonMenuCloseonColumnsChangedonCommand
gridMenu: {
// commandItems: [
// { command: 'help', title: 'Help', positionOrder: 70, action: (e, args) => console.log(args) },
// { command: '', divider: true, positionOrder: 72 },
// { command: 'hello', title: 'Hello', positionOrder: 69, action: (e, args) => alert('Hello World'), cssClass: 'red', tooltip: 'Hello World', iconCssClass: 'mdi mdi-close' },
// ],
// menuUsabilityOverride: () => false,
onBeforeMenuShow: () => {
console.log('onGridMenuBeforeMenuShow');
// return false; // returning false would prevent the grid menu from opening
},
onAfterMenuShow: () => console.log('onGridMenuAfterMenuShow'),
onColumnsChanged: (_e, args) => console.log('onGridMenuColumnsChanged', args),
onCommand: (e, args) => {
// e.preventDefault(); // preventing default event would keep the menu open after the execution
console.log('onGridMenuCommand', args.command);
},
onMenuClose: (e, args) => console.log('onGridMenuMenuClose - visible columns count', args.visibleColumns.length),
},For more info on all the available properties of the custom commands, you can read refer to the doc written in the Grid Menu implementation itself.
To customize the appearance of menu items with custom HTML, badges, icons, or interactive elements, you can use the slotRenderer or defaultMenuItemRenderer callbacks.
See Custom Menu Slots for detailed examples and best practices on rendering custom menu item content.
You can change any of the default command icon(s) by changing the icon[X-command], for example, see below for the defaults.
this.gridOptions = {
enableGridMenu: true,
gridMenu: {
iconClearAllFiltersCommand: 'mdi mdi-filter-remove-outline'
iconClearAllSortingCommand: 'mdi mdi-sort-variant-off',
iconExportCsvCommand: 'mdi mdi-download',
iconExportTextDelimitedCommand: 'mdi mdi-download',
iconRefreshDatasetCommand: 'mdi mdi-sync',
iconToggleFilterCommand: 'mdi-flip-vertical',
},
};By default the Grid Menu icon will be showing on the right after the column headers, if however you wish to move the button icon to show in the pre-header instead, you could simply use the iconButtonContainer grid option
this.gridOptions = {
createPreHeaderPanel: true,
showPreHeaderPanel: true,
preHeaderPanelHeight: 26,
gridMenu: {
iconButtonContainer: 'preheader', // we can display the grid menu icon in either the preheader or in the column header (default)
},
};You can disable the Grid Menu, by calling enableGridMenu: false from the Grid Options.
this.gridOptions = {
enableGridMenu: false,
};The example below demonstrates how to use the new alphabetical sorting feature:
this.gridOptions = {
gridMenu: {
// enable the "columnSort" option to sort columns by name
columnSort: (item1: Column, item2: Column) => {
const nameA = item1.name?.toString().toLowerCase() || '';
const nameB = item2.name?.toString().toLowerCase() || '';
return nameA.localeCompare(nameB);
},
}
};The columnListBuilder is a callback that is executed after reading the built-in columns but before rendering them in the DOM (this is useful to filter and/or sort columns).
For example:
this.gridOptions = {
gridMenu: {
// enable the "columnSort" option to sort columns by name
columnListBuilder: (columns: Column[]) => {
// optionally sort columns
columns.sort((a, b) => {
const nameA = item1.name?.toString().toLowerCase() || '';
const nameB = item2.name?.toString().toLowerCase() || '';
return nameA.localeCompare(nameB);
});
// optionally filter some columns
return columns.filter(c => c.field !== 'gender');
},
}
};