Skip to content

Latest commit

 

History

History
1125 lines (1014 loc) · 52.3 KB

File metadata and controls

1125 lines (1014 loc) · 52.3 KB

Config format

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, sqlOps, sqlFormatOp, sqlFormatValue, sqlFormatReverse, formatSpelField, sqlFunc, sqlFormatFunc, sqlImport 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

 

Basic config

  • 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, // multiline text
    number,
    price, // same as number but with decimal separator etc.
    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;

 

Sections

config.fields

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

type

+

One of types described in config.types or !struct/!group for complex field
(use !struct for objects, !group for arrays)

mode

For !group type, values are: some/array
some is light mode (default), at least one subrule should match
(for export elemMatch will be used in MongoDb, some in JsonLogic)
array is extended mode, user can choose one of group operators (some/all/none/count >/</==/…​)

subfields

+ for !struct/!group type

Config for subfields of complex field (multiple nesting is supported)

label

+

Label to be displayed in field list
(If not specified, fields’s key will be used instead)

label2

Can be optionally specified for nested fields.
By default, if nested field is selected (eg. name of user in example above), <FieldDropdown> component will show name.
Just name can be confusing, so can be overriden by setting label2 to something like User name.
As alternative, you can use <FieldCascader> component which handles nested fields right. See renderField in settings.

fieldName

By default field name for export is constructed from current feild key and ancestors keys joined by settings.fieldSeparator. You can override this by specifying fieldName

tooltip

Optional tooltip to be displayed in field list by hovering on item

fieldSettings

Settings for widgets, will be passed as props. Example: {min: 1, max: 10}
Available settings for Number/Slider widgets: min, max, step.
Slider also supports marks (example: { 0: "0%", 100: "100%" }).
Available settings for Price widgets: thousandSeparator, decimalSeparator, decimalScale, prefix, suffix, allowNegative (see type PriceFieldSettings and react-number-format).
Available settings for date/time widgets: timeFormat, dateFormat, valueFormat, use12Hours.
Available settings for text widget: maxLength, maxRows.
See table for other fieldSettings below.

defaultValue

Default value

preferWidgets

See usecase at packages/examples/src/demo/config for slider field. Its type is number.
There are 4 widgets defined for number type: number, price, slider, rangeslider.
So setting preferWidgets: ['slider', 'rangeslider'] will force rendering slider instead of number input.
Setting preferWidgets: ['price'] will render price input (supports thousands separator) instead of number.
Also you can use preferWidgets: ['textarea'] for type text for multiline input.

operators, defaultOperator, widgets, valueSources

You can override config of corresponding type (see below at section config.types)

mainWidgetProps

Shorthand for widgets.<main>.widgetProps

excludeOperators

Can exclude some operators. Example: ['proximity'] for text type

funcs

If comparing with funcs is enabled for this field (valueSources contains 'func'), you can also limit list of funcs to be compared (by default will be available all funcs from config.funcs with returnType matching field’s type)

hideForSelect

false

If true, field will appear only at right side (when you compare field with another field)

hideForCompare

false

If true, field will appear only at left side

conjunctions, showNot

For type=!group with mode=array. Example: conjunctions: ['AND'], showNot: false


fieldSettings

key default for widgets meaning

validateValue

*

Function to validate input value.
Simple way: return true/false. Advanced: if value is valid, return null, otherwise return error string or object {error, fixedValue?}.
error can be a string or an object {key, args} to use i18n.
(val: any, fieldSettings: Object) ⇒ boolean | string | {error: string | Object, fixedValue?: any} | null

listValues

select, multiselect

Required if asyncFetch is not provided. Static list of values.
Example: [{value: 'yellow', title: 'Yellow'}, {value: 'green', title: 'Green'}] (or alternatively { yellow: 'Yellow', green: 'Green' })
You can also use groupTitle to group values. Example: [{value: 'red', groupTitle: 'Warm colors'}, {value: 'orange', groupTitle: 'Warm colors'} …​]

