Skip to content

Latest commit

 

History

History
991 lines (892 loc) · 41.9 KB

CONFIG.adoc

File metadata and controls

991 lines (892 loc) · 41.9 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, 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

 

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

 

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 and Slider widgets: min, max, step. Slider also supports marks (example: { 0: "0%", 100: "100%" }).
Available settings for date/time widgets: timeFormat, dateFormat, valueFormat, use12Hours, useKeyboard.
Available settings for text widget: maxLength, maxRows.

fieldSettings.listValues

+ for (multi)select

List of values for (multi)select widget.
Example: [{value: 'yellow', title: 'Yellow'}, {value: 'green', title: 'Green'}] (or alternatively { yellow: 'Yellow', green: 'Green' })

fieldSettings.treeValues

+ for tree (multi)select

List of values for tree (multi)select widget.
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'} ]}])

fieldSettings.validateValue

Function to validate entered value. Return true/false or error string / null.
(mixed val, Object fieldSettings) ⇒ boolean | string | null

fieldSettings.allowCustomValues

- for multiselect widget

false

If true, user can provide own options in multiselect, otherwise they will be limited to listValues

fieldSettings.showSearch

- for (multi)select, tree (multi)select

false

Show search (autocomplete)?

fieldSettings.treeExpandAll

- for treeselect/treemultiselect widgets

false

Whether to expand all nodes by default

fieldSettings.treeSelectOnlyLeafs

- for treeselect widget

true

Can select only leafs or any node?

fieldSettings.asyncFetch

- for select widget

Async function to load list of options for select from server.
Function format: async (string search, int offset) ⇒ { values: Array, hasMore: boolean }
values - list of {title: string, value: mixed}
For server-side select listValues will not be used. See also useLoadMore, useAsyncSearch.

fieldSettings.useAsyncSearch

- for select widget

false

If true, asyncFetch supports search.

fieldSettings.useLoadMore

- for select widget

false

If true, asyncFetch supports pagination.

defaultValue

Default value

preferWidgets

See usecase at examples/demo for slider field.
Its type is number. There are 3 widgets defined for number type: number, slider, rangeslider.
So setting preferWidgets: ['slider', 'rangeslider'] will force rendering slider, and setting preferWidgets: ['number'] will render number 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

 
 

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",
    }
  },
  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: {}}

By default fields can be compared with values.
If you want to enable comparing with another fields, add field like in example above.
If you want to enable comparing with result of function, add func like in example above.

showErrorMessage

false

Show error message in QueryBuilder if validateValue() in field config returns false

canReorder

true

Activate reordering support for rules and groups of rules?

canRegroup

true

Allow move rules (or groups) in/out groups during reorder?
False - allow "safe" reorder, means only reorder at same level

showNot

true

Show NOT together with AND/OR?

forceShowConj

false

Show conjuction for 1 rule in group?

maxNumberOfRules

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

maxNesting

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

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

true

Remove incomplete rules (w/o value) during validation in Utils.checkTree()?

removeEmptyGroupsOnLoad

true

Remove empty groups during validation in Utils.checkTree()?

removeInvalidMultiSelectValuesOnLoad

true

Remove values that are not in listValues during validation in Utils.checkTree()?
By default true, but false for AntDesign as can be removed manually

useConfigCompress

false

Set to true if you use Utils.decompressConfig()

💡
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

renderSize

small

Size of AntDesign components - small or large

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, renderButtonGroup, renderSwitch, renderProvider, renderValueSources, renderConfirm, useConfirm, renderRuleError

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

renderItem

Render Item
Able to Customize Render behavior for rule/group items.

showLabels

false

Show labels above all fields?

maxLabelsLength

100

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

dropdownPlacement

bottomLeft

Placement of antdesign’s dropdown pop-up menu

customFieldSelectProps

{}

You can pass props to FieldSelect widget. Example: {showSearch: true}

groupActionsPosition

topRight

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

renderBeforeWidget

renderAfterWidget

renderBeforeActions

renderAfterActions

defaultSliderWidth

200px

Width for slider

defaultSelectWidth

200px

Width for select

defaultSearchWidth

100px

Width for search in autocomplete

defaultMaxRows

5

Max rows for textarea

Other 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

theme.material

{}

Options for createTheme

theme.mui

{}

Options for createTheme

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.

Localization:

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

notLabel

Not

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

 
 

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

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 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

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

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 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

v ⇒ SqlString.escape(v)

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

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

config.settings.valueLabel

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

valuePlaceholder

config.settings.valuePlaceholder

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

maxLength

Option for <TextWidget>, <TextAreaWidget>

maxRows

Option for <TextAreaWidget>

timeFormat

HH:mm:ss

Option for <TimeWidget>, <DateTimeWidget> to display time in widget. Example: 'HH:mm'

use12Hours

false

Option for <TimeWidget>

dateFormat

YYYY-MM-DD

Option for <DateWidget>, <DateTimeWidget> to display date in widget. Example: YYYY-MM-DD

valueFormat

Option for <TimeWidget>, <DateWidget>, <DateTimeWidget> to prepare string representation of value to be stored. Example: YYYY-MM-DD HH:mm

labelYes, labelNo

Option for <BooleanWidget>

customProps

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

hideOperator

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

 
 

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 examples/demo - it has 3 widgets number, slider, rangeslider.
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

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

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.

args.*

Arguments of function. Config is almost same as for simple fields

args.<arg>.label

arg’s key

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

args.<arg>.type

+

One of types described in config.types

args.<arg>.valueSources

keys of valueSourcesInfo at config.settings

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

args.<arg>.defaultValue

Default value

args.<arg>.fieldSettings

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

args.<arg>.fieldSettings.listValues

+ for (multi)select widgets

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

args.<arg>.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'}]

args.<arg>.isOptional

false

Last args can be optional

renderBrackets

['(', ')']

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

renderSeps

[', ']

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

allowSelfNesting

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

 
 

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.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()

 
 

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.