QueryBuilder
Refer to the TypeScript reference page for information about the types and interfaces referenced below.
The default export of react-querybuilder is the <QueryBuilder /> React component (also available as a named export).
QueryBuilder calls the useQueryBuilder hook to prepare the query, schema, update methods, etc., that get passed down to the subcomponents.
Subcomponents
QueryBuilder renders a RuleGroup representing the root of the query.
That root RuleGroup is nested within a <div> that has the standard queryBuilder class, any classes added by controlClassnames.queryBuilder, and data- properties with "enabled"/"disabled" values indicating whether drag-and-drop or inline combinators (showCombinatorsBetweenRules or independentCombinators) are enabled.
Finally, everything is wrapped in <QueryBuilderContext.Provider> which inherits any values from ancestor context providers and propogates them down to subcomponents (props will supersede context values).
Props
All QueryBuilder props are optional, but as stated in the getting started guide, the query builder is really only useful when, at a minimum, the fields prop is defined.
When you see RuleGroupTypeAny below (e.g. for query, defaultQuery, and onQueryChange), that means the type must either be RuleGroupType or RuleGroupTypeIC. However, if the type is RuleGroupTypeIC, then the independentCombinators prop must be set to true. Likewise, if the type is RuleGroupType then independentCombinators must be false or undefined.
fields
OptionList<Field> | Record<string, Field>
The array of fields that should be used or an array of option groups containing arrays of fields. (Alternatively, fields can be an object where the keys correspond to each field name and the values are the field definitions. If fields is an object, then the options array passed to the fieldSelector component will be sorted alphabetically by the label property.)
Field objects can also contain custom properties. Each field object will be passed in its entirety to the appropriate OperatorSelector and ValueEditor components as the fieldData prop (see the section on controlElements).
onQueryChange
(query: RuleGroupTypeAny) => void
This function is invoked whenever the query is updated from within the component. The query is provided as an object of type RuleGroupType by default. For example:
{
"combinator": "and",
"not": false,
"rules": [
{
"field": "firstName",
"operator": "=",
"value": "Steve"
},
{
"field": "lastName",
"operator": "=",
"value": "Vai"
},
{
"combinator": "and",
"rules": [
{
"field": "age",
"operator": ">",
"value": "30"
}
]
}
]
}
If the independentCombinators prop is provided, then the query argument will be of type RuleGroupTypeIC. The "IC" version of the example above would look like this:
{
"not": false,
"rules": [
{
"field": "firstName",
"operator": "=",
"value": "Steve"
},
"and",
{
"field": "lastName",
"operator": "=",
"value": "Vai"
},
"and",
{
"rules": [
{
"field": "age",
"operator": ">",
"value": "30"
}
]
}
]
}
query
RuleGroupTypeAny
The query is an object of type RuleGroupType (or RuleGroupTypeIC, if independentCombinators is true). If this prop is provided, <QueryBuilder /> will be a controlled component.
The query prop follows the same format as the parameter passed to the onQueryChange callback since they are meant to be used together to control the component. See examples.
defaultQuery
RuleGroupTypeAny
The initial query when <QueryBuilder /> is uncontrolled.
Do not provide both query and defaultQuery props. To use <QueryBuilder /> as a controlled component, provide and manage the query prop in combination with the onQueryChange callback. Use defaultQuery (or neither query prop) to render an uncontrolled component.
If both props are defined, TypeScript will throw an error during compilation and an error will be logged to the console during runtime (in "development" mode only). Errors will also be logged to the console if the query prop is defined during one render and undefined in the next, or vice versa.
context
any
A "bucket" for passing arbitrary props down to custom components (default components will ignore this prop). The context prop is passed to each and every component, so it's accessible anywhere in the QueryBuilder component tree.
operators
OptionList<Operator>
The array of operators that should be used. Custom operators must define a name and label property. An arity property, which can be "unary", "binary", or a number, may also be defined for each operator. If arity is either "unary" or a number less than 2, the value editor component will not be rendered when that operator is selected.
To build the operator list dynamically depending on a rule's field property, use getOperators. The result of getOperators, if not null, will supersede the operators prop.
The default operator list is below.
[
{ name: '=', label: '=' },
{ name: '!=', label: '!=' },
{ name: '<', label: '<' },
{ name: '>', label: '>' },
{ name: '<=', label: '<=' },
{ name: '>=', label: '>=' },
{ name: 'contains', label: 'contains' },
{ name: 'beginsWith', label: 'begins with' },
{ name: 'endsWith', label: 'ends with' },
{ name: 'doesNotContain', label: 'does not contain' },
{ name: 'doesNotBeginWith', label: 'does not begin with' },
{ name: 'doesNotEndWith', label: 'does not end with' },
{ name: 'null', label: 'is null' },
{ name: 'notNull', label: 'is not null' },
{ name: 'in', label: 'in' },
{ name: 'notIn', label: 'not in' },
{ name: 'between', label: 'between' },
{ name: 'notBetween', label: 'not between' },
];
combinators
OptionList
The array of combinators that should be used for RuleGroups. The default combinator list is below.
[
{ name: 'and', label: 'AND' },
{ name: 'or', label: 'OR' },
];
controlClassnames
Partial<Classnames>
This prop can be used to assign custom CSS classes to the various controls rendered by the <QueryBuilder /> component. Each attribute is a Classname which can be a string, string[], or Record<string, any> (see documentation for clsx):
Usage example
In the example below, any "+Rule" buttons in the query builder will have the "bold" class which might have the associated CSS rule .bold { font-weight: bold; }.
function App() {
return (
<QueryBuilder controlClassnames={{ addRule: 'bold' }}>
)
}
| Property | Classes are applied to... |
|---|---|
queryBuilder | ...the outermost <div> element |
ruleGroup | ...each <div> wrapping a group |
header | ...each <div> wrapping a group's header controls |
body | ...each <div> wrapping a group's body elements (child rules/groups) |
combinators | ...each <select> control for combinators |
addRule | ...each <button> that adds a rule |
addGroup | ...each <button> that adds a group |
cloneRule | ...each <button> that clones a rule |
cloneGroup | ...each <button> that clones a group |
removeGroup | ...each <button> that removes a group |
lockRule | ...each <button> that locks/disables a rule |
lockGroup | ...each <button> that locks/disables a group |
notToggle | ...each <label> on a "not" (aka "inversion") toggle |
rule | ...each <div> containing a rule |
fields | ...each <select> control for selecting a field |
operators | ...each <select> control for selecting an operator |
value | ...each <input> for entering a value |
removeRule | ...each <button> that removes a rule |
dragHandle | ...each <span> acting as a drag handle |
valueSource | ...each <select> control for selecting a value source |
controlElements
Partial<Controls>
This object allows you to override the default components.
Usage example
function App() {
return (
<QueryBuilder controlElements={{ valueEditor: CustomValueEditor }}>
)
}
The following control overrides are supported per the Controls interface:
| Property | Type |
|---|---|
addGroupAction | React.ComponentType<ActionWithRulesAndAddersProps> |
addRuleAction | React.ComponentType<ActionWithRulesAndAddersProps> |
cloneGroupAction | React.ComponentType<ActionWithRulesProps> |
cloneRuleAction | React.ComponentType<ActionProps> |
combinatorSelector | React.ComponentType<CombinatorSelectorProps> |
dragHandle | React.ForwardRefExoticComponent<DragHandleProps & React.RefAttributes<HTMLSpanElement>> |
fieldSelector | React.ComponentType<FieldSelectorProps> |
inlineCombinator | React.ComponentType<InlineCombinatorProps> |
lockGroupAction | React.ComponentType<ActionWithRulesProps> |
lockRuleAction | React.ComponentType<ActionProps> |
notToggle | React.ComponentType<NotToggleProps> |
operatorSelector | React.ComponentType<OperatorSelectorProps> |
removeGroupAction | React.ComponentType<ActionWithRulesProps> |
removeRuleAction | React.ComponentType<ActionProps> |
rule | React.ComponentType<RuleProps> |
ruleGroup | React.ComponentType<RuleGroupProps> |
valueEditor | React.ComponentType<ValueEditorProps> |
valueSourceSelector | React.ComponentType<ValueSourceSelectorProps> |
addGroupAction
Default is ActionElement. Receives the following props per the ActionWithRulesAndAddersProps interface:
| Prop | Type | Description |
|---|---|---|
label | string | translations.addGroup.label, e.g. "+Group" |
title | string | translations.addGroup.title, e.g. "Add group" |
className | string | CSS classNames to be applied |
handleOnClick | (e: React.MouseEvent, context?: any) => void | Adds a new sub-group to this group |
rules | RuleOrGroupArray | The rules array for this group |
ruleOrGroup | RuleGroupTypeAny | This group |
level | number | The level of this group |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this group |
disabled | boolean | Whether this group is disabled/locked |
path | number[] | Path of this group |
schema | Schema | Query schema |
addRuleAction
Default is ActionElement. Receives the following props per the ActionWithRulesAndAddersProps interface:
| Prop | Type | Description |
|---|---|---|
label | string | translations.addGroup.label, e.g. "+Rule" |
title | string | translations.addGroup.title, e.g. "Add rule" |
className | string | CSS classNames to be applied |
handleOnClick | (e: React.MouseEvent, context?: any) => void | Adds a new rule to this group |
rules | RuleOrGroupArray | The rules array for this group |
ruleOrGroup | RuleGroupTypeAny | This group |
level | number | The level of this group |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this group |
disabled | boolean | Whether this group is disabled/locked |
path | number[] | Path of this group |
schema | Schema | Query schema |
cloneGroupAction
Default is ActionElement. Receives the following props per the ActionWithRulesProps interface:
| Prop | Type | Description |
|---|---|---|
label | string | translations.addGroup.label, e.g. "+Group" |
title | string | translations.addGroup.title, e.g. "Add group" |
className | string | CSS classNames to be applied |
handleOnClick | (e: React.MouseEvent) => void | Clones this group |
rules | RuleOrGroupArray | The rules array for this group |
ruleOrGroup | RuleGroupTypeAny | This group |
level | number | The level of this group |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this group |
disabled | boolean | Whether this group is disabled/locked |
path | number[] | Path of this group |
schema | Schema | Query schema |
cloneRuleAction
Default is ActionElement. Receives the following props per the ActionProps interface:
| Prop | Type | Description |
|---|---|---|
label | string | translations.addGroup.label, e.g. "+Rule" |
title | string | translations.addGroup.title, e.g. "Add rule" |
className | string | CSS classNames to be applied |
handleOnClick | (e: React.MouseEvent) => void | Clones the rule |
ruleOrGroup | RuleType | This rule |
level | number | The level of this rule |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this rule |
disabled | boolean | Whether this rule is disabled/locked |
path | number[] | Path of this rule |
schema | Schema | Query schema |
combinatorSelector
Default is ValueSelector. Receives the following props per the CombinatorSelectorProps interface:
| Prop | Type | Description |
|---|---|---|
options | OptionList | Same as combinators prop passed into QueryBuilder |
value | string | Selected combinator from the existing query representation, if any |
className | string | CSS classNames to be applied |
handleOnChange | (value: any) => void | Updates the group's combinator |
rules | RuleOrGroupArray | The rules array for this group |
title | string | translations.combinators.title, e.g. "Combinators" |
level | number | The level of this group |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this group |
disabled | boolean | Whether this group is disabled/locked |
path | number[] | Path of this group |
schema | Schema | Query schema |
dragHandle
Default is DragHandle. Note that this component must be based on React.forwardRef, and must always render an element (never return null). Receives the forwarded ref and the following props per the DragHandleProps interface:
| Prop | Type | Description |
|---|---|---|
title | string | translations.dragHandle.title, e.g. "Drag handle" |
label | string | translations.dragHandle.label, e.g. "⁞⁞" |
className | string | CSS classNames to be applied |
level | number | The level of this rule/group |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this rule/group |
disabled | boolean | Whether this rule/group is disabled/locked |
path | number[] | Path of this rule/group |
schema | Schema | Query schema |
fieldSelector
Default is ValueSelector. Receives the following props per the FieldSelectorProps interface:
| Prop | Type | Description |
|---|---|---|
options | Field[] | Same as fields prop passed into QueryBuilder |
value | string | Selected field from the existing query representation, if any |
title | string | translations.fields.title, e.g. "Fields" |
operator | string | Selected operator from the existing query representation, if any |
className | string | CSS classNames to be applied |
handleOnChange | (value: any) => void | Updates the rule's field |
level | number | The level of this rule |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this rule |
disabled | boolean | Whether this rule is disabled/locked |
path | number[] | Path of this rule |
schema | Schema | Query schema |
inlineCombinator
A small wrapper around the combinatorSelector component. Receives the following props per the InlineCombinatorProps interface (which extends CombinatorSelectorProps):
| Prop | Type | Description |
|---|---|---|
component | Schema['controls']['combinatorSelector'] | Same as the combinatorSelector component |
independentCombinators | boolean | undefined | Same as independentCombinators prop passed in to QueryBuilder |
lockGroupAction
Default is ActionElement. Receives the following props per the ActionWithRulesProps interface:
| Prop | Type | Description |
|---|---|---|
label | string | translations.lockGroup.label, e.g. "🔓" when unlocked and "🔒" when locked |
title | string | translations.lockGroup.title, e.g. "Lock group" or "Unlock group" |
className | string | CSS classNames to be applied |
handleOnClick | (e: React.MouseEvent) => void | Locks the group |
rules | RuleOrGroupArray | The rules present for this group |
ruleOrGroup | RuleGroupTypeAny | This group |
level | number | The level of this group |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this group |
disabled | boolean | Whether this group is disabled/locked |
disabledTranslation | string | translations.lockGroupDisabled if parent group is not disabled, otherwise undefined |
path | number[] | Path of this group |
schema | Schema | Query schema |
lockRuleAction
Default is ActionElement. Receives the following props per the ActionWithRulesProps interface:
| Prop | Type | Description |
|---|---|---|
label | string | translations.lockRule.label, e.g. "🔓" when unlocked and "🔒" when locked |
title | string | translations.lockRule.title, e.g. "Lock rule" or "Unlock rule" |
className | string | CSS classNames to be applied |
handleOnClick | (e: React.MouseEvent) => void | Locks the rule |
ruleOrGroup | RuleType | This rule |
level | number | The level of this rule |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this rule |
disabled | boolean | Whether this rule is disabled/locked |
disabledTranslation | string | translations.lockRuleDisabled if parent group is not disabled, otherwise undefined |
path | number[] | Path of this rule |
schema | Schema | Query schema |
notToggle
Default is NotToggle. Receives the following props per the NotToggleProps interface:
| Prop | Type | Description |
|---|---|---|
label | string | translations.notToggle.label, e.g. "Not" |
title | string | translations.notToggle.title, e.g. "Invert this group" |
className | string | CSS classNames to be applied |
handleOnChange | (checked: boolean) => void | Updates the group's not property |
checked | boolean | Whether the input should be checked or not |
level | number | The level of this group |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this group |
disabled | boolean | Whether this group is disabled/locked |
path | number[] | Path of this group |
schema | Schema | Query schema |
operatorSelector
Default is ValueSelector. Receives the following props per the OperatorSelectorProps interface:
| Prop | Type | Description |
|---|---|---|
field | string | Field name corresponding to this rule |
fieldData | Field | The entire object from the fields array for this field |
options | OptionList<Operator> | Return value of getOperators(field) |
value | string | Selected operator from the existing query representation, if any |
title | string | translations.operators.title, e.g. "Operators" |
className | string | CSS classNames to be applied |
handleOnChange | (value: any) => void | Updates the rule's operator |
level | number | The level of this rule |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this rule |
disabled | boolean | Whether this rule is disabled/locked |
path | number[] | Path of this rule |
schema | Schema | Query schema |
removeGroupAction
Default is ActionElement. Receives the following props per the ActionWithRulesProps interface:
| Prop | Type | Description |
|---|---|---|
label | string | translations.removeGroup.label, e.g. "x" |
title | string | translations.removeGroup.title, e.g. "Remove group" |
className | string | CSS classNames to be applied |
handleOnClick | (e: React.MouseEvent) => void | Removes the group |
rules | RuleOrGroupArray | The rules array for this group |
ruleOrGroup | RuleGroupTypeAny | This group |
level | number | The level of this group |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this group |
disabled | boolean | Whether this group is disabled/locked |
path | number[] | Path of this group |
schema | Schema | Query schema |
removeRuleAction
Default is ActionElement. Receives the following props per the ActionProps interface:
| Prop | Type | Description |
|---|---|---|
label | string | translations.removeRule.label, e.g. "x" |
title | string | translations.removeRule.title, e.g. "Remove rule" |
className | string | CSS classNames to be applied |
handleOnClick | (e: React.MouseEvent) => void | Removes the rule |
ruleOrGroup | RuleType | This rule |
level | number | The level of this rule |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this rule |
disabled | boolean | Whether this rule is disabled/locked |
path | number[] | Path of this rule |
schema | Schema | Query schema |
rule
Default is Rule. Receives the following props per the RuleProps interface:
| Prop | Type | Description |
|---|---|---|
id | string | Unique identifier for this rule |
path | number[] | Path of this rule |
rule | RuleType | The rule object |
translations | Translations | The default translations merged with the translations prop |
schema | Schema | Query schema |
actions | QueryActions | Query update functions |
context | any | Container for custom props that are passed to all components |
disabled | boolean | Whether the rule itself is disabled |
parentDisabled | boolean | Whether the parent group of this rule is disabled |
If you enable drag-and-drop and want to use a custom Rule component, use the controlElements prop on the QueryBuilderDnD context provider instead of QueryBuilder.
ruleGroup
Default is RuleGroup. Receives the following props per the RuleGroupProps interface:
| Prop | Type | Description |
|---|---|---|
id | string | Unique identifier for this group |
path | number[] | Path of this group |
ruleGroup | RuleGroupTypeAny | The group object |
translations | Translations | The default translations merged with the translations prop |
schema | Schema | Query schema |
actions | QueryActions | Query update functions |
context | any | Container for custom props that are passed to all components |
disabled | boolean | Whether the group itself is disabled |
parentDisabled | boolean | Whether the parent group of this group is disabled |
If you enable drag-and-drop and want to use a custom RuleGroup component, use the controlElements prop on the QueryBuilderDnD context provider instead of QueryBuilder.
valueEditor
Default is ValueEditor. Receives the following props per the ValueEditorProps interface:
| Prop | Type | Description |
|---|---|---|
field | string | Field name corresponding to this rule |
fieldData | Field | The entire object from the fields array for this field |
operator | string | Operator name corresponding to this rule |
value | string | value from the existing query representation, if any |
title | string | translations.value.title, e.g. "Value" |
handleOnChange | (value: any) => void | Updates the rule's value |
type | ValueEditorType | Type of editor to be displayed |
inputType | string | Intended @type attribute of the <input>, if type prop is "text" |
values | any[] | List of available values for this rule |
className | string | CSS classNames to be applied |
valueSource | ValueSource | Value source for this rule |
listsAsArrays | boolean | Whether to manage value lists (i.e. "between"/"in" operators) as arrays |
parseNumbers | boolean | Whether to parse real numbers from strings |
separator | ReactNode | Separator element for series of editors (i.e. "between" operator) |
level | number | The level of this rule |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this rule |
disabled | boolean | Whether this rule is disabled/locked |
path | number[] | Path of this rule |
schema | Schema | Query schema |
valueSourceSelector
Default is ValueSelector. Receives the following props per the ValueSourceSelectorProps interface:
| Prop | Type | Description |
|---|---|---|
field | string | Field name corresponding to this rule |
fieldData | Field | The entire object from the fields array for the selected field |
options | OptionList<ValueSourceOption> | Return value of getValueSources(field, operator) |
value | ValueSource | Selected value source for this rule, if any |
title | string | translations.valueSourceSelector.title, e.g. "Value source" |
className | string | CSS classNames to be applied |
handleOnChange | (value: any) => void | Updates the rule's valueSource |
level | number | The level of this rule |
context | any | Container for custom props that are passed to all components |
validation | boolean | ValidationResult | Validation result of this rule |
disabled | boolean | Whether this rule is disabled/locked |
path | number[] | Path of this rule |
schema | Schema | Query schema |
getOperators
(field: string) => OptionList<Operator> | null
This function is invoked to get the list of allowed operators for the given field. If null is returned, the operators prop is used (or the default operators if the operators prop is not defined).
getValueEditorType
(field: string, operator: string) => ValueEditorType
This function is invoked to get the type of ValueEditor for the given field and operator. Allowed values are "text" (the default if the function is not provided or if null is returned), "select", "multiselect", "checkbox", "radio", "textarea", and "switch".
getValueSources
(field: string, operator: string) => ValueSources;
This function is invoked to get the list of allowed value sources for a given field and operator. The return value must be an array with one or two elements: "value", "field", or both (in either order). If the prop is not defined, () => ["value"] is used. The first element in the array will be the initial selection.
getValueEditorSeparator
(field: string, operator: string) => ReactNode;
This function should return the separator element for a given field and operator. It will be placed in between value editors when multiple are rendered, e.g. when the operator is "between". The element can be any valid React element, including a plain string (e.g. "and" or "to") or an HTML element like <span />.
getInputType
(field: string, operator: string) => string
This function is invoked to get the type attribute which will be applied to the rendered <input /> for the given field and operator. This prop is only applicable when getValueEditorType returns "text" or a falsy value. If no function is provided, "text" is used.
getValues
(field: string, operator: string) => OptionList
This function is invoked to get the list of allowed values for the given field and operator. This prop is only applicable when getValueEditorType returns "select", "multiselect", or "radio". If no function is provided, an empty array is used.
getDefaultField
string | ((fieldsData: OptionList<Field>) => string)
The default field for new rules. This can be a field name or a function that returns a field name based on the fields prop.
getDefaultOperator
string | ((field: string) => string)
The default operator for new rules. This can be an operator name or a function that returns an operator name.
getDefaultValue
(rule: RuleType) => any
This function returns the default value for new rules based on the existing rule properties.
getRuleClassname
(rule: RuleType) => Classname
Generate custom classes which will be added to the outer div of a rule based on the rule properties.
getRuleGroupClassname
(ruleGroup: RuleGroupTypeAny) => Classname
Generate custom classes which will be added to the outer div of a group based on the group properties.
onAddRule
(rule: RuleType, parentPath: number[], query: RuleGroupTypeAny, context?: any) => RuleType | false
This callback is invoked immediately before a new rule is added. The function should either manipulate the rule and return it as an object of type RuleType or return false to cancel the addition of the rule. You can use findPath to locate the parent group to which the new rule will be added within the query hierarchy. The context parameter (fourth argument) can be passed from a custom addRuleAction component to its onHandleClick prop, which will in turn pass it to onAddRule. This allows one to change the rule that gets added (or avoid the action completely) based on arbitrary data.
If independentCombinators is enabled, you can specify the combinator inserted immediately before the new rule (if the parent group is not empty) by adding a combinatorPreceding property (with a combinator name as the value) to the rule before returning it. Otherwise the combinator preceding the last rule, or the first combinator in the default list if the parent group has only one rule, will be used.
To completely prevent the addition of new rules, pass controlElements={{ addRuleAction: () => null }} which will prevent the "+Rule" button from rendering.
onAddGroup
<RG extends RuleGroupTypeAny>(ruleGroup: RG, parentPath: number[], query: RG, context?: any) => RG | false
This callback is invoked before a new group is added. The function should either manipulate the group and return it as an object of the same type (either RuleGroupType or RuleGroupTypeIC), or return false to cancel the addition of the group. You can use findPath to locate the parent group to which the new group will be added within the query hierarchy. The context parameter (fourth argument) can be passed from a custom addGroupAction component to its onHandleClick prop, which will in turn pass it to onAddGroup. This allows one to change the group that gets added (or avoid the action completely) based on arbitrary data.
If independentCombinators is enabled, you can specify the combinator inserted immediately before the new group (if the parent group is not empty) by adding a combinatorPreceding property (with a combinator name as the value) to the group before returning it. Otherwise the combinator preceding the last rule, or the first combinator in the default list if the parent group has only one rule, will be used.
To completely prevent the addition of new groups, pass controlElements={{ addGroupAction: () => null }} which will prevent the "+Group" button from rendering.
onRemove
<RG extends RuleGroupTypeAny>(ruleOrGroup: RG | RuleType, path: number[], query: RG, context?: any) => boolean
This callback is invoked before a rule or group is removed. The function should return true if the removal should proceed as normal, or false if the removal should be aborted.
translations
Partial<Translations>
This prop can be used to override translatable texts applied to various controls that are created by the <QueryBuilder /> component. All keys in the object and all properties within each key are optional. Missing translations will default to the corresponding values below.
{
"fields": {
"title": "Fields",
"placeholderName": "~",
"placeholderLabel": "------",
"placeholderGroupLabel": "------"
},
"operators": {
"title": "Operators",
"placeholderName": "~",
"placeholderLabel": "------",
"placeholderGroupLabel": "------"
},
"value": {
"title": "Value"
},
"removeRule": {
"label": "x",
"title": "Remove rule"
},
"removeGroup": {
"label": "x",
"title": "Remove group"
},
"addRule": {
"label": "+Rule",
"title": "Add rule"
},
"addGroup": {
"label": "+Group",
"title": "Add group"
},
"combinators": {
"title": "Combinators"
},
"notToggle": {
"label": "Not",
"title": "Invert this group"
},
"cloneRule": {
"label": "⧉",
"title": "Clone rule"
},
"cloneRuleGroup": {
"label": "⧉",
"title": "Clone group"
},
"dragHandle": {
"label": "⁞⁞",
"title": "Drag handle"
},
"lockRule": {
"label": "🔓",
"title": "Lock rule"
},
"lockGroup": {
"label": "🔓",
"title": "Lock group"
},
"lockRuleDisabled": {
"label": "🔒",
"title": "Unlock rule"
},
"lockGroupDisabled": {
"label": "🔒",
"title": "Unlock group"
}
}
showCombinatorsBetweenRules
boolean (default false) Click here for demo
Pass true to render the combinator selector between each child rule/group in the group body instead of in the group header. This can make some queries easier to understand as it encourages a more natural style of reading.
Note that when this option is enabled, the combinator property is still managed at the group level even though selectors are displayed among the rules. Selecting a new combinator with one of the inline selectors will update all combinator selectors within the same group since they all use the same value. To display inline combinator selectors that are managed independently, use the independentCombinators prop.
showNotToggle
boolean (default false) Click here for demo
Pass true to display the "Not" (aka inversion) toggle switch for each rule group.
showCloneButtons
boolean (default false) Click here for demo
Pass true to display a "clone" button on each group header and rule. Clicking a "clone" button will create an exact duplicate (with new id/ids) of the rule or group, positioned immediately after the original, within the same rules array.
showLockButtons
boolean (default false) Click here for demo
Pass true to display the "Lock rule" and "Lock group" buttons. When a rule is locked, all elements within the rule will be disabled except for the lock button itself (so the user can unlock the rule). When a group is locked, all elements within the group header (except the lock button itself), as well as all child rule/group elements (including their lock buttons), will be disabled.
resetOnFieldChange
boolean (default true) Click here for demo with this feature disabled
Pass false to avoid resetting the operator and value when the field is updated.
resetOnOperatorChange
boolean (default false) Click here for demo
Pass true to reset the value when the operator is updated.
enableMountQueryChange
boolean (default true)
Pass false to disable the onQueryChange call on initial mount of the component. This is enabled by default because the query/defaultQuery prop is processed during the first render and may be slightly different than the object passed in (ids would have been generated if they were missing, for example).
autoSelectField
boolean (default true) Click here for demo with this feature disabled
Pass false to automatically add an "empty" option (value "~" and label "------"; see translations.fields.placeholder* to customize) to the fields array as the first element. The "empty" option will be the initial field selection for all new rules. When the empty field option is selected, the operator selector and value components will not be rendered for that rule.
autoSelectOperator
boolean (default true) Click here for demo with this feature disabled
Pass false to automatically add an "empty" option (value "~" and label "------"; see translations.operators.placeholder* to customize) to the operators array as the first element. The "empty" option will be the initial operator selection for all new rules. When the empty operator option is selected, the value components will not be rendered for that rule.
addRuleToNewGroups
boolean (default false) Click here for demo
Pass true to automatically add a rule to new groups. If neither a query nor defaultQuery prop is not passed in, a rule will be added to the root group when the component is mounted. If a query/defaultQuery prop is passed in with an empty rules array, no rule will be added automatically.
listsAsArrays
boolean (default false) Click here for demo
Pass true to update rule values that represent lists with proper arrays instead of comma-separated strings. This prop applies when valueEditorType is "multiselect" and when a rule's operator is "between", "notBetween", "in", or "notIn".
For example, the default behavior for the "between" operator might produce this rule:
{
"field": "f1",
"operator": "between",
"value": "f2,f3",
"valueSource": "field"
}
When listsAsArrays is true, the rule's value will be an array:
{
"field": "f1",
"operator": "between",
"value": ["f2", "f3"],
"valueSource": "field"
}
parseNumbers
boolean | "strict" | "native" (default false) Click here for demo
Pass true, "strict", or "native" to store value as a number instead of a string (when possible). Passing "native" will use parseFloat to determine if a value is numeric, while true or "strict" will use a more strict algorithm that requires the value to be numeric in its entirety (not just start with a number as parseFloat requires). See more information in the note about the corresponding formatQuery option.
independentCombinators
boolean (default false) Click here for demo
Pass true to insert an independent combinator selector between each child rule/group within the body of a group. A combinator selector will not be rendered in group headers.
Visually, this option has a similar effect as the showCombinatorsBetweenRules option, except that each combinator selector is independently controlled. You may find that users take to this configuration more easily, as it can allow them to express queries more like they would in natural language.
When the independentCombinators option is enabled, the query (or defaultQuery) prop must be of type RuleGroupTypeIC instead of the default RuleGroupType. See onQueryChange above, or the Rules and groups section of the TypeScript documentation for more information.
enableDragAndDrop
boolean (default false) Click here for demo
This prop does not need to be set directly on the <QueryBuilder /> component. It has no effect unless the following conditions are met:
- A
QueryBuilderDnDcontext provider from the companion package@react-querybuilder/dndis rendered higher up in the component tree. react-dndandreact-dnd-html5-backendare installed/imported.
If those conditions are met, and enableDragAndDrop is not explicitly set to false on the <QueryBuilder /> component, then enableDragAndDrop is implicitly true.
When true (under the conditions detailed above), a drag handle is displayed on the left-hand side of each group header and each rule. Clicking and dragging the handle element allows users to visually reorder the rules and groups.
Recommended usage
yarn add react-querybuilder @react-querybuilder/dnd react-dnd react-dnd-html5-backend
import { QueryBuilderDnD } from '@react-querybuilder/dnd';
import * as ReactDnD from 'react-dnd';
import * as ReactDndHtml5Backend from 'react-dnd-html5-backend';
import { QueryBuilder } from 'react-querybuilder';
const App = () => (
<QueryBuilderDnD dnd={{ ...ReactDnD, ...ReactDndHtml5Backend }}>
<QueryBuilder />
</QueryBuilderDnD>
);
If your application already uses react-dnd, use QueryBuilderDndWithoutProvider instead of QueryBuilderDnD. They are functionally equivalent, but the former assumes a <DndProvider /> already exists higher up in the component tree. The latter renders its own DndProvider which will conflict with any pre-existing ones. (If you use the wrong component, you will probably see the error message "Cannot have two HTML5 backends at the same time" in the console.)
disabled
Use the disabled property on rules and groups within the query object instead.
boolean | number[][] (default false) Click here for demo
Pass true to disable all subcomponents and prevent changes to the query. Pass an array of paths to disable specific rules and/or groups. For example, disabled={[[0]]} will disable the top-most rule/group and its subcomponents, but nothing else.
debugMode
boolean (default false) Click here for demo
Pass true to enabled logging debug information with the onLog function.
onLog
(message: any) => void (default console.log)
Receives logging messages when debugMode is true.
idGenerator
() => string (default generateID)
Used to generate ids for rules and groups without them (or clones that need a new id). By default, QueryBuilder generates valid v4 UUIDs per RFC 4122, using the crypto package if available or a Math.random()-based method otherwise.
validator
QueryValidator Click here for demo
This function is executed each time QueryBuilder renders. The return value should be a boolean (true for valid queries, false for invalid) or an object whose keys are the ids of each validated rule and group in the query tree. If an object is returned, the values associated to each key should be a boolean (true for valid rules/groups, false for invalid) or an object with a valid boolean property and an optional reasons array. The full object will be passed to each rule and group component, and all sub-components of each rule/group will receive the value associated with the id of its rule or group. See the validation documentation for more information.