treeValues

treeselect, treemultiselect

Required. Static list of values.
Example: [{value: 'warm', title: 'Warm colors'}, {value: 'red', title: 'Red', parent: 'warm'}, {value: 'orange', title: 'Orange', parent: 'warm'}]
(or alternatively [{value: 'warm', title: 'Warm colors', children: [ {value: 'red', title: 'Red'}, {value: 'orange', title: 'Orange'} ]}])

maxLength

text, textarea

Max text length in characters

maxRows

textarea

Max rows

allowCustomValues

false

select, multiselect

If true, user can provide own options in multiselect.
Otherwise they will be limited to static listValues (or values loaded via asyncFetch)

showSearch

false

select, multiselect, treeselect, treemultiselect

Show search (autocomplete)?

treeExpandAll

false

treeselect, treemultiselect

Whether to expand all nodes by default

treeSelectOnlyLeafs

true

treeselect

Can select only leafs or any node?

asyncFetch

select, multiselect

Required if listValues is not provided.
Async function to load list of options from server.
Function format: async (string search, int offset) ⇒ { values: Array, hasMore: boolean }
values - list of {title: string, value: string/number, groupTitle?: string}
See also useLoadMore, useAsyncSearch, fetchSelectedValuesOnInit.

useAsyncSearch

false

select, multiselect with asyncFetch

If true, asyncFetch supports server-side search.
Otherwise search will be performed locally only within already loaded list values from server.

useLoadMore

false

select, multiselect with asyncFetch

If true, asyncFetch supports pagination.

forceAsyncSearch

false

select, multiselect with asyncFetch

If true, list of options will be loaded only when user types into search string (if search is empty, no options to be presented).

fetchSelectedValuesOnInit

false

select, multiselect with asyncFetch

