Skip to content

Filter Selection Cascade

Use filter.selection.cascadeOptions.enabled to make selection options context-aware.

In cascade mode, RevoGrid builds each column’s selection list from rows matching all active filters except filters for the current column. This keeps the current column reversible while still narrowing options in related columns.

Set filter.selection.cascadeOptions.showDependencyNumbers to true to show 1, 2, and later badges on active header filter icons in the order those filters are applied. The badges are hidden by default; omit this option or set it to false to keep them hidden.

Source code
TypeScript ts
import { defineCustomElements } from '@revolist/revogrid/loader';
import { AdvanceFilterPlugin, ColumnStretchPlugin } from '@revolist/revogrid-pro';
import { currentTheme } from '../composables/useRandomData';

defineCustomElements();

const rows = [
  { country: 'Germany', city: 'Berlin', department: 'Sales' },
  { country: 'Germany', city: 'Munich', department: 'Engineering' },
  { country: 'France', city: 'Paris', department: 'Sales' },
  { country: 'France', city: 'Lyon', department: 'Support' },
  { country: 'Poland', city: 'Warsaw', department: 'Engineering' },
  { country: 'Poland', city: 'Krakow', department: 'Support' },
];

export function load(parentSelector: string) {
  const grid = document.createElement('revo-grid');

  grid.columns = [
    { name: 'Country', prop: 'country', filter: ['selection'] },
    { name: 'City', prop: 'city', filter: ['selection'] },
    { name: 'Department', prop: 'department', filter: ['selection'] },
  ];

  grid.stretch = 'last';
  grid.plugins = [AdvanceFilterPlugin, ColumnStretchPlugin];
  grid.filter = {
    multiFilterItems: {
      department: [{ id: 0, type: 'selection', value: ['sales', 'support'], relation: 'and' }],
      country: [{ id: 1, type: 'selection', value: ['france', 'poland'], relation: 'and' }],
    },
    selection: {
      cascadeOptions: {
        enabled: true,
        showDependencyNumbers: true,
      },
    },
  };
  grid.resize = true;
  grid.theme = currentTheme().isDark() ? 'darkCompact' : 'compact';
  grid.hideAttribution = true;

  document.querySelector(parentSelector)?.appendChild(grid);
  grid.source = rows;

  return () => grid.remove();
}
Vue vue
<template>
  <RevoGrid
    :theme="isDark ? 'darkCompact' : 'compact'"
    :columns="columns"
    :source="rows"
    :plugins="plugins"
    stretch="last"
    :filter="filter"
    hide-attribution
  />
</template>

<script setup lang="ts">
import { computed, ref } from 'vue';
import RevoGrid from '@revolist/vue3-datagrid';
import { AdvanceFilterPlugin, ColumnStretchPlugin } from '@revolist/revogrid-pro';
import { currentThemeVue } from '../composables/useRandomData';

const { isDark } = currentThemeVue();

const columns = ref([
  { name: 'Country', prop: 'country', filter: ['selection'] },
  { name: 'City', prop: 'city', filter: ['selection'] },
  { name: 'Department', prop: 'department', filter: ['selection'] },
]);

const rows = ref([
  { country: 'Germany', city: 'Berlin', department: 'Sales' },
  { country: 'Germany', city: 'Munich', department: 'Engineering' },
  { country: 'France', city: 'Paris', department: 'Sales' },
  { country: 'France', city: 'Lyon', department: 'Support' },
  { country: 'Poland', city: 'Warsaw', department: 'Engineering' },
  { country: 'Poland', city: 'Krakow', department: 'Support' },
]);

const plugins = [AdvanceFilterPlugin, ColumnStretchPlugin];


const filter = computed(() => ({
  multiFilterItems: {
    department: [{ id: 0, type: 'selection', value: ['sales', 'support'], relation: 'and' }],
    country: [{ id: 1, type: 'selection', value: ['france', 'poland'], relation: 'and' }],
  },
  selection: {
    cascadeOptions: {
      enabled: true,
      showDependencyNumbers: true,
    },
  },
}));
</script>
React tsx
import { useMemo } from 'react';
import { RevoGrid } from '@revolist/react-datagrid';
import { AdvanceFilterPlugin, ColumnStretchPlugin } from '@revolist/revogrid-pro';
import { currentTheme } from '../composables/useRandomData';

