FilterBar
A unified search+sort+group toolbar. Any combination of controls can be included.
Fires a single m:filterbar:change event with the full filter state
whenever any control changes. When linked to a Pagination instance via ->pager(),
the pager is automatically reset to page 1 on each change.
The JS instance provides groupSlice() — a group-aware pagination
utility that packs complete groups into pages so no group is ever split across a page boundary.
Search Only
The simplest configuration — a search box that fires m:filterbar:change on every keystroke (debounced 200 ms).
Sort Buttons Only
Button groups for sort or view-mode switching. Buttons are mutually exclusive within a group.
Sort + Group with Labels
Mix icons and labels in the same button group. Useful when the distinction between options needs to be clear.
Group-Aware Pagination
The classic pagination bug: slicing items before grouping splits groups across page
boundaries. groupSlice(items, keyFn, sortFn, perPage, pageIndex) solves this by
packing complete groups into pages greedily — a group is never split.
Changing any control below updates the page count and resets to page 1 automatically.
48 films across multiple years and genres. Set per-page to a small number (e.g. 6) to observe that changing the group dimension never leaves a partial group at the end of a page.
Basic Usage
PHP PHP Methods (Fluent)
| Method / Property | Parameters | Description |
|---|---|---|
$m->filterBar($id) | FilterBar | Create a FilterBar instance. |
->search($placeholder) | self | Add a debounced search input. Default: omitted (no search shown). |
->sort($options) | self | Add a mutually-exclusive sort button group. Each option: ['value', 'icon', 'label', 'tooltip', 'active']. Default: omitted. |
->group($options) | self | Add a mutually-exclusive group/view button group. Same option shape as sort. Default: omitted. |
->pager($pagerId) | self | Link to a Pagination element (by id). The pager resets to page 1 on every filter change. Default: omitted (no linked pager). |
->addClass($class) | self | Append extra CSS class(es) to the root element. |
->attr($name, $val) | self | Add an arbitrary HTML attribute to the root element. |
JS JS Methods
| Method / Property | Parameters | Description |
|---|---|---|
m.filterBar(id) | API object | Get the FilterBar instance for the given element id. |
getState() | { search, sort, group } | Return the current filter state object. |
setState(partial) | void | Programmatically update one or more state keys. Does NOT fire the change event or reset the linked pager. |
groupSlice(items, keyFn, sortFn, perPage, pageIndex) | { keys, groups, totalPages } | Return the groups and keys for one page using group-aware pagination (no group is ever split). pageIndex is 0-based (= pager.getState().page − 1). |
computeGroupPages(items, keyFn, sortFn, perPage) | { pages, allGroups, sortedKeys, totalPages } | Pre-compute all page buckets. Useful when you need totalPages before rendering. |
EVENT Events
| Event Name | Detail | Description |
|---|---|---|
m:filterbar:change | { search: string, sort: string, group: string } | Fired on the FilterBar element whenever any search/sort/group control changes. The linked pager (if set) resets to page 1 before this fires. |