Documentation

Report Edit

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.

NamePhoneCity
Jerad Schaden804-734-6097Emilieton
Johathan Berge189-024-6725West Zakaryport
Jermey Miller127-919-9012New Jo
Zola Ryan294-841-2981West Norwoodhaven
Dena Larson098-813-2968South Declanville
Elise Gulgowski962-984-3630Andersonton
Trevion Dach517-647-7582Izaiahmouth
Norval Nitzsche111-436-5156Riceburgh
Damaris Hartmann793-684-3804Helgamouth
Alycia Cruickshank670-686-8221South Nettiefort
NamePhoneCity
<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" }}
/>
Copied!Cx Fiddle

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.

NamePhoneCity
Nayeli Bergnaum
345-753-1942Tristonhaven
Dorothea Bosco
886-291-2187Jacintoville
Mark Bishop
476-182-0113Puerto Nuevo
Sam Rempel
298-482-1184Port Lenna
Luke Jacobson
492-200-5819Sydneyland
Pavan Chernis
958-327-5723Sabovlet
Samantha-Lucy Robertson
432-698-7712Jacksonville
Kamil Oberlauf
459-320-1290Bonnstadt
Simona Pavetic
593-221-2079Kaufborgen
NamePhoneCity
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;
        }
    }}
/>
Copied!Cx Fiddle

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.