Filtering
The filtering plugin provides powerful, flexible data filtering with an intuitive API. Filter by exact matches, multiple values, custom predicates, or use built-in helpers for common patterns like ranges and text matching.
Enable Filtering
Add filtering using the reactiveFiltering plugin:
<script lang="ts">
import { reactiveTable, reactiveFiltering } from 'svelte-reactive-table';
const data = [
{ id: 1, name: 'Alice', age: 28, city: 'New York', status: 'active' },
{ id: 2, name: 'Bob', age: 35, city: 'Los Angeles', status: 'inactive' },
{ id: 3, name: 'Charlie', age: 22, city: 'Chicago', status: 'pending' }
];
const columns = [
{ accessor: 'id', header: 'ID', isIdentifier: true },
{ accessor: 'name', header: 'Name' },
{ accessor: 'age', header: 'Age' },
{ accessor: 'city', header: 'City' },
{ accessor: 'status', header: 'Status' }
];
// Create table instance with filtering
const table = reactiveTable(data, columns).use(reactiveFiltering());
// Access filtering controls through plugins
const { filtering } = table.plugins;
</script>
The table.rows property automatically contains only rows that match all active filters.
Filter Types
The filtering plugin supports three types of filters, automatically detected based on the value you provide:
Exact Match Filtering
Filter by exact equality for strings, numbers, or other values:
<script>
// Filter by exact city match
filtering.setFilter('city', 'New York');
// Filter by exact status
filtering.setFilter('status', 'active');
// Filter by exact age
filtering.setFilter('age', 28);
</script>
Array Filtering (IN Operation)
Provide an array to match any of the values (like SQL’s IN operator):
<script>
// Filter for multiple cities
filtering.setFilter('city', ['New York', 'Chicago']);
// Filter for multiple statuses
filtering.setFilter('status', ['active', 'pending']);
</script>
Predicate Function Filtering
Use a custom function for complex filtering logic:
<script>
// Filter by age range
filtering.setFilter('age', (age) => age >= 25 && age <= 35);
// Filter by name length
filtering.setFilter('name', (name) => name.length > 5);
// Filter by complex conditions
filtering.setFilter('email', (email) => email.endsWith('@company.com'));
</script>
String Filtering
String filters are special - they perform substring matching (contains) by default:
<script>
// Matches any name containing "alice" (case-insensitive)
filtering.setFilter('name', 'alice');
// Matches: "Alice", "Alice Johnson", "alice smith", etc.
// Matches any city containing "york"
filtering.setFilter('city', 'york');
// Matches: "New York", "York", "Yorkshire", etc.
</script>
String matching is case-insensitive by default. You can enable case-sensitive matching:
<script>
const table = reactiveTable(data, columns).use(
reactiveFiltering({
caseSensitive: true
})
);
// Now 'alice' won't match 'Alice'
filtering.setFilter('name', 'alice');
</script>
Filter Helpers
The plugin includes helper functions for common filtering patterns:
Range Filter
Perfect for numbers, dates, or any comparable values:
<script>
import { filterHelpers } from 'svelte-reactive-table';
// Age between 25 and 35 (inclusive)
filtering.setFilter('age', filterHelpers.range(25, 35));
// Age 25 or higher (no max)
filtering.setFilter('age', filterHelpers.range(25, undefined));
// Age 35 or lower (no min)
filtering.setFilter('age', filterHelpers.range(undefined, 35));
// Date range
filtering.setFilter('createdAt', filterHelpers.range(
new Date('2024-01-01'),
new Date('2024-12-31')
));
</script>
Text Pattern Helpers
Match text patterns with precision:
<script>
import { filterHelpers } from 'svelte-reactive-table';
// Exact text match (case-sensitive)
filtering.setFilter('name', filterHelpers.exactText('Alice'));
// Starts with (case-insensitive by default)
filtering.setFilter('name', filterHelpers.startsWith('A'));
// Ends with
filtering.setFilter('email', filterHelpers.endsWith('@company.com'));
// Case-sensitive starts with
filtering.setFilter('name', filterHelpers.startsWith('A', true));
</script>
NOT Filter
Invert any filter condition:
<script>
import { filterHelpers } from 'svelte-reactive-table';
// Not in New York
filtering.setFilter('city', filterHelpers.not('New York'));
// Not active or inactive
filtering.setFilter('status', filterHelpers.not(['active', 'inactive']));
// Not in age range
filtering.setFilter('age', filterHelpers.not(filterHelpers.range(18, 25)));
</script>
Multiple Filters
Multiple filters use AND logic - rows must match all filters to appear:
<script>
// Set multiple filters at once
filtering.setFilters({
city: 'New York',
status: 'active',
age: filterHelpers.range(25, 35)
});
// Or set filters individually
filtering.setFilter('city', 'New York');
filtering.setFilter('status', 'active');
// Both filters must match
</script>
Managing Filter State
The plugin provides methods to control filter state:
Set and Remove Filters
<script>
// Set a single filter
filtering.setFilter('city', 'New York');
// Set multiple filters
filtering.setFilters({
city: 'New York',
status: 'active'
});
// Remove a specific filter
filtering.removeFilter('city');
// Clear all filters
filtering.clearFilters();
// Get current filter value
const cityFilter = filtering.getFilter('city');
</script>
Empty Values Auto-Remove
Filters are automatically removed when set to empty values:
<script>
// These all remove the filter:
filtering.setFilter('city', undefined);
filtering.setFilter('city', null);
filtering.setFilter('city', '');
filtering.setFilter('city', []);
</script>
Reactive Filter State
Access reactive properties to monitor filter state:
<script>
// Number of active filters
const filterCount = filtering.count;
// Whether any filters are active
const hasFilters = filtering.hasActiveFilters;
// All current filters (read-only)
const currentFilters = filtering.filters;
</script>
<!-- Show filter status in UI -->
{#if filtering.hasActiveFilters}
<div class="filter-status">
{filtering.count} filter{filtering.count === 1 ? '' : 's'} active
<button onclick={() => filtering.clearFilters()}>Clear All</button>
</div>
{/if}
Complete Filter UI Example
Here’s a practical example combining multiple filter types:
<script lang="ts">
import { reactiveTable, reactiveFiltering, filterHelpers } from 'svelte-reactive-table';
const table = reactiveTable(data, columns).use(reactiveFiltering());
const { filtering } = table.plugins;
// Reactive form state
let nameSearch = $state('');
let selectedCities = $state<string[]>([]);
let minAge = $state<number | undefined>();
let maxAge = $state<number | undefined>();
// Sync filters with form state
$effect(() => {
filtering.setFilter('name', nameSearch.trim());
});
$effect(() => {
filtering.setFilter('city', selectedCities);
});
$effect(() => {
filtering.setFilter('age', filterHelpers.range(minAge, maxAge));
});
</script>
<!-- Filter Controls -->
<div class="filters">
<input
type="text"
bind:value={nameSearch}
placeholder="Search names..."
/>
<div>
{#each cities as city}
<label>
<input
type="checkbox"
value={city}
bind:group={selectedCities}
/>
{city}
</label>
{/each}
</div>
<input type="number" bind:value={minAge} placeholder="Min age" />
<input type="number" bind:value={maxAge} placeholder="Max age" />
{#if filtering.hasActiveFilters}
<button onclick={() => {
filtering.clearFilters();
nameSearch = '';
selectedCities = [];
minAge = undefined;
maxAge = undefined;
}}>
Clear Filters ({filtering.count})
</button>
{/if}
</div>
<!-- Results Summary -->
<div class="results">
Showing {table.rows.length} of {table.allRows.length} results
{#if filtering.hasActiveFilters}
<span>(filtered)</span>
{/if}
</div>
<!-- Table -->
<table>
<tbody>
{#each table.rows as row}
<tr>
{#each row.cells as cell}
<td>{cell.value}</td>
{/each}
</tr>
{/each}
{#if table.rows.length === 0 && filtering.hasActiveFilters}
<tr>
<td colspan={table.columns.length}>
No results match your filters
</td>
</tr>
{/if}
</tbody>
</table>
Integration with Other Plugins
Filtering works seamlessly with other plugins:
<script>
import {
reactiveTable,
reactiveFiltering,
reactiveSorting,
reactivePagination
} from 'svelte-reactive-table';
// Filters are applied first, then sorting, then pagination
const table = reactiveTable(data, columns)
.use(reactiveFiltering())
.use(reactiveSorting())
.use(reactivePagination({ pageSize: 10 }));
// table.rows contains: filtered → sorted → paginated results
// table.allRows contains: all data (useful for "showing X of Y")
</script>
When combined with pagination:
- Pagination automatically resets to page 0 when filters change
- Page counts update based on filtered results
table.rowsshows the current page of filtered resultstable.allRowsshows all data before filtering
Initial Filters
Set filters when creating the table:
<script>
const table = reactiveTable(data, columns).use(
reactiveFiltering({
initialFilters: {
status: 'active',
city: ['New York', 'Chicago']
}
})
);
</script>
Automatic Updates
The filtering system automatically:
- Re-filters when data items change
- Re-filters when filter values change
- Updates
countandhasActiveFiltersproperties - Works reactively with Svelte 5’s
$stateand$derived
API Reference
For complete property and method documentation, see the reactiveFiltering API reference.