Skip to content

Filtering

WitTable provides a FilterEngine with 14 built-in operators and AND logic within and across columns. A FilterPanel DOM overlay gives users a point-and-click interface for setting filters. Filtering integrates with sorting — filters are applied first, then sort operates on the filtered result set via DataView.

Live Demo
Right-click a column header or click filter icons to apply filters. Combine with sorting.
Click the filter icon in column headers to filter
View source code
FilteringDemo.tsx
import { useState, useRef } from 'react';
import { WitTable } from '@witqq/spreadsheet-react';
import type { WitTableRef } from '@witqq/spreadsheet-react';
import type { FilterChangeEvent } from '@witqq/spreadsheet';
import { DemoWrapper } from './DemoWrapper';
import { generateEmployees, employeeColumns } from './generate-data';
import { useSiteTheme } from './useSiteTheme';
const data = generateEmployees(100);
const filterableColumns = employeeColumns.map(col => ({ ...col, filterable: true, sortable: true }));
export function FilteringDemo() {
const { witTheme } = useSiteTheme();
const [filterInfo, setFilterInfo] = useState('Click the filter icon in column headers to filter');
const tableRef = useRef<WitTableRef>(null);
const handleFilterChange = (event: FilterChangeEvent) => {
setFilterInfo(`Showing ${event.visibleRowCount} of ${event.totalRowCount} rows`);
};
return (
<DemoWrapper title="Live Demo" description="Right-click a column header or click filter icons to apply filters. Combine with sorting." height={440}>
<div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
<div style={{ padding: '0.5rem 0.75rem', fontSize: '0.8rem', color: '#64748b', borderBottom: '1px solid #e2e8f0', flexShrink: 0 }}>
{filterInfo}
</div>
<div style={{ flex: 1 }}>
<WitTable
theme={witTheme}
ref={tableRef}
columns={filterableColumns}
data={data}
showRowNumbers
editable={false}
sortable
onFilterChange={handleFilterChange}
style={{ width: '100%', height: '100%' }}
/>
</div>
</div>
</DemoWrapper>
);
}
OperatorDescription
equalsExact match
notEqualsNot equal
containsSubstring match
startsWithStarts with value
endsWithEnds with value
greaterThanGreater than (numeric/date)
lessThanLess than (numeric/date)
greaterThanOrEqualGreater than or equal
lessThanOrEqualLess than or equal
betweenValue in range (inclusive)
inValue in set
notInValue not in set
isEmptyCell is empty/null
isNotEmptyCell has a value
import { WitTable } from '@witqq/spreadsheet-react';
const columns: ColumnDef[] = [
{ key: 'name', title: 'Name', filterable: true },
{ key: 'status', title: 'Status', filterable: true },
{ key: 'amount', title: 'Amount', type: 'number', filterable: true },
];
function App() {
return (
<WitTable
columns={columns}
data={data}
onFilterChange={(filters) => {
console.log('Active filters:', filters);
}}
/>
);
}
const ref = useRef<WitTableRef>(null);
// Set a filter on column 1
ref.current?.getInstance().getFilterEngine().setColumnFilter(1, [
{ col: 1, operator: 'contains', value: 'active' },
]);
// Set a range filter
ref.current?.getInstance().getFilterEngine().setColumnFilter(2, [
{ col: 2, operator: 'between', value: 100, valueTo: 500 },
]);
// Remove a column filter
ref.current?.getInstance().getFilterEngine().removeColumnFilter(1);
// Clear all filters
ref.current?.getInstance().getFilterEngine().clearFilters();
MethodSignatureDescription
setColumnFilter(col: number, conditions: FilterCondition[]) => voidSet filter on column
removeColumnFilter(col: number) => voidRemove filter from column
clearFilters() => voidRemove all filters
getColumnFilters(col: number) => FilterCondition[]Get filters for column
interface FilterCondition {
col: number;
operator: FilterOperator;
value?: CellValue;
valueTo?: CellValue; // Second value for 'between' operator
values?: CellValue[]; // Values for 'in' / 'notIn' operators
}
type FilterOperator =
| 'equals' | 'notEquals'
| 'contains' | 'startsWith' | 'endsWith'
| 'greaterThan' | 'lessThan'
| 'greaterThanOrEqual' | 'lessThanOrEqual'
| 'between' | 'in' | 'notIn'
| 'isEmpty' | 'isNotEmpty';

The low-level function used by FilterEngine to test a single cell value:

import { evaluateCondition } from '@witqq/spreadsheet';
const matches = evaluateCondition(cellValue, {
col: 1,
operator: 'between',
value: 100,
valueTo: 500,
}); // true | false
  • Sorting — sort operates on filtered result set
  • DataView — logical↔physical row mapping