If true, selected list values will be initially fetched from server (on query load) to resolve their titles for UI.
asyncFetch should support format async (Array selectedValues) ⇒ { values: Array }
where selectedValues - array of values (string/number) and values - list of {title: string, value: mixed, groupTitle?: string}
Example for multiselect: asyncFetch(['#FFFF00', '#008000', '#20B2A2']) should be resolved with [{title: "Yellow", value: "#FFFF00"}, {title: "Green", value: "#008000"}] to display color names in UI. (Assuming #20B2A2 is a custom value entered by user)
Example for select: asyncFetch(['#FFFF00']) should be resolved with [{title: "Yellow", value: "#FFFF00"}].
See logic/autocomplete data in demo app.

thousandSeparator

price

Defines the thousands separator character (eg. ,).

decimalSeparator

.

price

Defines the decimal character.

decimalScale

price

If defined, it limits the number of digits after the decimal point.

prefix

price

Adds the prefix character before the input value (useful for currency).

suffix

price

Adds the suffix after the input value (useful for currency).

allowNegative

true

price

If set to false, negative numbers will not be allowed.

timeFormat

HH:mm

time, datetime

Format to render time in widget

dateFormat

DD.MM.YYYY

date, datetime

Format to render date in widget

use12Hours

false

time, datetime

Use AM/PM?

 
 

config.settings

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",
    }
  },
  fieldSources: ["field", "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

valueSourcesInfo

{ value: { label: "Value" }, field: { label: "Field" }, func: { label: "Function" } }

Sources for RHS (right side of rule, after operator). By default LHS (left side of rule) can be compared with values, another fields and functions in RHS.
If you want to disable comparing with another fields in RHS, remove field key.
If you want to disable comparing with result of function in RHS, remove func key.

fieldSources

["field"]

Sources for LHS. To enable functions in LHS, set to ["field", "func"]

keepInputOnChangeFieldSrc

true

Keep value entered in RHS after changing source of LHS?

showErrorMessage

false

Show error message in QueryBuilder if validateValue() in field config returns false for the value or if input value does not satisfy max, min constraints in fieldSettings

canReorder

true

Activate reordering support for rules and groups of rules?

canRegroup

true

Allow to move a rule (group) in/out of group during reorder?
False - allow "safe" reorder, means only reorder at same level

canRegroupCases

false

For ternary mode - Allow to move a rule (group) from one case to another?

showNot

true

Show NOT together with AND/OR?

forceShowConj

false

Show conjuction for 1 rule in group?

defaultConjunction

AND

Default group conjunction, should be key in config.conjunctions

maxNumberOfRules

Maximum number of rules which can be added to the query builder

maxNesting

Max nesting for groups.
Set 1 if you don’t want to use groups at all. This will remove also Add group button.

maxNumberOfCases

For ternary mode - maximum number of cases

canLeaveEmptyGroup

true

True - leave empty group after deletion of rules, false - automatically remove empty groups + add 1 empty rule to empty root

shouldCreateEmptyGroup

false

False - automatically add 1 empty rule into new group

immutableGroupsMode

false

Not allow to add/delete rules or groups, but allow change

immutableFieldsMode

false

Not allow to change fields

immutableOpsMode

false

Not allow to change operators

immutableValuesMode

false

Not allow to change values

clearValueOnChangeField

false

Clear value on field change? false - if prev & next fields have same type (widget), keep

clearValueOnChangeOp

false

Clear value on operator change?

setOpOnChangeField

['keep', 'default']

Strategies for selecting operator for new field (used by order until success):
default (default if present), keep (keep prev from last field), first, none

canCompareFieldWithField

For <ValueFieldWidget> - Function for building right list of fields to compare field with field
(string leftField, Object leftFieldConfig, string rightField, Object rightFieldConfig) ⇒ boolean
For type == select/multiselect you can optionally check listValues

groupOperators

['all', 'some', 'none']

Operators usable in !group fields with array mode

showLock

false

Show "Lock" switch for rules and groups to make them read-only ("admin mode")
NOTE: To preserve read-only state of rules in JsonLogic, please use jsonLogic.add_operation("locked", v ⇒ v); in your code

canDeleteLocked

false

Show "Delete" button for locked rule?

removeIncompleteRulesOnLoad

false

Remove incomplete rules (without field, operator, value, or if not all required args are present for functin) during initial validation of value prop passed to <Query>

exportPreserveGroups

false

Preserve unnecessary groups (ie. groups with only one rule or empty groups) during JsonLogic export

removeEmptyRulesOnLoad

true

Remove empty rules during initial validation of value prop passed to <Query>

removeEmptyGroupsOnLoad

true

Remove empty groups during initial validation of value prop passed to <Query>

removeInvalidMultiSelectValuesOnLoad

true

Remove values that are not in listValues during initial validation of value prop passed to <Query>?
By default true, but false for AntDesign as can be removed manually

useConfigCompress

false

Set to true if you use Utils.ConfigUtils.decompressConfig()

fieldItemKeysForSearch

["label", "path", "altLabel", "grouplabel"]

Keys in field item (see type FieldItem) available for search. Available keys: "key", "path", "label", "altLabel" (label2), "tooltip", "grouplabel" (label of parent group, for subfields of complex fields)

listKeysForSearch

["title", "value"]

Keys in list item (see type ListItem) available for search. Available keys: "title", "value", "groupTitle"

reverseOperatorsForNot

false

True to convert "!(x == 1)" to "x != 1" on import and export

canShortMongoQuery

true

True to simplify exported MongoDb query eg. {$and: [ {num:{$gt:1}}, {num:{$ne:5} } ]} to { num: {$gt: 1, $ne: 5} }

fixJsonLogicDateCompareOp

false

Fix comparing of Date instances in JsonLogic by using custom ops date==/datetime== instead of == and date1=/datetime!= instead of 1=

💡
For fully read-only mode use these settings:
immutableGroupsMode: true,
immutableFieldsMode: true,
immutableOpsMode: true,
immutableValuesMode: true,
canReorder: false,
canRegroup: false,

Theme settings:

key default meaning

themeMode

undefined

light or dark.
If <Query> is wrapped in theme provider component (eg. <ThemeProvider> for MUI, <ConfigProvider> for AntDesign) then will be detected automatically (doesn’t work for reactstrap).
Otherwise light by default

compactMode

false

Use compact styles (eg. smaller margins)

liteMode

true

Hide some elements (butons "Add", "Delete", drag icon, select source arrow, inactive conjunctions buttons). Show only on hover.
Same as adding class .qb-lite to .query-builder

theme.material

{}

Options for createTheme

theme.mui

{}

Options for createTheme

theme.antd

{}

Options for ConfigProvider

theme.fluent

{}

Options for ThemeProvider

designSettings.canInheritThemeFromOuterProvider

true

If <Query> is wrapped in theme provider component (eg. <ThemeProvider> for MUI) and settings.theme.mui is also provided then merge themes.

designSettings.generateCssVarsFromThemeLibrary

true

Adopt <Query> styling to used UI framework theme (MUI/AntDesign etc.).
Use false if you don’t want a new behaviour and want to use static styles like in versions < 6.7.0

designSettings.useThickLeftBorderOnHoverItem

false

Fancy effect for hovering on rule/group

designSettings.useShadowOnHoverItem

false

Fancy effect for hovering on rule/group

generateCssVars.*

If you want to override generation of css vars for RAQB using UI framework’s theme, use your own function.
generateCssVars is an object with keys mui, antd, fluent, material. Value - function (theme, config) ⇒ Object
Example of overriding: generateCssVars.mui = (theme, config) ⇒ ({ "--group-background": theme.palette.background.paper })
Example of extending: generateCssVars.mui = (theme, config) ⇒ ({ …​config.ctx.generateCssVars(theme, config), "--group-background": theme.palette.grey["200"] })

renderSize

small

Size of components - small, middle or large

dropdownPlacement

bottomLeft

Placement of antdesign’s dropdown pop-up menu

groupActionsPosition

topRight

You can change the position of the group actions to the following:
topLeft, topCenter, topRight, bottomLeft, bottomCenter, bottomRight

defaultSliderWidth

200px

Width for slider

defaultSelectWidth

200px

Width for select

defaultSearchWidth

100px

Width for search in autocomplete inputs

defaultMaxRows

5

Max rows for textarea widget

maxLabelsLength

100

To shorten long labels of fields/values (by length, i.e. number of chars)

showLabels

false

Show labels above all fields?

showSelectedValueSourceLabel

false

Show selected value source label?

Render settings:

key default meaning

renderField

(props) ⇒ <FieldSelect {…​props} />

Render fields list
Available widgets for AntDesign: FieldSelect, FieldDropdown, FieldCascader, FieldTreeSelect

renderOperator

(props) ⇒ <FieldSelect {…​props} />

Render operators list
Available widgets for AntDesign: FieldSelect, FieldDropdown

renderFunc

(props) ⇒ <FieldSelect {…​props} />

Render functions list
Available widgets for AntDesign: FieldSelect, FieldDropdown

renderConjs, renderButton, renderIcon, renderButtonGroup, renderSwitch, renderProvider, renderValueSources, renderConfirm, useConfirm, renderRuleError

Other internal render functions you can override if using another UI framework (example)

renderItem

Able to customize render behavior for rule/group items.

customFieldSelectProps

{}

You can pass props to the field select widget. Example: {showSearch: true}

customOperatorSelectProps

{}

You can pass props to the operator select widget. Example: {showSearch: true}

renderBeforeWidget

renderAfterWidget

renderBeforeActions

renderAfterActions

renderSwitchPrefix

IF

For ternary mode - render on top of all confitions

renderBeforeCaseValue

<span>then</span>

For ternary mode - render before case value (except default case), after case condition tree

renderAfterCaseValue

For ternary mode - render after case value (except default case)

Other settings:

key default meaning

formatReverse

Function for formatting query string, used to format rule with reverse operator which haven’t formatOp.
(string q, string operator, string reversedOp, Object operatorDefinition, Object revOperatorDefinition, bool isForDisplay) ⇒ string
q - already formatted rule for opposite operator (which have formatOp)
return smth like "NOT(" + q + ")"

formatField

Function for formatting query string, used to format field
(string field, Array parts, string label2, Object fieldDefinition, Object config, bool isForDisplay) ⇒ string
parts - list of fields’s keys for struct field
label2 - field’s label2 OR parts joined by fieldSeparatorDisplay
Default impl will just return field (or label2 for isForDisplay==true)

formatAggr

Function for formatting query string, used to format aggregation rule (like SOME OF Cars HAVE Year > 2010)
(string whereStr, string aggrField, string operator, mixed value, string valueSrc, string valueType, Object operatorDefinition, Object operatorOptions, bool isForDisplay, Object aggrFieldDef) ⇒ string
whereStr - formatted string representing condition for items (eg. Year > 2010 in example)
aggrField - aggregation field (eg. Cars in example)
operator - can be some/all/none (with cardinality 0) or equal/less/between/.. (applied to count of items)
value - for operators with cardinality 1/2 it is value for comparing with count of items

fieldSeparator

.

Separator for struct fields.

fieldSeparatorDisplay

.

Separator for struct fields in UI.

defaultField

Field to be selected by default for new rule.

defaultOperator

Operator to be selected by default for new rule.

caseValueField

(For ternary mode) Special field config to be used for displaying widget in "then" parts.
Example: {type: "text"} for simple text input in "then" part

sqlDialect

Affects import/export to SQL. Possible values: BigQuery, PostgreSQL, MySQL.

Localization settings:

key default meaning

locale.moment

en

Locale (string or array of strings) used for moment

locale.antd

en_US

Locale object used for AntDesign widgets

locale.material

enUS

Locale object used for MaterialUI v4 widgets

locale.mui

enUS

Locale object used for MUI widgets

Localization strings:

key default

valueLabel

Value

valuePlaceholder

Value

fieldLabel

Field

operatorLabel

Operator

funcLabel

Function

fieldPlaceholder

Select field

funcPlaceholder

Select function

operatorPlaceholder

Select operator

lockLabel

Lock

lockedLabel

Locked

deleteLabel

null

delGroupLabel

null

addGroupLabel

Add group

addRuleLabel

Add rule

addSubRuleLabel

Add sub rule

addSubGroupLabel

Add sub group

notLabel

Not

fieldSourcesPopupTitle

Select source

valueSourcesPopupTitle

Select value source

removeRuleConfirmOptions

If you want to ask confirmation of removing non-empty rule/group, add these options.
List of all valid properties is here

removeRuleConfirmOptions.title

Are you sure delete this rule?

removeRuleConfirmOptions.okText

Yes

removeRuleConfirmOptions.okType

danger

removeRuleConfirmOptions.cancelText

Cancel

removeGroupConfirmOptions.title

Are you sure delete this group?

removeGroupConfirmOptions.okText

Yes

removeGroupConfirmOptions.okType

danger

removeGroupConfirmOptions.cancelText

Cancel

defaultCaseLabel

Default:

addCaseLabel

Add condition

addDefaultCaseLabel

Add default condition

loadMoreLabel

Load more…​

loadingMoreLabel

Loading more…​

typeToSearchLabel

Type to search

loadingLabel

Loading…​

notFoundLabel

Not found

 
 

config.conjunctions

{
  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

+

Label to be displayed in conjunctions swicther

formatConj

+

Function for formatting query, used to join rules into group with conjunction.
(Immultable.List children, string conj, bool not, bool isForDisplay) ⇒ string
children - list of already formatted queries (strings) to be joined with conjuction

mongoConj

+ for MongoDB format

Name of logical operator for MongoDb

sqlFormatConj

+ for SQL format

See formatConj

spelFormatConj

+ for SpEL format

See formatConj

reversedConj

Opposite logical operator.
Can be used to optimize !(A OR B) to !A && !B (done for MongoDB format)

 
 

config.operators

{
  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

+

Label to be displayed in operators select component

tooltip

Optional tooltip to be displayed in operators list by hovering on item

reversedOp

+

Opposite operator

isNotOp

false

Eg. true for operator "!=", false for operator "=="

cardinality

1

Number of right operands (1 for binary, 2 for between)

formatOp

+

Function for formatting query string, used to join operands into rule.
(string field, string op, mixed value, string valueSrc, string valueType, Object opDef, Object operatorOptions, bool isForDisplay) ⇒ string
value - string (already formatted value) for cardinality==1 -or- Immutable.List of strings for cardinality>1

labelForFormat

If formatOp is missing, labelForFormat will be used to join operands when building query string

mongoFormatOp

+ for MongoDB format

Function for formatting MongoDb expression, used to join operands into rule.
(string field, string op, mixed value, bool not, bool useExpr, string valueSrc, string valueType, Object opDef, Object operatorOptions, Object fieldDef) ⇒ object
value - mixed for cardinality==1 -or- Array for cardinality>2
useExpr - true if resulted expression will be wrapped in {'$expr': {…​}} (used only if you compare field with another field or function) (you need to use aggregation operators in this case, like $eq (aggregation) instead of $eq)

sqlOp

+ for SQL format

Operator name in SQL

sqlOps

- for SQL format

Operator names in SQL

sqlFormatOp

- for SQL format

Function for advanced formatting SQL WHERE query when just sqlOp is not enough.
(string field, string op, mixed value, string valueSrc, string valueType, Object opDef, Object operatorOptions, Object fieldDef) ⇒ string
value - mixed for cardinality==1 -or- Array for cardinality>2

sqlImport

- for SQL format

Function to convert given raw SQL value (not string, but object got from node-sql-parser) to { children: Array }. If given expression can’t be parsed into current operator, throw an error.

spelOp

+ for SpEL format

Operator name in SpEL

spelFormatOp

- for SpEL format

Function for advanced formatting query in SpEL when just spelOp is not enough.
(string field, string op, mixed value, string valueSrc, string valueType, Object opDef, Object operatorOptions, Object fieldDef) ⇒ string
value - mixed for cardinality==1 -or- Array for cardinality>2

jsonLogic

+ for JsonLogic

String (eg. '<') -or- function for advanced formatting
(object field, string op, mixed value, Object opDef, Object operatorOptions, Object fieldDef) ⇒ object
value - mixed for cardinality==1 -or- Array for cardinality>2
field - already formatted {"var": <some field>}

elasticSearchQueryType

+ for ElasticSearch format

String (eg. term) -or- function (string valueType) ⇒ string
One of types of term-level queries

valueLabels

+ for cardinality==2

Labels to be displayed on top of 2 values widgets if config.settings.showLabels is true
Example: ['Value from', {label: 'Value to', placeholder: 'Enter value to'}]

textSeparators

+ for cardinality==2

Labels to be displayed before each 2 values widgets
Example: [null, 'and']

options

Special for proximity operator (see demo for details)

ℹ️

There is also special proximity operator, its options are rendered with <ProximityOperator>.

import {CustomOperators: {ProximityOperator}} from '@react-awesome-query-builder/ui';

 
 

config.widgets

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 for widgets meaning

type

+

*

One of types described in config.types

factory

+

*

React function component

formatValue

+

*

Function for formatting widget’s value in query string.
(mixed val, Object fieldDef, Object wgtDef, bool isForDisplay, string op, Object opDef) ⇒ string

mongoFormatValue

- for MongoDB format

v ⇒ v

*

Function for formatting widget’s value in MongoDb query.
(mixed val, Object fieldDef, Object wgtDef, string op, Object opDef) ⇒ any

sqlFormatValue

- for SQL format

SqlString.escape

*

Function for formatting widget’s value in SQL WHERE query.
(mixed val, Object fieldDef, Object wgtDef, string op, Object opDef) ⇒ string

spelFormatValue

- for SpEL format

spelEscape from ExportUtils

*

Function for formatting widget’s value in SpEL query.
(mixed val, Object fieldDef, Object wgtDef, string op, Object opDef) ⇒ string

jsonLogic

- for JsonLogic

v ⇒ v

*

Function for formatting widget’s value for JsonLogic.
(mixed val, Object fieldDef, Object wgtDef, string op, Object opDef) ⇒ any

elasticSearchFormatValue

- for ElasticSearch format

v ⇒ v

*

Function for formatting widget’s value for ES query.
(string esQueryType, mixed val, string op, string field, Object config) ⇒ Object

valueLabel

valueLabel from config.settings

*

Common option, text to be placed on top of widget if config.settings.showLabels is true

valuePlaceholder

valuePlaceholder from config.settings

*

Common option, placeholder text to be shown in widget for empty value

timeFormat

HH:mm

<TimeWidget>, <DateTimeWidget>

Option to display time in widget. Example: 'HH:mm'

use12Hours

false

<TimeWidget>

Use AM/PM?

dateFormat

DD.MM.YYYY

<DateWidget>, <DateTimeWidget>

Option to display date in widget. Example: YYYY-MM-DD

valueFormat

YYYY-MM-DD HH:mm:ss for datetime, YYYY-MM-DD for date, HH:mm:ss for time

<TimeWidget>, <DateWidget>, <DateTimeWidget>

Option to prepare string representation of value to be stored in query tree.

maxLength

<TextWidget>, <TextAreaWidget>

Max length in characters

maxRows

<TextAreaWidget>

Max rows

labelYes, labelNo

<BooleanWidget>

Labels for true/false, can be string or JSX

thousandSeparator

<PriceWidget>

Defines the thousands separator character (eg. ,).

decimalSeparator

.

<PriceWidget>

Defines the decimal character.

decimalScale

<PriceWidget>

If defined, it limits the number of digits after the decimal point.

prefix

<PriceWidget>

Adds the prefix character before the input value (useful for currency).

suffix

<PriceWidget>

Adds the suffix after the input value (useful for currency).

allowNegative

true

<PriceWidget>

If set to false, negative numbers will not be allowed.

customProps

*

You can pass any props directly to widget with customProps.
For example enable search for <Select> widget: customProps: {showSearch: true}

hideOperator

false

*

Can be useful for <BooleanWidget>: it can always use only operator equal by default, then operator select can be hidden.

operatorInlineLabel

*

Can be used together with hideOperator to render text/JSX instead of operator select input.

ℹ️
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).

 
 

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

valueSources

keys of valueSourcesInfo at config.settings

Array with values 'value', 'field', 'func'. If 'value' is included, you can compare field with values. If 'field' is included, you can compare field with another field of same type. If 'func' is included, you can compare field with result of function (see config.funcs).

defaultOperator

If specified, it will be auto selected when user selects field

widgets.*

+

Available widgets for current type and their config.
Normally there is only 1 widget per type. But see type number at packages/examples/src/demo/config - it has 4 widgets: number, slider, rangeslider, price.
Or see type select - it has widget select for operator = and widget multiselect for operator IN.

widgets.<widget>.operators

List of operators for widget, described in config.operators

widgets.<widget>.widgetProps

Can be used to override config of corresponding widget specified in config.widgets. Example: {timeFormat: 'h:mm:ss A'} for time field with AM/PM.

widgets.<widget>.opProps.<operator>

Can be used to override config of operator for widget. Example: opProps: { between: {valueLabels: ['Time from', 'Time to']} } for building range of times.

 
 

config.funcs

{
  lower: {
    label: 'Lowercase',
    sqlFunc: 'LOWER',
    mongoFunc: '$toLower',
    returnType: 'text',
    args: {
      str: {
        type: 'text',
        valueSources: ['value', 'field'],
      }
    }
  },
  ..
}
key required default meaning

returnType

+

One of types described in config.types

label

same as func key

Label to be displayed in functions list

args.*

Arguments of function. Config is almost same as for simple fields. See "Argument config" below

allowSelfNesting

false

Allows the function to be used within its own arguments.

formatFunc

Example result: for isForDisplay==false - FUNC(val1, val2), for isForDisplay==true - FUNC(arg1: val1, arg2: val2)

Function for formatting func expression in query rule.
(Object args, bool isForDisplay) ⇒ string
where args is object {<arg name> : <arg value>}

sqlFunc

- for SQL format

same as func key

Func name in SQL

sqlFormatFunc

- for SQL format

Can be used instead of sqlFunc. Function with 1 param - args object {<arg name> : <arg value>}, should return formatted function expression string.
Example: SUM function can be formatted with ({a, b}) ⇒ a + " + " + b

sqlImport

- for SQL format

Function to convert given raw SQL value (not string, but object got from node-sql-parser) to {args: Object}. If given expression can’t be parsed into current function, throw an error.

spelFunc

- for SpEL format

same as func key

Func name in SpEL

spelFormatFunc

- for SpEL format

Can be used instead of spelFunc. Function with 1 param - args object {<arg name> : <arg value>}, should return formatted function expression string.
Example: SUM function can be formatted with ({a, b}) ⇒ a + " + " + b

mongoFunc

- for MongoDB format

same as func key

Func name in Mongo

mongoArgsAsObject

false

Some functions like $rtrim supports named args, other ones like $slice takes args as array

mongoFormatFunc

- for MongoDB format

Can be used instead of mongoFunc. Function with 1 param - args object {<arg name> : <arg value>}, should return formatted function expression object.

jsonLogic

+ for JsonLogic

String (function name) or function with 1 param - args object {<arg name> : <arg value>}, should return formatted function expression for JsonLogic.

jsonLogicImport

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.

spelImport

Function to convert given raw SpEL value to object of arguments of current function. If given value can’t be parsed into current function, throw an error or return undefined.

renderBrackets

['(', ')']

Can render custom function brackets in UI (or not render).

renderSeps

[', ']

Can render custom arguments separators in UI (other than ,).

Argument config:

key required default meaning

label

arg’s key

Label to be displayed in arg’s label or placeholder (if config.settings.showLabels is false)

type

+

One of types described in config.types

valueSources

keys of valueSourcesInfo at config.settings

Array with values 'value', 'field', 'func', 'const'.
const requires defaultValue

defaultValue

Default value

fieldSettings

Settings for widgets, will be passed as props. Example: {min: 1, max: 10}

fieldSettings.listValues

+ for (multi)select widgets

List of values for Select widget.
Example: [{value: 'yellow', title: 'Yellow'}, {value: 'green', title: 'Green'}]

fieldSettings.treeValues

+ for tree (multi)select widgets

List of values for TreeSelect widget.
Example: [{value: 'warm', title: 'Warm colors'}, {value: 'red', title: 'Red', parent: 'warm'}, {value: 'orange', title: 'Orange', parent: 'warm'}]

isOptional

false

Last args can be optional

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,
  }
};

 
 

config.ctx

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.ConfigUtils.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.ConfigUtils.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.ConfigUtils.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.ConfigUtils.compressConfig(config, BasicConfig);
const config2 = Utils.ConfigUtils.decompressConfig(zipConfig, BasicConfig, ctx); // should be same as `config`
ℹ️
settings.useConfigCompress should be true if you use Utils.ConfigUtils.decompressConfig()

 
 

Serialize entire config to string

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.