Has 8 sections:
{conjunctions, operators, widgets, types, funcs, settings, fields, ctx}
Each section is described below.
Usually it’s enough to just reuse basic config, provide your own fields and maybe change some settings.
Optionally you can override some options in basic config or add your own types/widgets/operators (or even conjunctions like XOR or NOR).
There are functions for building query string: formatConj
, formatValue
, formatOp
, formatField
, formatFunc
which are used for QbUtils.queryString()
.
They have common param isForDisplay
- false by default, true will be used for QbUtils.queryString(immutableTree, config, true)
(see 3rd param true).
Also there are similar mongoConj
, mongoFormatOp
, mongoFormatValue
, mongoFunc
, mongoFormatFunc
, mongoArgsAsObject
for building MongoDb query with QbUtils.mongodbFormat()
.
And sqlFormatConj
, sqlOp
, sqlFormatOp
, sqlFormatValue
, sqlFormatReverse
, formatSpelField
, sqlFunc
, sqlFormatFunc
for building SQL where query with QbUtils.sqlFormat()
.
And spelFormatConj
, spelOp
, spelFormatOp
, spelFormatValue
, spelFormatReverse
, spelFunc
, spelFormatFunc
for building query in (Spring Expression Language (SpEL) with QbUtils.spelFormat()
.
And jsonLogic
for building JsonLogic with QbUtils.jsonLogicFormat()
.
💡
|
Example 1: config for sandbox_simple
|
💡
|
Example 2: config for sandbox
|
-
Use
BasicConfig
for simple vanilla UI -
Use
AntdConfig
for more advanced UI with AntDesign widgets -
Use
MuiConfig
for MUI widgets -
Use
MaterialConfig
for Material-UI v4 widgets -
Use
BootstrapConfig
for Bootstrap widgets -
Use
FluentUIConfig
for Fluent UI widgets
import {BasicConfig} from '@react-awesome-query-builder/ui'; import {AntdConfig} from '@react-awesome-query-builder/antd'; import {MuiConfig} from '@react-awesome-query-builder/mui'; import {MaterialConfig} from '@react-awesome-query-builder/material'; import {BootstrapConfig} from "@react-awesome-query-builder/bootstrap"; import {FluentUIConfig} from "@react-awesome-query-builder/fluent"; const InitialConfig = BasicConfig; // or AntdConfig or MuiConfig or BootstrapConfig or FluentUIConfig const myConfig = { ...InitialConfig, // reuse basic config fields: { stock: { label: 'In stock', type: 'boolean', }, // ... my other fields } };
What is in basic config?
const {
conjunctions: {
AND,
OR
},
operators: {
equal,
not_equal,
less,
less_or_equal,
greater,
greater_or_equal,
like,
not_like,
starts_with,
ends_with,
between,
not_between,
is_null,
is_not_null,
is_empty,
is_not_empty,
select_equals, // like `equal`, but for select
select_not_equals,
select_any_in,
select_not_any_in,
multiselect_contains,
multiselect_not_contains,
multiselect_equals, // like `equal`, but for multiselect
multiselect_not_equals,
proximity, // complex operator with options
},
widgets: {
text,
textarea,
number,
slider,
rangeslider, // missing in `BasicConfig`, `BootstrapConfig`, `FluentUIConfig`
select,
multiselect,
treeselect, // present only in `AntdConfig`
treemultiselect, // present only in `AntdConfig`
date,
time,
datetime,
boolean,
field, // to compare field with another field of same type
func, // to compare field with result of function
},
types: {
text,
number,
date,
time,
datetime,
select,
multiselect,
treeselect,
treemultiselect,
boolean,
},
settings,
ctx,
} = AntdConfig;
Example:
{
// simple
qty: {
type: 'number',
label: 'Quantity',
fieldSettings: {
min: 0,
max: 100,
}
},
// complex
user: {
type: '!struct', // special keyword for complex fields
label: 'User',
subfields: {
// subfields of complex field
name: {
type: 'text',
label: 'Name',
label2: 'User name', //optional, see below
fieldSettings: {
validateValue: (val, _fieldSettings) => (val.length <= 20),
}
},
},
},
...
}
key | required | default | meaning |
---|---|---|---|
|
+ |
One of types described in config.types or |
|
|
|||
|
+ for |
Config for subfields of complex field (multiple nesting is supported) |
|
|
+ |
Label to be displayed in field list |
|
|
Can be optionally specified for nested fields. |
||
|
By default field name for export is constructed from current feild key and ancestors keys joined by |
||
|
Optional tooltip to be displayed in field list by hovering on item |
||
|
Settings for widgets, will be passed as props. Example: |
||
|
+ for (multi)select |
List of values for (multi)select widget. |
|
|
+ for tree (multi)select |
List of values for tree (multi)select widget. |
|
|
Function to validate entered value. Return true/false or error string / null. |
||
|
- for |
false |
If true, user can provide own options in multiselect, otherwise they will be limited to |
|
- for (multi)select, tree (multi)select |
false |
Show search (autocomplete)? |
|
- for |
false |
Whether to expand all nodes by default |
|
- for |
true |
Can select only leafs or any node? |
|
- for |
Async function to load list of options for |
|
|
- for |
false |
If true, |
|
- for |
false |
If true, |
|
Default value |
||
|
See usecase at |
||
|
You can override config of corresponding type (see below at section config.types) |
||
|
Shorthand for |
||
|
Can exclude some operators. Example: |
||
|
If comparing with funcs is enabled for this field ( |
||
|
false |
If true, field will appear only at right side (when you compare field with another field) |
|
|
false |
If true, field will appear only at left side |
|
|
For type= |
Example:
import ru_RU from 'antd/es/locale/ru_RU';
import { ruRU } from '@material-ui/core/locale'; //v4
import { ruRU as muiRuRU } from '@mui/material/locale';
import { AntdWidgets } from '@react-awesome-query-builder/antd';
const { FieldCascader, FieldDropdown, FieldTreeSelect } = AntdWidgets;
{
valueSourcesInfo: {
value: {
label: "Value"
},
field: {
label: "Field",
widget: "field",
},
func: {
label: "Function",
widget: "func",
}
},
locale: {
moment: 'ru',
antd: ru_RU,
material: ruRU,
mui: muiRuRU,
},
renderField: (props) => <FieldCascader {...props} />,
renderOperator: (props) => <FieldDropdown {...props} />,
renderFunc: (props) => <FieldDropdown {...props} />,
canReorder: true,
canRegroup: true,
maxNesting: 10,
showLabels: false,
showNot: true,
setOpOnChangeField: ['keep', 'default'],
customFieldSelectProps: {
showSearch: true
},
...
}
Behaviour settings:
key | default | meaning |
---|---|---|
|
|
By default fields can be compared with values. |
|
false |
Show error message in QueryBuilder if validateValue() in field config returns false |
|
true |
Activate reordering support for rules and groups of rules? |
|
true |
Allow move rules (or groups) in/out groups during reorder? |
|
true |
Show |
|
false |
Show conjuction for 1 rule in group? |
|
Maximum number of rules which can be added to the query builder |
|
|
Max nesting for rule groups. |
|
|
true |
True - leave empty group after deletion of rules, false - automatically remove empty groups + add 1 empty rule to empty root |
|
false |
False - automatically add 1 empty rule into new group |
|
false |
Not allow to add/delete rules or groups, but allow change |
|
false |
Not allow to change fields |
|
false |
Not allow to change operators |
|
false |
Not allow to change values |
|
false |
Clear value on field change? false - if prev & next fields have same type (widget), keep |
|
false |
Clear value on operator change? |
|
|
Strategies for selecting operator for new field (used by order until success): |
|
For |
|
|
|
Operators usable in |
|
false |
Show "Lock" switch for rules and groups to make them read-only ("admin mode") |
|
false |
Show "Delete" button for locked rule? |
|
true |
Remove incomplete rules (w/o value) during validation in |
|
true |
Remove empty groups during validation in |
|
true |
Remove values that are not in |
|
false |
Set to |
💡
|
For fully read-only mode use these settings: |
immutableGroupsMode: true,
immutableFieldsMode: true,
immutableOpsMode: true,
immutableValuesMode: true,
canReorder: false,
canRegroup: false,
Render settings:
key | default | meaning |
---|---|---|
|
|
Size of AntDesign components - |
|
|
Render fields list |
|
|
Render operators list |
|
|
Render functions list |
|
Other internal render functions you can override if using another UI framework (example) |
|
|
Render Item |
|
|
false |
Show labels above all fields? |
|
100 |
To shorten long labels of fields/values (by length, i.e. number of chars) |
|
|
Placement of antdesign’s dropdown pop-up menu |
|
|
You can pass props to |
|
|
You can change the position of the group actions to the following: |
|
||
|
||
|
||
|
||
|
|
Width for slider |
|
|
Width for select |
|
|
Width for search in autocomplete |
|
5 |
Max rows for textarea |
Other settings:
key | default | meaning |
---|---|---|
|
"en" |
Locale (string or array of strings) used for moment |
|
|
Locale object used for AntDesign widgets |
|
|
Locale object used for MaterialUI v4 widgets |
|
|
Locale object used for MUI widgets |
|
{} |
Options for createTheme |
|
{} |
Options for createTheme |
|
Function for formatting query string, used to format rule with reverse operator which haven’t |
|
|
Function for formatting query string, used to format field |
|
|
Function for formatting query string, used to format aggregation rule (like |
|
|
|
Separator for struct fields. |
|
|
Separator for struct fields in UI. |
Localization:
key | default |
---|---|
|
Value |
|
Value |
|
Field |
|
Operator |
|
Function |
|
Select field |
|
Select function |
|
Select operator |
|
Lock |
|
Locked |
|
|
|
|
|
Add group |
|
Add rule |
|
Add sub rule |
|
Not |
|
Select value source |
|
If you want to ask confirmation of removing non-empty rule/group, add these options. |
|
Are you sure delete this rule? |
|
Yes |
|
|
|
Cancel |
|
Are you sure delete this group? |
|
Yes |
|
|
|
Cancel |
{
AND: {
label: 'And',
formatConj: (children, _conj, not) => ( (not ? 'NOT ' : '') + '(' + children.join(' || ') + ')' ),
reversedConj: 'OR',
mongoConj: '$and',
},
OR: {...},
}
where AND
and OR
- available conjuctions (logical operators). You can add NOR
if you want.
key | required | meaning |
---|---|---|
|
+ |
Label to be displayed in conjunctions swicther |
|
+ |
Function for formatting query, used to join rules into group with conjunction. |
|
+ for MongoDB format |
Name of logical operator for MongoDb |
|
+ for SQL format |
See |
|
+ for SpEL format |
See |
|
Opposite logical operator. |
{
equal: {
label: 'equals',
reversedOp: 'not_equal',
labelForFormat: '==',
cardinality: 1,
formatOp: (field, _op, value, _valueSrc, _valueType, opDef) => `${field} ${opDef.labelForFormat} ${value}`,
mongoFormatOp: (field, op, value) => ({ [field]: { '$eq': value } }),
},
..
}
key | required | default | meaning |
---|---|---|---|
|
+ |
Label to be displayed in operators select component |
|
|
+ |
Opposite operator |
|
|
false |
Eg. true for operator "!=", false for operator "==" |
|
|
1 |
Number of right operands (1 for binary, 2 for |
|
|
+ |
Function for formatting query string, used to join operands into rule. |
|
|
If |
||
|
+ for MongoDB format |
Function for formatting MongoDb expression, used to join operands into rule. |
|
|
+ for SQL format |
Operator name in SQL |
|
|
- for SQL format |
Function for advanced formatting SQL WHERE query when just |
|
|
+ for SpEL format |
Operator name in SpEL |
|
|
- for SpEL format |
Function for advanced formatting query in SpEL when just |
|
|
+ for JsonLogic |
String (eg. |
|
|
+ for ElasticSearch format |
String (eg. |
|
|
+ for |
Labels to be displayed on top of 2 values widgets if |
|
|
+ for |
Labels to be displayed before each 2 values widgets |
|
|
Special for |
ℹ️
|
There is also special import {CustomOperators: {ProximityOperator}} from '@react-awesome-query-builder/ui'; See |
import {VanillaWidgets} from '@react-awesome-query-builder/ui';
import {AntdWidgets} from '@react-awesome-query-builder/antd';
import {MuiWidgets} from '@react-awesome-query-builder/mui';
import {MaterialWidgets} from '@react-awesome-query-builder/material'; // MUI v4
import {BootstrapWidgets} from '@react-awesome-query-builder/bootstrap';
import {FluentUIWidgets} from "@react-awesome-query-builder/fluent";
const {
VanillaTextWidget,
VanillaNumberWidget,
...
} = VanillaWidgets;
const {
TextWidget,
NumberWidget,
...
} = AntdWidgets;
const {
MuiTextWidget,
MuiNumberWidget,
...
} = MuiWidgets;
const {
BootstrapTextWidget,
BootstrapNumberWidget,
...
} = BootstrapWidgets;
const {
FluentUITextWidget,
FluentUINumberWidget,
...
} = FluentUIWidgets;
{
text: {
type: 'text',
valueSrc: 'value',
factory: (props) => <TextWidget {...props} />,
formatValue: (val, _fieldDef, _wgtDef, isForDisplay) => (isForDisplay ? val.toString() : JSON.stringify(val)),
mongoFormatValue: (val, _fieldDef, _wgtDef) => (val),
// Options:
valueLabel: "Text",
valuePlaceholder: "Enter text",
// Custom props (https://ant.design/components/input/):
customProps: {
maxLength: 3
},
},
..
},
key | required | default | meaning |
---|---|---|---|
|
+ |
One of types described in config.types |
|
|
+ |
React function component |
|
|
+ |
Function for formatting widget’s value in query string. |
|
|
- for MongoDB format |
v ⇒ v |
Function for formatting widget’s value in MongoDb query. |
|
- for SQL format |
|
Function for formatting widget’s value in SQL WHERE query. |
|
- for SpEL format |
Function for formatting widget’s value in SpEL query. |
|
|
- for JsonLogic |
v ⇒ v |
Function for formatting widget’s value for JsonLogic. |
|
- for ElasticSearch format |
|
Function for formatting widget’s value for ES query. |
|
|
Common option, text to be placed on top of widget if |
|
|
|
Common option, placeholder text to be shown in widget for empty value |
|
|
Option for |
||
|
Option for |
||
|
|
Option for |
|
|
|
Option for |
|
|
|
Option for |
|
|
Option for |
||
|
Option for |
||
|
You can pass any props directly to widget with |
||
|
Hide operator? |
ℹ️
|
There is special field widget, rendered by <ValueFieldWidget> .It can be used to compare field with another field of same type. To enable this feature set valueSources of type to ['value', 'field'] (see below in config.types).
|
ℹ️
|
There is special func widget, rendered by <FuncWidget> .It can be used to compare field with result of function (see config.funcs). To enable this feature set valueSources of type to ['value', 'func'] (see below in config.types).
|
{
time: {
valueSources: ['value', 'field', 'func'],
defaultOperator: 'equal',
widgets: {
time: {
operators: ['equal', 'between'],
widgetProps: {
valuePlaceholder: "Time",
timeFormat: 'h:mm:ss A',
use12Hours: true,
},
opProps: {
between: {
valueLabels: ['Time from', 'Time to'],
},
},
},
},
},
..
}
key | required | default | meaning |
---|---|---|---|
|
keys of |
Array with values |
|
|
If specified, it will be auto selected when user selects field |
||
|
+ |
Available widgets for current type and their config. |
|
|
List of operators for widget, described in config.operators |
||
|
Can be used to override config of corresponding widget specified in config.widgets. Example: |
||
|
Can be used to override config of operator for widget. Example: |
{
lower: {
label: 'Lowercase',
sqlFunc: 'LOWER',
mongoFunc: '$toLower',
returnType: 'text',
args: {
str: {
type: 'text',
valueSources: ['value', 'field'],
}
}
},
..
}
key | required | default | meaning |
---|---|---|---|
|
+ |
One of types described in config.types |
|
|
same as func key |
Label to be displayed in functions list |
|
|
Example result: for |
Function for formatting func expression in query rule. |
|
|
- for SQL format |
same as func key |
Func name in SQL |
|
- for SQL format |
Can be used instead of |
|
|
- for SpEL format |
same as func key |
Func name in SpEL |
|
- for SpEL format |
Can be used instead of |
|
|
- for MongoDB format |
same as func key |
Func name in Mongo |
|
false |
||
|
- for MongoDB format |
Can be used instead of |
|
|
+ for JsonLogic |
String (function name) or function with 1 param - args object |
|
|
Function to convert given JsonLogic expression to array of arguments of current function. If given expression can’t be parsed into current function, throw an error. |
||
|
Arguments of function. Config is almost same as for simple fields |
||
|
arg’s key |
Label to be displayed in arg’s label or placeholder (if |
|
|
+ |
One of types described in config.types |
|
|
keys of |
Array with values |
|
|
Default value |
||
|
Settings for widgets, will be passed as props. Example: |
||
|
+ for (multi)select widgets |
List of values for Select widget. |
|
|
+ for tree (multi)select widgets |
List of values for TreeSelect widget. |
|
|
false |
Last args can be optional |
|
|
|
Can render custom function brackets in UI (or not render). |
|
|
|
Can render custom arguments separators in UI (other than |
|
|
false |
Allows the function to be used within its own arguments. |
See the collection of basic funcstions.
You can copy them to config.funcs
:
import { BasicFuncs } from '@react-awesome-query-builder/ui';
const config = {
//...
funcs: {
LINEAR_REGRESSION: BasicFuncs.LINEAR_REGRESSION,
LOWER: BasicFuncs.LOWER,
}
};
Required starting from version 6.3.0
It is a collection of JS functions and React components to be used in other sections of config by reference to ctx
rather than by reference to imported modules.
💡
|
The purpose of ctx is to isolate non-serializable part of config.
|
Typically you just need to copy it from basic config - AntdConfig.ctx
for AntDesign, MuiConfig.ctx
for MUI, BasicConfig.ctx
for vanilla UI etc.
But if you use advanced server-side config, you may need to add your custom functions (eg. validateValue
) to ctx
and refer to them in other config sections by name.
import {BasicConfig} from '@react-awesome-query-builder/ui';
const fields = {
firstName: {
type: "text",
fieldSettings: {
// use function `validateFirstName` from `ctx` by name
validateValue: "validateFirstName",
}
},
};
const ctx = {
...BasicConfig.ctx,
validateFirstName: (val: string) => {
return (val.length < 10);
},
};
// `zipConfig` can be passed to backend as JSON
const zipConfig = {
fields,
settings: {
useConfigCompress: true, // this is required to use Utils.decompressConfig()
},
// you can add here other sections like `widgets` or `types`, but don't add `ctx`
};
// Config can be loaded from backend with providing `ctx`
const config = Utils.decompressConfig(zipConfig, BasicConfig, ctx);
You can’t just pass JS function to validateValue
in fieldSettings
because functions can’t be serialized to JSON.
The shape of ctx
:
const ctx = {
// provided in BasicConfig:
RCE: React.createElement,
W: {
VanillaButton,
// ... other widgets provieded with the lib
},
utils: {
moment, // used in `formatValue`
SqlString, // used in `sqlFormatValue`
// ... other utils
},
// your custom extensions:
components: {
MyLabel, // used in `labelYes` and `labelNo` below
// ... other custom components used in JSXs in your config
},
validateFirstName: (val: string) => {
return (val.length < 10);
},
myRenderField: (props: FieldProps, _ctx: ConfigContext) => {
if (props?.customProps["showSearch"]) {
return <MuiFieldAutocomplete {...props}/>;
} else {
return <MuiFieldSelect {...props}/>;
}
},
autocompleteFetch, // see implementation in `/packages/sandbox_next/components/demo/config_ctx.tsx`
}
Referring to ctx
in zipConfig
:
const zipConfig = {
fields: {
firstName: {
type: "text",
fieldSettings: {
validateValue: "validateFirstName",
}
},
in_stock: {
type: "boolean",
mainWidgetProps: {
labelYes: <MyLabel>Yes</MyLabel>,
labelNo: <MyLabel>No</MyLabel>,
}
},
autocomplete: {
type: "select",
fieldSettings: {
asyncFetch: "autocompleteFetch",
},
},
},
settings: {
renderField: "myRenderField",
renderButton: "W.VanillaButton",
useConfigCompress: true, // this is required
},
};
To build zip config from full config you can use this util:
const zipConfig = Utils.compressConfig(config, BasicConfig);
In order to generate zip config corretly (to JSON-serializable object), you should put your custom functions to ctx
and refer to them by names as in examples above.
import merge from "lodash/merge";
const ctx = {
validateFirstName: (val) => {
return (val.length < 10);
},
};
const config = merge({}, BasicConfig, {
fields: {
firstName: {
type: "text",
fieldSettings: {
validateValue: "validateFirstName",
}
},
},
ctx,
});
const zipConfig = Utils.compressConfig(config, BasicConfig);
const config2 = Utils.decompressConfig(zipConfig, BasicConfig, ctx); // should be same as `config`
ℹ️
|
settings.useConfigCompress should be true if you use Utils.decompressConfig()
|
Section config.ctx demonstrates the concept of zipConfig
which is a special config format that contains only changes against full config and can be serialized to JSON.
Base configs provided by this library (BasicConfig
, AntdConfig
etc.) still has JS functions (at least for the moment of writing, in version 6.3.0).
If you want to serialize the entire config (not only changes), you can’t do it to JSON as it contains JS functions. But you can do it to string with a help of serialize-javascript and deserialize back with eval()
. Yes, it’s unsecure, but can be used for some purposes.
🔥
|
Using eval() is not secure
|
To achieve this ability, JS functions in config (like factory
, formatValue
, validateValue
etc.) should be pure functions, they should not use imported modules like this:
import { VanillaWidgets } from '@react-awesome-query-builder/ui';
const { VanillaButton } = VanillaWidgets;
import moment from "moment";
const config = {
settings: {
renderButton: (props) => <VanillaButton {...props} />,
},
widgets: {
date: {
jsonLogic: (val, fieldDef, wgtDef) => moment(val, wgtDef.valueFormat).toDate(),
},
},
};
If you try to serialize this config and deserialize back with eval()
, you will get
ReferenceError: react__WEBPACK_IMPORTED_MODULE_0___default is not defined
.
Instead of this all imported modules should be included in config.ctx
. All render functions in config have ctx
as 2nd argument. In format functions you can refer to ctx
via this
.
const config = {
settings: {
renderButton: (props, {RCE, W: {VanillaButton}}) => RCE(VanillaButton, props),
},
widgets: {
date: {
jsonLogic: function (val, fieldDef, wgtDef) {
return this.utils.moment(val, wgtDef.valueFormat).toDate();
},
},
},
ctx: {
RCE: React.createElement,
W: {
VanillaButton,
},
utils: {
moment,
},
}
};
Now entire config (without ctx
) can be serialized to a string with serialize-javascript and then deserialized back with eval()
and appending ctx
.
See example.