Skip to content

Slider Filter

The slider filter gives numeric columns a two-handle range control. It derives minimum and maximum bounds from eligible row values and stores the active interval in the advanced filter model.

Source code
TypeScriptts
grid.plugins = [AdvanceFilterPlugin];
grid.columns = [
  { prop: 'price', name: 'Price', filter: ['number', FIlTER_SLIDER] },
];
grid.filter = { slider: { showRangeInputs: true } };

return [{ price: 20 }, { price: 100 }, { price: 250 }];

For a fuller example with formatting and additional slider options:

Source code
TypeScriptts
// src/components/filter-slider/FilterAdvanced.ts

import { defineCustomElements } from '@revolist/revogrid/loader';
import { currentTheme } from '../composables/useRandomData';
import {
  createFilterSliderFilter,
  createFilterSliderRows,
  filterSliderColumns,
  filterSliderPlugins,
} from './filter-slider.shared';
defineCustomElements();

const { isDark } = currentTheme();

export function load(parentSelector: string) {
  const grid = document.createElement('revo-grid');
  grid.className = 'cell-border';
  grid.columns = filterSliderColumns;
  grid.plugins = filterSliderPlugins;
  grid.stretch = 'all';
  grid.filter = createFilterSliderFilter();
  grid.theme = isDark() ? 'darkMaterial' : 'material';
  grid.hideAttribution = true;
  document.querySelector(parentSelector)?.appendChild(grid);
  grid.source = createFilterSliderRows();

  return () => grid.remove();
}
Vuevue
// src/components/filter-slider/FilterAdvanced.vue

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

<script setup lang="ts">
import { ref } from 'vue'
import { currentThemeVue } from '../composables/useRandomData'
import { VGrid } from '@revolist/vue3-datagrid'
import {
  createFilterSliderFilter,
  createFilterSliderRows,
  filterSliderColumns,
  filterSliderPlugins,
} from './filter-slider.shared'

const { isDark } = currentThemeVue();
const columns = ref(filterSliderColumns)

const plugins = filterSliderPlugins

const rows = ref(createFilterSliderRows())
const filter = ref(createFilterSliderFilter())
</script>
Reacttsx
// src/components/filter-slider/FilterAdvanced.tsx

import { useState, useMemo } from 'react';
import { RevoGrid, type DataType } from '@revolist/react-datagrid';
import { currentTheme } from '../composables/useRandomData';
import {
  createFilterSliderFilter,
  createFilterSliderRows,
  filterSliderColumns,
  filterSliderPlugins,
} from './filter-slider.shared';

function FilterAdvanced() {
  const { isDark } = currentTheme();

  const [source] = useState<DataType[]>(() => createFilterSliderRows());

  const columns = useMemo(() => filterSliderColumns, []);

  const filter = useMemo(() => createFilterSliderFilter(), []);
  const plugins = useMemo(() => filterSliderPlugins, []);

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

export default FilterAdvanced;
Angularts
// src/components/filter-slider/FilterAdvancedAngular.ts

import { Component, ViewEncapsulation } from '@angular/core';
import { RevoGrid } from '@revolist/angular-datagrid';
import { currentTheme } from '../composables/useRandomData';
import {
  createFilterSliderFilter,
  createFilterSliderRows,
  filterSliderColumns,
  filterSliderPlugins,
} from './filter-slider.shared';

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

  source = createFilterSliderRows();

  columns = filterSliderColumns;

  filter = createFilterSliderFilter();
  plugins = filterSliderPlugins;
}

Add AdvanceFilterPlugin, then combine the number and slider filter families on a numeric column:

import { AdvanceFilterPlugin, FIlTER_SLIDER } from '@revolist/revogrid-pro';
import '@revolist/revogrid-pro/dist/revogrid-pro.css';
grid.plugins = [AdvanceFilterPlugin];
grid.columns = [
{
name: 'Price',
prop: 'price',
filter: ['number', FIlTER_SLIDER],
},
];
grid.filter = true;
grid.source = [{ price: 25 }, { price: 80 }, { price: 140 }];

Returning both handles to the complete data range clears the slider condition. Add FilterHeaderPlugin when the same range control should also appear directly in the column header.

Add options only when the default control needs customization:

grid.filter = {
slider: {
showRangeInputs: true,
formatValue: (value) => `$${value.toFixed(2)}`,
},
};

When the slider column defines cellParser, the slider calculates its minimum and maximum bounds from parsed values and applies range filtering to those same values. Use this when the stored value needs normalization before numeric filtering.

Grouping rows and non-finite parsed values are excluded from the bound calculation. The @revolist/pivot plugin excludes its total rows through Advanced Filter’s cancelable beforefilteroptionsourcerow extension event. If no finite values remain, the slider falls back to 0 for both bounds.

grid.columns = [
{
name: 'Price',
prop: 'priceInCents',
filter: ['number', 'slider'],
cellParser: (model, column) => Number(model[column.prop] ?? 0) / 100,
},
];

See the Core guide on filtering parsed values for the underlying cellParser contract.

The slider filter can be customized using the following configuration options:

OptionTypeDefaultDescription
headerView'slider' | 'range''slider'With FilterHeaderPlugin, shows either the interactive slider or a compact formatted from–to range in the column header
showTooltipsbooleantrueShows tooltips when hovering over the slider handles
showRangeDisplaybooleantrueDisplays the current range values above the slider
showRangeInputsbooleanfalseShows numeric inputs for editing the selected range
formatValuefunction(value) => value.toFixed(2)Custom function to format the displayed values
formatInputValuefunction(value) => String(value)Custom function to format values inside editable range inputs
parseInputValuefunction(value) => Number(value.replace(',', '.'))Custom function to parse editable range input text

The slider component supports custom styling through CSS variables:

revo-grid {
--slider-color: #c6c6c6; /* Color of the inactive slider track */
--range-color: #0068f0; /* Color of the active slider range */
--tooltip-bg: #333333; /* Tooltip background color */
--tooltip-color: #ffffff; /* Tooltip text color */
}
/* Dark theme support */
revo-grid[theme^='dark'] {
--slider-color: #c6c6c6;
--range-color: #0068f0;
--filter-input-bg: #333333;
--filter-input-color: #ffffff;
--tooltip-bg: #f2f2f6;
--tooltip-color: #333333;
}
  1. Range Selection:

    • The slider provides two handles for selecting a range of values
    • Values are automatically normalized between the minimum and maximum values in your dataset
    • Real-time filtering as users adjust the range
  2. Tooltips:

    • Interactive tooltips show the exact value when hovering over slider handles
    • Tooltips can be customized using the formatValue function
    • Position updates dynamically as the handles move
  3. Range Display:

    • Optional display of current range values above the slider
    • Formatted values using the same formatValue function
    • Clear visual feedback of the selected range
  4. Theme Integration:

    • Automatically adapts to light and dark themes
    • Customizable colors through CSS variables
    • Consistent look and feel with the rest of your grid

The slider filter can be combined with other filter types for more complex filtering scenarios:

grid.columns = [
{
name: 'Price',
prop: 'price',
filter: ['number', 'slider', 'selection'], // Combine with selection filter
},
];
  1. User experience:

    • Use showTooltips for precise value selection
    • Implement formatValue for meaningful value display
    • Enable showRangeDisplay for clear range visualization
  2. Accessibility:

    • The handles are native range inputs and remain keyboard-operable.
    • Use showRangeDisplay or editable range inputs when users also need exact textual values.