Skip to content

Filter Header

The Filter Header Plugin enhances RevoGrid by embedding interactive filter controls directly within the column headers.

Source code
TypeScript ts
// src/components/filter-header/FilterAdvanced.ts

import { defineCustomElements } from '@revolist/revogrid/loader';
import {
  AdvanceFilterPlugin,
  ColumnStretchPlugin,
  FilterHeaderPlugin,
  RowOddPlugin,
  RowSelectPlugin,
  SameValueMergePlugin,
} from '@revolist/revogrid-pro';
defineCustomElements();

import { currentTheme } from '../composables/useRandomData';
import { makeData } from '../composables/makeData';

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

  grid.columns = [
    {
      name: 'Superheroes',
      children: [
        {
          name: 'First Name',
          prop: 'firstName',
          filter: true,
          rowSelect: true,
          columnTemplate: (h) =>
            h('span', { style: { fontWeight: 'bold', color: '#0066cc' } }, 'Custom First Name'),
        },
        {
          name: 'Last Name',
          prop: 'lastName',
          filter: ['selection'],
        },
      ],
    },
    {
      name: 'Params',
      children: [
        {
          name: 'Gender',
          prop: 'gender',
          filter: ['selection'],
        },
      ],
    },
  ];
  grid.plugins = [
    AdvanceFilterPlugin,
    FilterHeaderPlugin,
    ColumnStretchPlugin,
    SameValueMergePlugin,
    RowSelectPlugin,
    RowOddPlugin,
  ];
  grid.stretch = 'all';
  grid.filter = {};
  grid.theme = isDark() ? 'darkMaterial' : 'material';
  grid.hideAttribution = true;
  grid.resize = true;
  document.querySelector(parentSelector)?.appendChild(grid);
  grid.source = makeData(100);
}
Vue vue
// src/components/filter-header/FilterAdvanced.vue

<template>
  <VGrid
    class="grow h-full cell-border"
    :theme="isDark ? 'darkMaterial' : 'material'"
    :columns="columns"
    :source="rows"
    :plugins="plugins"
    stretch="all"
    :filter="filter"
    style="min-height: 400px;"
    hide-attribution
    resize
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { currentThemeVue } from '../composables/useRandomData';
import {
  type ColumnGrouping,
  type ColumnRegular,
  VGrid,
} from '@revolist/vue3-datagrid';
import {
  AdvanceFilterPlugin,
  FilterHeaderPlugin,
  ColumnStretchPlugin,
  SameValueMergePlugin,
  RowSelectPlugin,
  RowOddPlugin
} from '@revolist/revogrid-pro';
import { makeData } from '../composables/makeData';

const { isDark } = currentThemeVue();

const columns = ref<(ColumnRegular | ColumnGrouping)[]>([
  {
    name: 'Superheroes',
    children: [
      {
        name: 'First Name',
        prop: 'firstName',
        filter: true,
        rowSelect: true,
        columnTemplate: (h) =>
          h('span', { style: { fontWeight: 'bold', color: '#0066cc' } }, 'Custom First Name'),
      },
      {
        name: 'Last Name',
        prop: 'lastName',
        filter: ['selection'],
      },
    ],
  },
  {
    name: 'Params',
    children: [
      {
        name: 'Gender',
        prop: 'gender',
        filter: ['selection'],
      },
    ],
  },
]);

const plugins = ref([
  AdvanceFilterPlugin,
  FilterHeaderPlugin,
  ColumnStretchPlugin,
  SameValueMergePlugin,
  RowSelectPlugin,
  RowOddPlugin
]);

const rows = ref(makeData(100));

const filter = ref({});
</script>
React tsx
// src/components/filter-header/FilterAdvanced.tsx

import { useMemo, useState } from 'react';
import {
  RevoGrid,
  type ColumnGrouping,
  type ColumnRegular,
  type DataType,
} from '@revolist/react-datagrid';
import {
  AdvanceFilterPlugin,
  ColumnStretchPlugin,
  FilterHeaderPlugin,
  RowOddPlugin,
  RowSelectPlugin,
  SameValueMergePlugin,
} from '@revolist/revogrid-pro';
import { currentTheme } from '../composables/useRandomData';
import { makeData } from '../composables/makeData';

