Global filtering system with pub/sub architecture for cross-component communication
Central event system that allows any component to subscribe to filter changes and react automatically.
Pills, buttons, dropdown, chips, toggle, search, radio, checkbox - choose the right style for your use case.
WCAG 2.1 AA compliant with keyboard navigation, ARIA labels, and live announcements for screen readers.
Works seamlessly with Smart Table, KPI Cards, Charts, Gallery, and any custom component.
Optional localStorage persistence keeps user filter preferences across sessions.
Designed for easy integration with RSL's JSON Layout API V2 for declarative filter configuration.
Include the CSS and JavaScript files:
<link rel="stylesheet" href="styles/filter.css">
<script src="javascript/filter.js"></script>
Create a basic filter with pills:
<div data-rsl-filter
data-filter-key="status"
data-filter-style="pills"
aria-label="Filter by status">
<button data-filter-value="all">All</button>
<button data-filter-value="active">Active</button>
<button data-filter-value="pending">Pending</button>
<button data-filter-value="completed">Completed</button>
</div>
Subscribe to filter changes in your component:
// Subscribe to filter changes
RSL.FilterBus.subscribe('my-table', function(filterState, meta) {
console.log('Filter changed:', filterState);
// filterState = { status: 'active', category: 'finance', ... }
// Filter your data based on the state
filterTableData(filterState);
});
// Unsubscribe when done
RSL.FilterBus.unsubscribe('my-table');
Live Demo:
Selected: all
| Attribute | Type | Default | Description |
|---|---|---|---|
data-rsl-filter |
- | - | Required. Marks element as a filter container. |
data-filter-key |
string | - | Required. Unique identifier for this filter (e.g., "status", "category"). |
data-filter-style |
string | "pills" | UI style: pills, buttons, dropdown, chips, toggle, search, radio, checkbox |
data-filter-multi |
boolean | false | Allow multiple values to be selected. |
data-filter-default |
string | null | Default value to select on initialization. |
data-filter-persist |
boolean | false | Persist selection to localStorage. |
data-filter-announce |
boolean | true | Announce changes to screen readers. |
data-filter-label |
string | null | Accessible label for the filter group. |
data-filter-size |
string | "md" | Size variant: sm, md, lg |
data-filter-color |
string | "primary" | Color variant: primary, success, warning, danger, info |
data-filter-show-clear |
boolean | true | Show clear button when filter is active. |
data-filter-show-count |
boolean | false | Show count badges on options. |
| Attribute | Type | Description |
|---|---|---|
data-filter-value |
string | Required. The value to publish when this option is selected. |
data-filter-label |
string | Screen reader label (defaults to element text content). |
data-filter-count |
number | Count to display in badge (requires data-filter-show-count on container). |
FilterBus is the central pub/sub system that allows any component to subscribe to filter changes. It's available globally at window.RSL.FilterBus.
| Method | Parameters | Description |
|---|---|---|
subscribe(id, callback, options) |
id: string, callback: function, options?: object | Subscribe to filter changes. Returns unsubscribe function. |
unsubscribe(id) |
id: string | Remove a subscription. |
publish(key, value, options) |
key: string, value: any, options?: object | Publish a filter change. Pass null to clear. |
batch(updates, options) |
updates: object, options?: object | Apply multiple filter changes at once. |
clear(key, options) |
key: string, options?: object | Clear a specific filter. |
clearAll(options) |
options?: object | Clear all filters. |
getState() |
- | Get current filter state as immutable copy. |
getValue(key, defaultValue) |
key: string, defaultValue?: any | Get a specific filter value. |
hasActiveFilters() |
- | Returns true if any filters are active. |
undo() |
- | Revert to previous filter state. |
persist(key) |
key: string | Enable localStorage persistence. |
restore(key) |
key: string | Restore state from localStorage. |
| Option | Type | Description |
|---|---|---|
keys |
array | Only receive updates for specific filter keys. |
immediate |
boolean | Call callback immediately with current state (default: true). |
| Method | Parameters | Description |
|---|---|---|
RSL.Filter.init() |
- | Initialize all filters on the page. |
RSL.Filter.create(element, options) |
element: HTMLElement|string, options?: object | Create a filter instance. |
RSL.Filter.destroy(element) |
element: HTMLElement|string | Destroy a filter instance. |
RSL.Filter.getInstance(element) |
element: HTMLElement|string | Get instance for an element. |
RSL.Filter.setValue(key, value) |
key: string, value: any | Set filter value programmatically. |
RSL.Filter.getValue(key) |
key: string | Get current filter value. |
RSL.Filter.clear(key) |
key: string | Clear a specific filter. |
RSL.Filter.clearAll() |
- | Clear all filters. |
RSL.Filter.getActiveFilters() |
- | Get all active filter values. |
| Event | Detail Properties | Description |
|---|---|---|
rsl-filter-change |
key, value, state, source | Fired when any filter value changes. |
rsl-filter-clear |
key, state, source, all | Fired when a filter is cleared. |
rsl-filter-ready |
key, instance | Fired when a filter UI is initialized. |
rsl-filter-bus-ready |
FilterBus, Filter | Fired when FilterBus is ready. |
The Filter component is built with accessibility as a core requirement:
role="group", role="button", aria-pressed, and aria-label attributes.aria-live region.prefers-reduced-motion user preference.Always provide an aria-label or data-filter-label attribute to describe the filter's purpose. For example: "Filter by status" or "Filter products by category".
Watch how a single Filter component can control a Smart Table in real-time. This live demo shows the power of RSL's pub/sub architecture.
View Live Dashboard DemoSee Filter + Smart Table working together
View examples.html for comprehensive demos
Test features in playground.html
Browse all RSL components