Skip to content

Array and Tags Filter

Use the array and tags filter for labels, skills, categories, flags, or nested models that resolve to a tag array. Tag identity is typed, so 1, '1', true, and null remain distinct values.

Source code
TypeScriptts
const tagOptions = [
  { value: 1, label: 'UI' },
  { value: 2, label: 'API' },
  { value: 3, label: 'Docs' },
];

grid.plugins = [AdvanceFilterPlugin];
grid.columnTypes = { dropdown: ColumnDropdown };
grid.columns = [
  { prop: 'item', name: 'Item', size: 180 },
  {
    prop: 'tags',
    name: 'Tags',
    size: 220,
    columnType: 'dropdown',
    filter: ['array', FILTER_ARRAY_TAGS],
    dropdown: {
      source: tagOptions,
      placeholder: 'Select tags',
      config: {
        multiSelect: true,
        search: true,
      },
    },
  },
];
grid.filter = true;

return [
  { item: 'Dashboard', tags: [1, 2] },
  { item: 'Developer portal', tags: [2, 3] },
  { item: 'Design guide', tags: [1, 3] },
  { item: 'Unassigned', tags: [] },
];
import { AdvanceFilterPlugin, FILTER_ARRAY_TAGS } from '@revolist/revogrid-pro';
import '@revolist/revogrid-pro/dist/revogrid-pro.css';
grid.plugins = [AdvanceFilterPlugin];
grid.columns = [
{
prop: 'tags',
name: 'Tags',
filter: ['array', FILTER_ARRAY_TAGS],
},
];
grid.source = [{ tags: ['UI', 'API'] }, { tags: ['Docs'] }, { tags: [] }];
grid.filter = true;

The popup flattens provider-backed array values into at most 200 typed tag options. The base 'array' family also keeps the ordinary empty/not-empty operators available.

When rows store tag IDs and a ColumnDropdown editor uses { value, label } options, keep the IDs in the row and filter model. The filter automatically reuses the normalized dropdown labels in its popup, header summary, and condition description.

const tagOptions = [
{ value: 1, label: 'UI' },
{ value: 2, label: 'API' },
];
grid.columns = [{
prop: 'tags',
columnType: 'dropdown',
filter: ['array', FILTER_ARRAY_TAGS],
dropdown: { source: tagOptions, config: { multiSelect: true, search: true } },
}];

For remote labels that are not present in the dropdown source, use arrayTags.formatLabel globally or under arrayTags.columns[prop]. An explicit formatter takes precedence over the dropdown label. Presentation never changes identity: numeric ID 1 remains distinct from string ID '1' during matching and saved-state restore.

  • Structured type: FILTER_ARRAY_TAGS ('arrayTags')
  • Operator: ARRAY_TAGS_MATCH ('arrayTagsMatch')
  • Value: { mode, values, emptyOnly, exact }
  • Modes: 'any' | 'all' | 'none'
grid.filter = {
multiFilterItems: {
tags: [
{
id: 1,
type: 'arrayTagsMatch',
value: {
mode: 'all',
values: ['UI', 'API'],
emptyOnly: false,
exact: false,
},
relation: 'and',
},
],
},
};

This JSON-safe object is the programmatic restore shape. any matches at least one selected tag, all requires every selected tag, and none rejects rows containing any selected tag. exact compares the complete normalized set and is ignored for none. emptyOnly takes precedence and matches only an actual empty array.

Configure an accessor globally or by column property through filter.arrayTags. It receives the cell value plus { property, column, model } context and must return the array to treat as tags.

import { defineAdvancedFilterConfig } from '@revolist/revogrid-pro';
grid.columns = [
{
prop: 'metadata',
name: 'Labels',
filter: ['array', FILTER_ARRAY_TAGS],
},
];
grid.filter = defineAdvancedFilterConfig({
arrayTags: {
columns: {
metadata: {
accessor: (value) => value?.labels,
},
},
},
});
grid.source = [
{ metadata: { labels: ['Priority', 'Customer'] } },
{ metadata: { labels: ['Internal'] } },
];

Use arrayTags.accessor for one global rule and arrayTags.columns[prop].accessor for exceptions. The per-column accessor wins. The same accessor is used to collect popup choices and evaluate rows.

Accessor functions are not serializable. Server-side filtering must implement the same extraction rule. For a high-cardinality or partially loaded remote source, provide complete array values or prepared { kind: 'arrayTags', values } data rather than deriving choices from one page.

  • Do not restore type: 'arrayTags'; saved conditions use type: 'arrayTagsMatch'.
  • Do not return a scalar from the accessor. It must return the tag array.
  • Do not expect string coercion: numeric 1 and string '1' are different tags.
  • Do not combine mode: 'none' with exact; normalization disables exact mode for none.
  • Do not use emptyOnly for null, missing, or sparse arrays. It delegates to strict empty-array semantics (Array.isArray(value) && value.length === 0).
  • Do not forget to reproduce a custom accessor in a remote filter backend.