function FilterAdvanced() {
  const { isDark } = currentTheme();
  const [source] = useState<DataType[]>(() => makeData(100));
  const filter = useMemo(() => ({}), []);
  const plugins = useMemo(
    () => [
      AdvanceFilterPlugin,
      FilterHeaderPlugin,
      ColumnStretchPlugin,
      SameValueMergePlugin,
      RowSelectPlugin,
      RowOddPlugin,
    ],
    [],
  );

  const columns = useMemo<(ColumnRegular | ColumnGrouping)[]>(
    () => [
      {
        name: 'Superheroes',
        children: [
          {
            name: 'First Name',
            prop: 'firstName',
            filter: true,
            rowSelect: true,
            columnTemplate: (h) =>
              h('span', { style: { fontWeight: 'bold', color: '#0066cc' } }, 'Custom First Name'),
          },
          {
            name: 'Last Name',
            prop: 'lastName',
            filter: ['selection'],
          },
        ],
      },
      {
        name: 'Params',
        children: [
          {
            name: 'Gender',
            prop: 'gender',
            filter: ['selection'],
          },
        ],
      },
    ],
    [],
  );

  return (
    <RevoGrid
      className="grow h-full cell-border"
      columns={columns}
      source={source}
      stretch="all"
      filter={filter}
      hide-attribution
      theme={isDark() ? 'darkMaterial' : 'material'}
      plugins={plugins}
      style={{ minHeight: 400 }}
      resize
    />
  );
}

export default FilterAdvanced;
Angular ts
// src/components/filter-header/FilterAdvancedAngular.ts

import { Component, ViewEncapsulation } from '@angular/core';
import { RevoGrid } from '@revolist/angular-datagrid';
import {
  AdvanceFilterPlugin,
  ColumnStretchPlugin,
  FilterHeaderPlugin,
  RowOddPlugin,
  RowSelectPlugin,
  SameValueMergePlugin,
} from '@revolist/revogrid-pro';
import { currentTheme } from '../composables/useRandomData';
import { makeData } from '../composables/makeData';

@Component({
  selector: 'filter-header-grid',
  standalone: true,
  imports: [RevoGrid],
  template: `
    <revo-grid
      class="grow h-full cell-border"
      [columns]="columns"
      [source]="source"
      stretch="all"
      [filter]="filter"
      [hideAttribution]="true"
      [theme]="theme"
      [plugins]="plugins"
      [resize]="true"
      style="min-height: 400px;"
    ></revo-grid>`,
  encapsulation: ViewEncapsulation.None,
})
export class FilterHeaderGridComponent {
  theme = currentTheme().isDark() ? 'darkMaterial' : 'material';
  source = makeData(100);

  columns = [
    {
      name: 'Superheroes',
      children: [
        {
          name: 'First Name',
          prop: 'firstName',
          filter: true,
          rowSelect: true,
          columnTemplate: (h) =>
            h('span', { style: { fontWeight: 'bold', color: '#0066cc' } }, 'Custom First Name'),
        },
        {
          name: 'Last Name',
          prop: 'lastName',
          filter: ['selection'],
        },
      ],
    },
    {
      name: 'Params',
      children: [
        {
          name: 'Gender',
          prop: 'gender',
          filter: ['selection'],
        },
      ],
    },
  ];

  filter = {};
  plugins = [
    AdvanceFilterPlugin,
    FilterHeaderPlugin,
    ColumnStretchPlugin,
    SameValueMergePlugin,
    RowSelectPlugin,
    RowOddPlugin,
  ];
}

This means that users can apply text-based and selection-based filters right at the grid level, without needing separate filter panels.

This feature allows for complex multi-criteria filtering that is both intuitive and highly efficient.

What makes this so powerful - is its ability to wrap existing header content with dynamic filter inputs, ensuring that the grid remains clean and user-friendly while offering robust filtering capabilities. With optimized performance through input debouncing, the Filter Header Plugin significantly improves data exploration, making it an essential tool for managing and analyzing large datasets.

To enable this powerful filtering capability, you simply need to include the FilterHeaderPlugin in your grid’s plugins array.

import { AdvanceFilterPlugin, FilterHeaderPlugin } from '@revolist/revogrid-pro'
const plugins = ref([AdvanceFilterPlugin, FilterHeaderPlugin])

This plugin automatically integrates filter input elements into your column headers, so when you mark a column with a filter property, it dynamically adds a text input or selection control right below the header.

For selection, slider, and date popup filters, the header renders a popup trigger instead of a free text input.

Selection triggers show All while no values are excluded. Opening a selection popup and closing it without changes keeps the header value as All; it does not expand to every selected item.

When values are unchecked in the selection popup, the trigger shows the selected values and, by default, includes a count when more than one value is selected. Set hideFilterHeaderCount on the column to hide the count.