QueryBuilder
This component allows you to create conditions and group them using logical operators. It outputs a structured set of rules which can be easily parsed to create SQL/NoSQL/whatever queries.
Take a look at the usage page to learn more about this component.
How to use
The query builder component enables you to create conditions and then group them using logical operators to create structured sets of rules. The output of this component can be easily parsed to create SQL, NoSQL, or any other type of query depending on your use case.
Attributes
To use this component, you’ll need to define your attributes using the attributes
property. This property receives an object with all the attributes you’ll be able to choose from to create conditions in the query builder.
An attribute has the following specification:
interface HvQueryBuilderAttribute {
id?: string;
label: string;
type: "boolean" | "numeric" | "dateandtime" | "text" | "textarea" | string;
}
The depth of the query, i.e. the number of nested query groups, can be controlled through the maxDepth
where the default value is 1
.
Furthermore, confirmation dialogs will always be shown by default when removing a condition or group.
To change this behavior, the disableConfirmation
property is available. If you need your QueryBuilder to be read-only, you can set the readOnly
property to true
.
The query builder already has 5 built-in attribute types, boolean
, numeric
, text
, textarea
, and dateandtime
, but custom ones can be created if needed.
Find below an example for the attributes property using custom and built-in attribute types.
const attributes: HvQueryBuilderProps["attributes"] = {
attr1: {
label: "Numeric",
type: "numeric",
},
attr2: {
label: "Text",
type: "text",
},
attr3: {
label: "Text Area",
type: "textarea",
},
attr4: {
label: "Boolean",
type: "boolean",
},
attr5: {
label: "Date & Time",
type: "dateandtime",
},
attr6: {
label: "Custom",
type: "custom",
},
};
Combinators
The query builder already has 2 default combinator operands used out of the box: or
and and
. This set of combinators enables you to define how your conditions can be combined together.
If you want to override the default combinators and define new ones, you can use the combinators
property that receives an array of combinators where each combinator has the following specification:
interface HvQueryBuilderQueryCombinator {
operand: string;
label: string;
}
Find an example of combinators below.
const combinators: HvQueryBuilderProps["combinators"] = [
{ operand: "or", label: "OR" },
{ operand: "and", label: "AND" },
];
Operators
After defining your attributes
, you’ll need to specify the operators for each one of your attribute types through the operators
property. This property enables you to define the conditions’ operators by attribute type and combinator.
The query builder already has default operators
for each built-in attribute type and they are used out of the box. The default operators are available through the hvQueryBuilderDefaultOperators
object exported by UI Kit’s core
package. However, you’ll most likely need to override these operators depending on your use case.
An operator has the following specification:
interface HvQueryBuilderQueryOperator {
operator: string;
label: string;
combinators: string[];
}
Find below an example for the operators
property.
const operators: HvQueryBuilderProps["operators"] = {
// Using the default operators for the "boolean", "numeric", "text", "textarea", and "dateandtime" attribute types
...hvQueryBuilderDefaultOperators,
// Defining the operators for the "custom" attribute type
custom: [
{
operator: "equalsTo",
label: "Equal to (=)",
combinators: ["and", "or"],
},
{
operator: "notEqual",
label: "Not equal to (!=)",
combinators: ["and", "or"],
},
{
operator: "Empty",
label: "Empty",
combinators: ["and", "or"],
},
],
};
Initial query
you can pass an initial query to the query builder using the defaultValue
property. Use the disableConfirmation
property to disable the confirmation dialogs.
Jan 1, 2021
Renderers
Having attributes
, operators
, and combinators
enables you to have a fully functional query builder since this component already has some intrinsic behavior.
For instance, the query builder already has built-in value renderers, i.e. inputs to type the condition’s value, for the default attribute types boolean
, numeric
, text
, textarea
, and dateandtime
. For custom attribute types, a basic text input is rendered by default. Moreover, if the range
operator is selected, the condition’s value is cleared automatically, and the value renderer updates to range inputs for the numeric
and dateandtime
attribute types.
This component also has a default behavior for the Empty
and IsNotEmpty
operators. When they are selected, the condition’s value is cleared and an empty component is rendered for the value. This behavior is configured through the emptyRenderer
property, which enables you to define the operators that should reset the condition’s value and render an empty component when selected.
If you don’t want to rely on the default behavior provided by the query builder and the built-in value renderers are not enough to cover your use case, it’s possible to customize them through the renderers
property. This property enables you to customize the value renderers for specific operators and attribute types.
When customizing the query builder, you should note that emptyRenderer
takes priority over renderers
.
Find below an example on how to customize the value renderers through the renderers
property.
const renderers: HvQueryBuilderProps["renderers"] = {
// Renderer for the custom attribute type "custom"
custom: CustomRenderer,
text: {
// Renderer to customize the "Contains" operator of the "text" attribute type
Contains: ContainsRenderer,
},
numeric: {
// Renderer to customize the "numeric" attribute type
DEFAULT: NumericRenderer,
// Renderer to customize the "range" operator of the "numeric" attribute type
range: RangeRenderer,
},
};
In the example above, 4 renderers were provided:
CustomRenderer
will be used to render the value for thecustom
attribute type overriding the default text input used for custom attribute types.ContainsRenderer
will be used to render the value for thetext
attribute type when theContains
operator is selected overriding the default for this operator. When any other operator is selected for this attribute, the query builder relies on its default behavior.NumericRenderer
will be used to render the value for thenumeric
attribute type overriding the default renderer for this attribute type.RangeRenderer
will be used to render the value for thenumeric
attribute type when therange
operator is selected. This renderer takes precedence overNumericRenderer
when overriding the default renderer.
If necessary, it’s also possible to define value renderers at a more broad level using the DEFAULT
key at the root of the renderers
object like shown below. You should be aware that DEFAULT
is a reserved key, you shouldn’t use to define your own attribute or operator types.
// Example 1
const renderers: HvQueryBuilderProps["renderers"] = {
// Renderer to customize all attribute types and operators
DEFAULT: DefaultRenderer,
};
// Example 2
const renderers: HvQueryBuilderProps["renderers"] = {
DEFAULT: {
// Renderer to customize all attribute types and operators
DEFAULT: DefaultRenderer,
// Renderer to customize the "range" operator of all attribute types
range: DefaultRangeRenderer,
},
};
In the first example, the DefaultRenderer
will be used to render the value for all attribute types and operators. However, in the second example, the DefaultRenderer
is used for all attribute types and operators except the range
operator since the DefaultRangeRenderer
will be used. These customizations have the lowest priority meaning that any renderer defined at the attribute type level will take precedence.
Find below an example where the priorities are annotated.
const renderers: HvQueryBuilderProps["renderers"] = {
DEFAULT: {
DEFAULT: DefaultRenderer, // 4
range: DefaultRangeRenderer, // 3
},
numeric: {
DEFAULT: NumericRenderer, // 2
range: RangeRenderer, // 1
},
};
Defining renderers
The value renderers are function components that receive the following properties:
interface HvQueryBuilderRendererProps<V = any> {
id: React.Key;
attribute: string;
operator?: string;
value?: V;
}
Find below an example of a value renderer.
const Renderer = ({ id }: HvQueryBuilderRendererProps) => {
const { dispatchAction } = useQueryBuilderContext();
return (
<HvSlider
required
label="Slider"
onChange={(value) => {
dispatchAction({
type: "set-value",
id,
value,
});
}}
/>
);
};
Custom Renderers example
If the default attribute types (boolean
, numeric
, text
, textarea
, and dateandtime
) are not enough to cover your use case, custom ones can be used. For these custom types, if no corresponding renderer is provided through the renderers
property, a text input will be rendered. The renderers
property can also be used to customize the value renderers for specific operators of an attribute type.
dispatchAction
is needed to update the query and can be accessed through the useQueryBuilderContext
hook exported by the core
package. This utility can be used to dispatch several action types such as: reset-query
, reset-group
, add-rule
, add-group
, remove-node
, set-combinator
, set-attribute
, set-operator
, and set-value
. However, you’ll most likely only need the set-value
action that enables you to set the value of a condition. This action has the following specification:
{
type: "set-value";
id: React.Key;
value: any;
}
Controlled
The query builder state can be controlled using the value
and onChange
properties.