Searching and Filtering
import { getSearchQueryPredicate } from 'cx/util'; Copied Grids support client-side filtering using filterParams and onCreateFilter. This is ideal for filtering data already loaded in the browser.
<div controller={PageController}>
<div className="flex gap-4 mb-4">
<TextField value={m.search} icon="search" placeholder="Search..." />
<LookupField
value={m.cityFilter}
options={m.cities}
placeholder="Filter by city..."
style="width: 200px"
/>
</div>
<Grid
records={m.employees}
columns={[
{ header: "Name", field: "fullName", sortable: true },
{ header: "Phone", field: "phone" },
{ header: "City", field: "city", sortable: true },
]}
style="height: 300px"
scrollable
emptyText="No records match the filter criteria"
filterParams={{ search: m.search, city: m.cityFilter }}
onCreateFilter={(params: { search: string; city: string }) => {
let { search, city } = params || {}
let predicate = search ? getSearchQueryPredicate(search) : null
return (record: Employee) => {
if (city && record.city !== city) return false
if (predicate) {
return (
predicate(record.fullName) ||
predicate(record.phone) ||
predicate(record.city)
)
}
return true
}
}}
/>
</div> Filter by city...
| Name | Phone | City |
|---|---|---|
| Alice Johnson | 555-1234 | New York |
| Bob Smith | 555-2345 | Los Angeles |
| Carol White | 555-3456 | Chicago |
| David Brown | 555-4567 | Houston |
| Eva Green | 555-5678 | Phoenix |
| Frank Miller | 555-6789 | New York |
| Grace Lee | 555-7890 | Chicago |
| Henry Wilson | 555-8901 | Los Angeles |
Type in the search field to filter records across all fields. Use the city dropdown to filter by a specific city. Both filters can be combined.
How It Works
The filterParams property holds the current filter state. It can be a single value or an object with multiple filter criteria. Whenever it changes, onCreateFilter is called to create a new predicate function:
<Grid
records={m.employees}
filterParams={{ search: m.search, city: m.cityFilter }}
onCreateFilter={(params: { search: string; city: string }) => {
let { search, city } = params || {};
let predicate = search ? getSearchQueryPredicate(search) : null;
return (record) => {
if (city && record.city !== city) return false;
if (predicate) {
return (
predicate(record.fullName) ||
predicate(record.phone) ||
predicate(record.city)
);
}
return true;
};
}}
/>
The getSearchQueryPredicate utility creates a case-insensitive predicate that supports multiple search terms. Records pass the filter if any field matches all search terms.
Configuration
| Property | Type | Description |
|---|---|---|
filterParams | Prop | Parameters passed to onCreateFilter when they change. |
onCreateFilter | function | Callback that receives filterParams and returns a predicate function (record) => boolean. |
emptyText | string | Text displayed when no records match the filter. |