Dynamic Query Operators by Field Type
Choose suitable operators and inputs for text, number, date, yes/no, list, empty-value, and field-to-field comparisons.
What this recipe builds
- Operators that match each field data type.
- Static lists plus options that can change for a field or individual rule.
- Optional comparisons between compatible fields.
Loading the interactive recipe demo...
Install and imports
Install / imports
npm install @vojtechportes/react-query-builder
Fields and initial query
Typed field configuration
import type {DenormalizedQuery,IBuilderFieldProps,} from '@vojtechportes/react-query-builder';const statusOptions = [{ value: 'OPEN', label: 'Open' },{ value: 'CLOSED', label: 'Closed' },];const fields: IBuilderFieldProps[] = [{field: 'name',label: 'Name',type: 'TEXT',operators: ['EQUAL', 'CONTAINS', 'IS_NULL'],},{field: 'amount',label: 'Amount',type: 'NUMBER',operators: ['EQUAL', 'LARGER', 'BETWEEN'],},{field: 'createdAt',label: 'Created',type: 'DATE',operators: ['EQUAL', 'SMALLER', 'LARGER'],},{ field: 'active', label: 'Active', type: 'BOOLEAN' },{field: 'status',label: 'Status',type: 'LIST',value: statusOptions,operators: ['EQUAL', 'NOT_EQUAL', 'IN'],},{field: 'approvedAmount',label: 'Approved amount',type: 'NUMBER',fieldComparison: { type: 'number', comparableFields: ['amount'] },},];const initialQuery: DenormalizedQuery = [{ type: 'GROUP', value: 'AND', isNegated: false, children: [] },];
Builder implementation
React implementation
import '@vojtechportes/react-query-builder/styles.css';import React from 'react';import {Builder,type DenormalizedQuery,type IBuilderFieldProps,useBuilderRef,} from '@vojtechportes/react-query-builder';const statusOptions = [{ value: 'OPEN', label: 'Open' },{ value: 'CLOSED', label: 'Closed' },];const fields: IBuilderFieldProps[] = [{field: 'name',label: 'Name',type: 'TEXT',operators: ['EQUAL', 'CONTAINS', 'IS_NULL'],},{field: 'amount',label: 'Amount',type: 'NUMBER',operators: ['EQUAL', 'LARGER', 'BETWEEN'],},{field: 'createdAt',label: 'Created',type: 'DATE',operators: ['EQUAL', 'SMALLER', 'LARGER'],},{ field: 'active', label: 'Active', type: 'BOOLEAN' },{field: 'status',label: 'Status',type: 'LIST',value: statusOptions,operators: ['EQUAL', 'NOT_EQUAL', 'IN'],},{field: 'approvedAmount',label: 'Approved amount',type: 'NUMBER',fieldComparison: { type: 'number', comparableFields: ['amount'] },},];const initialQuery: DenormalizedQuery = [{ type: 'GROUP', value: 'AND', isNegated: false, children: [] },];export const DynamicOperatorFilter = () => {const [query, setQuery] = React.useState(initialQuery);const builderRef = useBuilderRef();React.useEffect(() => {builderRef.current?.setFieldOptions('status', statusOptions);}, [builderRef]);return (<Builderref={builderRef}fields={fields}data={query}onChange={setQuery}allowFieldComparisonsshowValidation/>);};
Update list options while the app is running
Update list options while the app is running
const builderRef = useBuilderRef();builderRef.current?.setFieldOptions('status', statusOptions);// Pass builderRef to <Builder ref={builderRef} />.
Validation and safety
- Your server should check that each field is used only with supported operators.
- Treat hidden or disabled UI choices as presentation, not access control.
Production notes
- Define how your application treats null and empty values.
- Clear or replace values that are no longer valid when available options change.
Related guides
Frequently asked questions
What happens when a user changes the field in an existing rule?
Check whether the current operator and value still work with the new field. Clear or replace them when they do not.
Can the value options depend on another field?
Yes. Update the available options when the related field changes, then clear or replace values that are no longer valid.