Filtering Text
Create custom text filters in LyteNyte Grid. This guide covers common filters for string cell values.
Note
Applying a text filter varies depending on the row source. Refer to the guides below for each supported row data source:
While this guide focuses on using client row filtering, these filter concepts apply to all row sources.
Basic Text Filtering
LyteNyte Grid provides flexible filter capabilities that let you define any type of text filter. You can filter on contains, begins with, ends with, exact matching, or regex matching.
To create a text filter, define a function that receives a row node
and returns true to keep the row or false to remove it.
For example, the following function filters a list of products and keeps only rows
where the product name contains Xbox:
const filterXbox: Grid.T.FilterFn<GridSpec["data"]> = (row) => { return row.data.product.includes("Xbox");};Click the Show Xbox Only switch to toggle the filter state.
Filter Modifiers
Apply modifiers within the text filter function to control matching behavior. For example, convert values to lowercase to enable case-insensitive filtering:
const filterXbox: Grid.T.FilterFn<GridSpec["data"]> = (row) => { return row.data.product.toLowerCase().includes("xbox");};Expand filter logic to ignore punctuation, trim whitespace, and normalize accented characters, such as mapping “á” to “a”:
const collator = new Intl.Collator(locale, { sensitivity: "case" });const filterXbox: Grid.T.FilterFn<GridSpec["data"]> = (row) => { const product = row.data.product.trim().replace(/[!"#$%&'()*+,-./:;<=>?@[\\\]^_`{|}~]/g, "");
return collator.compare("xbox", product);};Text Filter Model
Define text filters dynamically rather than relying on predefined logic. LyteNyte Grid lets you define a filter model and a set of operations to build custom filters. This section presents one approach. Design the filter model that best fits your application’s requirements.
Begin by defining the type representation for your text filter. The code below defines a basic filter model you can use to create a filter function for the client row data source:
export type FilterStringOperator = | "equals" | "not_equals" | "begins_with" | "not_begins_with" | "ends_with" | "not_ends_with" | "contains" | "not_contains";
export interface FilterString { readonly operator: FilterStringOperator; readonly value: string;}
export interface GridFilter { readonly left: FilterString; readonly right: FilterString | null; readonly operator: "AND" | "OR";}
export interface GridSpec { readonly data: OrderData; readonly api: { readonly filterModel: PieceWritable<Record<string, GridFilter>>; };}Open the filter popover by clicking the funnel icon on the Product, Customer, or Email columns.
The code below defines the filter model. It creates filter model state and passes it to the grid API as an extension. The demo also includes a filter UI for applying filters interactively.
When a user applies a filter, useMemo creates a new filterFn, which you then pass to
the client data source. See the filter.tsx file in the demo’s expanded code for the logic
that builds the filter UI.
const [filter, setFilter] = useState<Record<string, GridFilter>>({});const filterModel = usePiece(filter, setFilter);
const filterFn = useMemo(() => { const entries = Object.entries(filter);
const evaluateStringFilter = (operator: FilterStringOperator, compare: string, value: string) => { if (operator === "equals") return value === compare; if (operator === "begins_with") return compare.startsWith(value); if (operator === "ends_with") return compare.endsWith(value); if (operator === "contains") return compare.includes(value); if (operator === "not_begins_with") return !compare.startsWith(value); if (operator === "not_ends_with") return !compare.endsWith(value); if (operator === "not_contains") return !compare.includes(value); if (operator === "not_equals") return value !== compare;
return false; };
return entries.map<Grid.T.FilterFn<GridSpec["data"]>>(([column, filter]) => { return (row) => {27 collapsed lines
const value = row.data[column as keyof GridSpec["data"]];
// This guide only covers string filters, so return false for non-string values. if (typeof value !== "string") return false;
// Perform a case-insensitive match const compareValue = value.toLowerCase();
const leftResult = evaluateStringFilter( filter.left.operator, compareValue, filter.left.value.toLowerCase(), );
if (!filter.right) return leftResult;
if (filter.operator === "OR") { return ( leftResult || evaluateStringFilter(filter.right.operator, compareValue, filter.right.value.toLowerCase()) ); }
return ( leftResult && evaluateStringFilter(filter.right.operator, compareValue, filter.right.value.toLowerCase()) ); }; });}, [filter]);Next Steps
- Filtering Numbers: Filter row data based on numerical cell values.
- Filtering Dates: Learn how to create custom date filters.
- Quick Search Filtering: Quickly find rows based on simple text searches.