const rows = [
  { country: 'Germany', city: 'Berlin', department: 'Sales' },
  { country: 'Germany', city: 'Munich', department: 'Engineering' },
  { country: 'France', city: 'Paris', department: 'Sales' },
  { country: 'France', city: 'Lyon', department: 'Support' },
  { country: 'Poland', city: 'Warsaw', department: 'Engineering' },
  { country: 'Poland', city: 'Krakow', department: 'Support' },
];

export default function FilterSelectionCascade() {
  const { isDark } = currentTheme();

  const columns = useMemo(
    () => [
      { name: 'Country', prop: 'country', filter: ['selection'] },
      { name: 'City', prop: 'city', filter: ['selection'] },
      { name: 'Department', prop: 'department', filter: ['selection'] },
    ],
    [],
  );

  const plugins = useMemo(() => [AdvanceFilterPlugin, ColumnStretchPlugin], []);

  const filter = useMemo(
    () => ({
      multiFilterItems: {
        department: [{ id: 0, type: 'selection', value: ['sales', 'support'], relation: 'and' }],
        country: [{ id: 1, type: 'selection', value: ['france', 'poland'], relation: 'and' }],
      },
      selection: {
        cascadeOptions: {
          enabled: true,
          showDependencyNumbers: true,
        },
      },
    }),
    [],
  );

  return (
    <RevoGrid
      columns={columns}
      source={rows}
      plugins={plugins}
      stretch="last"
      filter={filter}
      hide-attribution
      theme={isDark() ? 'darkCompact' : 'compact'}
    />
  );
}
Angular ts
import { Component, ViewEncapsulation } from '@angular/core';
import { RevoGrid } from '@revolist/angular-datagrid';
import { AdvanceFilterPlugin, ColumnStretchPlugin } from '@revolist/revogrid-pro';
import { currentTheme } from '../composables/useRandomData';

@Component({
  selector: 'filter-selection-cascade-grid',
  standalone: true,
  imports: [RevoGrid],
  template: `
    <revo-grid
      [columns]="columns"
      [source]="source"
      stretch="last"
      [filter]="filter"
      [hideAttribution]="true"
      [theme]="theme"
      [plugins]="plugins"
      style="min-height: 400px;"
    ></revo-grid>
  `,
  encapsulation: ViewEncapsulation.None,
})
export class FilterSelectionCascadeGridComponent {
  theme = currentTheme().isDark() ? 'darkCompact' : 'compact';

  source = [
    { country: 'Germany', city: 'Berlin', department: 'Sales' },
    { country: 'Germany', city: 'Munich', department: 'Engineering' },
    { country: 'France', city: 'Paris', department: 'Sales' },
    { country: 'France', city: 'Lyon', department: 'Support' },
    { country: 'Poland', city: 'Warsaw', department: 'Engineering' },
    { country: 'Poland', city: 'Krakow', department: 'Support' },
  ];

  columns = [
    { name: 'Country', prop: 'country', filter: ['selection'] },
    { name: 'City', prop: 'city', filter: ['selection'] },
    { name: 'Department', prop: 'department', filter: ['selection'] },
  ];

  filter = {
    multiFilterItems: {
      department: [{ id: 0, type: 'selection', value: ['sales', 'support'], relation: 'and' }],
      country: [{ id: 1, type: 'selection', value: ['france', 'poland'], relation: 'and' }],
    },
    selection: {
      cascadeOptions: {
        enabled: true,
        showDependencyNumbers: true,
      },
    },
  };

  plugins = [AdvanceFilterPlugin, ColumnStretchPlugin];
}
grid.filter = {
multiFilterItems: {
department: [{ id: 0, type: 'selection', value: ['sales', 'support'], relation: 'and' }],
country: [{ id: 1, type: 'selection', value: ['france', 'poland'], relation: 'and' }],
},
selection: {
cascadeOptions: {
enabled: true,
showDependencyNumbers: true,
},
},
};

If selection.getItems is provided, that custom source is used as-is. Cascade options are only applied to the built-in source loader.