Selection Filter
Selection filters let users include or exclude values through a searchable checkbox list. The list is a virtualized nested revo-grid, so large option sets render only the visible rows while preserving sorting, search, and checkbox behavior.
Use the default interaction for immediate checkbox updates. When users should review a staged checklist and choose Apply, use the dedicated Excel-Style Filter preset.
Source code
grid.plugins = [AdvanceFilterPlugin];
grid.columns = [
{ prop: 'fruit', name: 'Fruit', filter: [FIlTER_SELECTION] },
];
grid.filter = true;
return [
{ fruit: 'Apple' },
{ fruit: 'Banana' },
{ fruit: 'Apple' },
{ fruit: 'Pear' },
];Quick start
Section titled “Quick start”Add AdvanceFilterPlugin, then include selection in the column’s filter families:
import { AdvanceFilterPlugin, FIlTER_SELECTION } from '@revolist/revogrid-pro';import '@revolist/revogrid-pro/dist/revogrid-pro.css';
grid.plugins = [AdvanceFilterPlugin];grid.columns = [ { name: 'Fruit', prop: 'name', filter: ['string', FIlTER_SELECTION], },];
grid.filter = true;grid.source = [{ name: 'Apple' }, { name: 'Banana' }, { name: 'Pear' }];By default, checked values are included and unchecked values are stored as an excluded-value Set. Opening and closing a fully selected list does not create a filter.
Add grid.filter = { selection: { sortDirection: 'asc' } } when the options should be sorted rather than kept in source order.
Windows Excel mode
Section titled “Windows Excel mode”selection.excelMode: 'windows' changes selection-filter columns into a staged, spreadsheet-style checklist. It keeps the same excluded-value Set model but adds Apply, Cancel, tri-state Select All, blanks, search actions, and optional date hierarchies.
See Excel-Style Filter for the interactive four-framework example and complete behavior reference. This heading remains available for links created before the guide was separated.
How the option list behaves
Section titled “How the option list behaves”The selection popup keeps the search row fixed at the top and renders option rows through an internal revo-grid.
- Search still matches normalized option
value. - Select-all only affects currently searched and visible option rows.
- Checked state still means the value is included; unchecked values are stored in the selection filter’s excluded-value
Set. - Opening and closing a fully selected popup does not create an empty selection filter, so
FilterHeaderPluginkeeps showingAll. - Group rows are visual only; option checkboxes still belong to leaf option rows.
The old .filter-list li DOM shape is not part of the public API. Use the visible option behavior or .filter-list-option when tests need to interact with option rows.
Control option values and sources
Section titled “Control option values and sources”Parsed cell values
Section titled “Parsed cell values”When a column defines cellParser, the built-in selection option loader uses the parsed value for option labels, quick search, and row comparison. This lets rows keep identifiers or structured values while the filter presents and compares the normalized value returned by the parser. Context-aware cascading options use the same parsed values.
const statusLabels = { 1: 'Active', 2: 'Paused',};
grid.columns = [ { prop: 'status', name: 'Status', filter: ['selection'], cellParser: (model, column) => statusLabels[model[column.prop]], },];If you provide selection.getItems, that custom loader remains the explicit source for option values and labels. See the Core guide on filtering parsed values for the underlying cellParser contract.
Extend source-row eligibility
Section titled “Extend source-row eligibility”The built-in selection and slider option loaders emit the cancelable beforefilteroptionsourcerow event before a source row contributes a value. Cancel the event to exclude application- or plugin-owned synthetic rows without coupling Advanced Filter to their data shape.
import { BEFORE_FILTER_OPTION_SOURCE_ROW_EVENT } from '@revolist/revogrid-pro';
grid.addEventListener(BEFORE_FILTER_OPTION_SOURCE_ROW_EVENT, (event) => { if (event.detail.row.__summaryRow) { event.preventDefault(); }});Grouping rows are excluded before the event is emitted. The @revolist/pivot plugin uses this extension automatically for subtotal and grand-total rows. A custom selection.getItems loader remains fully application-owned and does not scan or emit events for grid source rows.
Search and context-aware options
Section titled “Search and context-aware options”Quick-search filtering
Section titled “Quick-search filtering”By default, the selection popup search input does two things:
- narrows the option rows shown inside the popup
- applies a hidden
quickSearchfilter to the grid rows
This preserves the existing behavior for users who expect the grid to narrow while they type. Set selection.quickSearchFiltering to false when search should only help users find values in the popup and should not change the grid rows until they check or uncheck selection values.
grid.filter = { selection: { quickSearchFiltering: false, },};When selection values are IDs but the popup renders names, use selection.quickSearchFilter to match the text users see. The matcher receives normalized search, normalized option value, display label, original item, and columnProp. If quickSearchFiltering remains enabled, grid rows are filtered by the matched option values, so row data can still store IDs.
grid.filter = { selection: { getItems: { ownerId: () => [ ], }, quickSearchFilter: { ownerId: ({ search, label, item }) => `${label} ${item.email}`.toLowerCase().includes(search), }, },};Context-aware cascading options
Section titled “Context-aware cascading options”Enable context-aware selection options with selection.cascadeOptions.enabled.
- For column X, options are built from rows matching all active filters except filters for X.
- This keeps current-column values reversible while still narrowing related column options.
optionVisibilitysupportshide,disable, andshow;hideis the default.- Header totals and tooltips always describe context-valid values, even when the popup shows the complete domain.
- The feature is opt-in, and default behavior is unchanged when omitted.
grid.filter = { selection: { cascadeOptions: { enabled: true, optionVisibility: 'hide', }, },};See Cascading Selection Filters for a detailed comparison of all three modes and preserved exclusion behavior.
Custom option sources
Section titled “Custom option sources”By default, the selection filter builds its checkbox list from the current grid data. Use filter.selection.getItems when the list should come from somewhere else, for example:
- server-side or infinite-scroll datasets
- a curated allow-list of accepted values
- normalized values that differ from the rendered cell text
Default lists are rebuilt when the popup opens. If a cell value is edited, rows are removed, or grid.source is replaced, the next selection popup reflects the latest column values. Values that no longer exist in the source are not shown unless you provide them through a custom selection.getItems loader.
When pinned rows should not contribute checkbox values, keep the default loader and restrict its row stores:
grid.filter = { selection: { sourceRowTypes: ['rgRow'], },};The loader receives the current column prop and may return data synchronously or asynchronously.
grid.filter = { selection: { getItems: async (prop) => { if (prop !== 'name') { return []; }
const response = await fetch('/api/filter-options/names'); const items = await response.json();
return items.map((item: { id: string; title: string }) => ({ value: item.id.toLowerCase(), label: item.title, })); }, },};If only some columns need custom values, pass a record keyed by column prop:
grid.filter = { selection: { getItems: { name: async () => [ { value: 'apple', label: 'Apple' }, { value: 'banana', label: 'Banana' }, ], category: () => [ { value: 'fresh', label: 'Fresh' }, { value: 'frozen', label: 'Frozen' }, ], }, },};Keep value aligned with the value used during filter comparison. The built-in selection filter compares lower-cased string values, so custom lists should usually provide lower-cased value fields.
Customize option presentation
Section titled “Customize option presentation”Custom option templates
Section titled “Custom option templates”Use selection.itemTemplate to render badges, icons, or richer labels inside the selection popup. The checkbox remains controlled by the filter plugin; the template only replaces the content next to it.
To reuse an existing column renderer without defining a second template, enable selection.syncCellTemplate. The option item is exposed as a synthetic row model, including metadata returned by selection.getItems, and the current column prop is set to the normalized filter value.
grid.filter = { selection: { syncCellTemplate: { availability: true, }, getItems: { availability: () => [ { value: 'in stock', label: 'In stock', tone: 'green' }, { value: 'backorder', label: 'Backorder', tone: 'amber' }, ], }, },};grid.filter = { selection: { getItems: { availability: () => [ { value: 'in stock', label: 'In stock', tone: 'green' }, { value: 'backorder', label: 'Backorder', tone: 'amber' }, { value: 'seasonal', label: 'Seasonal', tone: 'indigo' }, ], }, itemTemplate: { availability: (h, { item, label, checked }) => h( 'span', { class: `availability-badge availability-badge--${item.tone}`, 'data-selected': String(checked), }, label, ), }, },};itemTemplate receives:
columnProp: Current column property.item: Original item returned byselection.getItemsor the default source loader.value: Normalized value used by selection filtering.label: Display label.checked: Whether the option is currently included in the result.
Option progress
Section titled “Option progress”Use selection.optionProgress for a responsive distribution bar inside the selection-owned option
row. The label, track, and formatted value share the available width, and unchecked options switch
to the muted visual state automatically. Values read item metadata returned by selection.getItems.
grid.filter = { selection: { getItems: { status: () => [ { value: 'processing', label: 'Processing', count: 42 }, { value: 'shipped', label: 'Shipped', count: 28 }, ], }, optionProgress: { status: { valueProp: 'count', getMax: ({ values }) => Math.max(1, ...values), formatValue: value => `${value} rows`, }, }, },};Use getValue instead of valueProp for derived values, and max or getMax to control the range.
showValue: false hides the trailing value while keeping the accessible progressbar. ariaLabel
accepts a string or formatter.
For secondary metadata that is not progress, selection.optionColumns still appends ordinary
read-only RevoGrid columns after the selection-owned checkbox and label column.
Grouped option rows
Section titled “Grouped option rows”Selection option rows can be grouped by fields on the option item. This is useful for large curated lists where users need a hierarchy such as family and color, region and country, or category and status.
grid.filter = { selection: { grouping: { name: { props: ['family', 'color'], expandedAll: true, }, }, getItems: { name: () => [ { value: 'apple', label: 'Apple', family: 'Tree fruit', color: 'Red' }, { value: 'pear', label: 'Pear', family: 'Tree fruit', color: 'Green' }, { value: 'lemon', label: 'Lemon', family: 'Citrus', color: 'Yellow' }, ], }, },};selection.grouping can also be a single GroupingOptions object when every selection-filter column should use the same grouping configuration.
Nested-list plugins and settings
Section titled “Nested-list plugins and settings”The selection list is a nested grid, and you can pass plugins or grid settings to that nested grid when you need additional rendering behavior.
import { AdvanceFilterPlugin } from '@revolist/revogrid-pro';
class SelectionListPlugin { constructor(selectionGrid) { selectionGrid.setAttribute('data-selection-list-plugin', 'mounted'); }}
grid.plugins = [AdvanceFilterPlugin];grid.filter = { selection: { plugins: { name: [SelectionListPlugin], }, gridSettings: { name: { theme: 'compact', rowSize: 32, frameSize: 2, hideAttribution: true, }, }, },};selection.plugins and selection.gridSettings accept either a global value or a record keyed by column prop.
The filter list owns source, columns, and grouping so filtering, checkbox state, and virtualization stay consistent. Use selection.grouping for grouped option rows instead of gridSettings.grouping.
Restore selection state
Section titled “Restore selection state”Selection filters store unchecked values as an excluded-value Set. To predefine a selection filter, add a hidden selection filter with values that should be excluded.
grid.filter = { multiFilterItems: { name: [ { id: 0, type: 'selection', value: new Set(['banana', 'lemon']), relation: 'and', hidden: true, }, ], },};The Excel-style demo uses this pattern for the Fruit column, so two fruit values are already unchecked when it loads. See Filter State and Presets before persisting this model because a Set is not directly JSON-safe.
Configuration reference
Section titled “Configuration reference”| Option | Purpose |
|---|---|
sortDirection | Sort options with 'asc', 'desc', or 'none'. |
excelMode | Set to 'windows' for the dedicated Excel-style checklist. |
quickSearchFiltering | Choose whether popup search also filters grid rows; defaults to true. |
quickSearchFilter | Match search text against labels or custom item metadata. |
sourceRowTypes | Choose which row stores feed the default option loader. |
getItems | Provide synchronous or asynchronous custom options globally or by column. |
itemTemplate / syncCellTemplate | Customize option content while the plugin retains checkbox behavior. |
optionProgress | Add selection-owned responsive progress with checked and unchecked visual states. |
optionColumns | Append read-only metadata columns for non-progress option details. |
grouping | Group option rows using fields returned by getItems. |
plugins / gridSettings | Configure the nested option grid without replacing its owned source, columns, or grouping. |
cascadeOptions | Build options from rows matching filters in other columns. |
Default-mode localization includes selectionTitle and selectionSearchPlaceholder. Excel mode adds the action and blank captions documented in Excel-Style Filter.