Recipes

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 (
<Builder
ref={builderRef}
fields={fields}
data={query}
onChange={setQuery}
allowFieldComparisons
showValidation
/>
);
};

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.

© Vojtěch Václav Porteš 2026 - All library contents are available under the MIT license.
Loading privacy preferences...