Searching and Filtering
When it comes to Grid, it is common to require a functionality for filtering records.
One way to accomplish that is by specifying filterParams and onCreateFilter.
<TextField
value-bind="$page.search"
icon="search"
placeholder="Search..."
/>
<Grid
records-bind="$page.employees"
columns={[
{ header: "Name", field: "fullName" },
{ header: "Phone", field: "phone" },
{ header: "City", field: "city" }
]}
emptyText="No records match the specified filter"
filterParams-bind="$page.search"
onCreateFilter={(search) => {
if (!search) return () => true;
let predicate = getSearchQueryPredicate(search);
return (record) =>
predicate(record.fullName) ||
predicate(record.phone) ||
predicate(record.city);
}}
scrollable
style={{ height: "315px" }}
/>Searching Tree Grid
Tree Grid also supports searching, but we need to separate two cases: leaf
nodes and non-leaf nodes. Leaf nodes are checked immediately to see if they
match the search query, whereas for non-leaf nodes, the match could be found
in one of the nodes further down the tree.
ControllerGrid
<TextField
value-bind="$page.treeSearch"
icon="search"
placeholder="Search..."
/>
<Grid
records-bind="$page.data"
style={{ width: "100%", height: "300px" }}
scrollable
mod="tree"
dataAdapter={{
type: TreeAdapter
}}
emptyText="No data for the specified filter."
columns={[
{
field: "fullName",
header: "Name",
items: (
<cx>
<TreeNode
expanded-bind="$record.$expanded"
leaf-bind="$record.$leaf"
level-bind="$record.$level"
loading-bind="$record.$loading"
text-bind="$record.fullName"
/>
</cx>
)
},
{
header: "Phone",
field: "phone"
},
{
header: "City",
field: "city"
}
]}
filterParams-bind="$page.treeSearch"
onCreateFilter={(search) => {
if (!search) return () => true;
search = search.toLowerCase();
return (node) => {
if (isMatch(node, search)) return true; // Found a match
if (node.$leaf) return false;
// Look for a match in the subtree
const result = findTreeNode(
node.$children,
(subNode) => isMatch(subNode, search),
"$children"
);
return result ? true : false;
}
}}
/>Disclaimer: This solution works by using onCreateFilter which calls our
search function for each node in the tree. That could cause performance
issues when working with very large trees.