Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 72 additions & 14 deletions docs/api/export.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,6 @@ function formatQuery(
- MongoDB
- Common Expression Language (CEL)

:::info

The inversion operator (setting `not: true` for a rule group) is currently unsupported for the MongoDB format, but rules can be created using the `"!="` operator.

:::

For the next few sections, assume the `query` variable has been defined as:

```ts
Expand Down Expand Up @@ -169,6 +163,12 @@ Output:
`{"$and":[{"firstName":{"$eq":"Steve"}},{"lastName":{"$eq":"Vai"}}]}`;
```

:::info

For now, the MongoDB export format has two major shortcomings. For one, it does not support the inversion operator (setting `not: true` for a rule group), however rules _can_ be created using the `"!="` operator. Also, if the query uses [independent combinators](./querybuilder#independentcombinators), it will not be processed and `formatQuery(query, 'mongodb')` will always return the [fallback expression](#fallback-expression).

:::

### Common Expression Language

For Common Expression Language (CEL) output, use the "cel" format.
Expand All @@ -185,7 +185,65 @@ Output:

## Configuration

An object can be passed as the second argument instead of a string in order to have more detailed control over the output.
An object can be passed as the second argument instead of a string to have more fine-grained control over the output.

### Parse numbers

Since HTML `<input>` controls store values as strings (even when `type="number"`), exporting a query to various formats may produce a string representation of a value when a true numeric value is required or more appropriate. Set the `parseNumbers` option to `true` and `formatQuery` will attempt to convert all values to numbers, falling back to the original value if `parseFloat(value)` returns `NaN` (not a number).

```ts
const query: RuleGroupType = {
combinator: 'and',
not: false,
rules: [
{
field: 'digits',
operator: '=',
value: '20',
},
{
field: 'age',
operator: 'between',
value: '26, 52',
},
{
field: 'lastName',
operator: '=',
value: 'Vai',
},
],
};

// Default configuration - all values are strings:
formatQuery(query, { format: 'sql' });
// Returns: "(digits = '20' and age between '26' and '52' and lastName = 'Vai')"

// `parseNumbers: true` - numeric strings converted to actual numbers:
formatQuery(query, { format: 'sql', parseNumbers: true });
// Returns: "(digits = 20 and age between 26 and 52 and lastName = 'Vai')"
```

:::info

To avoid information loss, this option is more strict about what qualifies as "numeric" than [the standard `parseFloat` function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseFloat). Put simply, `parseFloat` works with any string that _starts_ with a numeric sequence, ignoring the rest of the string beginning with the first non-numeric character. When `parseNumbers` is `true`, `formatQuery` will only convert a `value` to a `number` if it appears to be numeric _in its entirety_ (after trimming whitespace).

The following expressions all evaluate to `true`:

```ts
parseFloat('000111abcdef') === 111;

formatQuery(
{ rules: [{ field: 'f', operator: '=', value: '000111abcdef' }] },
{ format: 'sql', parseNumbers: true }
) === "(f = '000111abcdef')";

formatQuery(
{ rules: [{ field: 'f', operator: '=', value: ' 000111 ' }] },
{ format: 'sql', parseNumbers: true }
) === '(f = 111)';
```

:::

### Value processor

Expand All @@ -198,13 +256,13 @@ const query: RuleGroupType = {
rules: [
{
field: 'instrument',
value: ['Guitar', 'Vocals'],
operator: 'in',
value: ['Guitar', 'Vocals'],
},
{
field: 'lastName',
value: 'Vai',
operator: '=',
value: 'Vai',
},
],
};
Expand All @@ -218,7 +276,7 @@ const valueProcessor = (field, operator, value) => {
};

formatQuery(query, { format: 'sql', valueProcessor });
// Output: "(instrument in ('Guitar','Vocals') and lastName = 'Vai')"
// Returns: "(instrument in ('Guitar','Vocals') and lastName = 'Vai')"
```

### Quote field names
Expand All @@ -227,7 +285,7 @@ Some database engines wrap field names in backticks. This can be configured with

```ts
formatQuery(query, { format: 'sql', quoteFieldNamesWith: '`' });
// Output: "(`firstName` = 'Steve' and `lastName` = 'Vai')"
// Returns: "(`firstName` = 'Steve' and `lastName` = 'Vai')"
```

### Parameter prefix
Expand Down Expand Up @@ -306,21 +364,21 @@ formatQuery(query, {
format: 'sql',
validator: () => false,
});
// Output: "(1 = 1)" <-- see `fallbackExpression` option
// Returns: "(1 = 1)" <-- see `fallbackExpression` option

// Rule "r1" is invalid based on the validation map
formatQuery(query, {
format: 'sql',
validator: () => ({ r1: false }),
});
// Output: "(lastName = 'Vai')" <-- skipped `firstName` rule with `id === 'r1'`
// Returns: "(lastName = 'Vai')" <-- skipped `firstName` rule with `id === 'r1'`

// Rule "r1" is invalid based on the field validator for `firstName`
formatQuery(query, {
format: 'sql',
fields: [{ name: 'firstName', validator: () => false }],
});
// Output: "(lastName = 'Vai')" <-- skipped `firstName` rule because field validator returned `false`
// Returns: "(lastName = 'Vai')" <-- skipped `firstName` rule because field validator returned `false`
```

### Automatic validation
Expand Down
2 changes: 1 addition & 1 deletion docs/api/import.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Use the `parseSQL` function to convert SQL `SELECT` statements into a format sui
function parseSQL(sql: string, options?: ParseSQLOptions): RuleGroupTypeAny;
```

`parseSQL` takes a SQL `SELECT` statement (either the full statement or the `WHERE` clause by itself). Try it out in the [demo](https://react-querybuilder.github.io/react-querybuilder/) by clicking the "Load from SQL" button.
`parseSQL` takes a SQL `SELECT` statement (either the full statement or the `WHERE` clause by itself). Try it out in the [demo](https://react-querybuilder.js.org/react-querybuilder/) by clicking the "Load from SQL" button.

The optional second parameter to `parseSQL` is an options object that configures how the function handles named or anonymous bind variables within the SQL string.

Expand Down
2 changes: 1 addition & 1 deletion docs/api/misc.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function defaultValidator(query: RuleGroupType): {

Pass `validator={defaultValidator}` to automatically validate groups (rules will be ignored). A group will be marked invalid if either 1) it has no child rules or groups (`query.rules.length === 0`), or 2) it has a missing/invalid `combinator` and more than one child rule or group (`rules.length >= 2`).

You can see an example of the default validator in action in the [demo](https://react-querybuilder.github.io/react-querybuilder/) if you check the ["Use validation" option](https://react-querybuilder.github.io/react-querybuilder/#validateQuery=true). Empty groups will have bold text on their "+Rule" button and a description of the situation where the rules normally appear.
You can see an example of the default validator in action in the [demo](https://react-querybuilder.js.org/react-querybuilder/) if you check the ["Use validation" option](https://react-querybuilder.js.org/react-querybuilder/#validateQuery=true). Empty groups will have bold text on their "+Rule" button and a description of the situation where the rules normally appear.

### `findPath`

Expand Down
30 changes: 18 additions & 12 deletions docs/api/querybuilder.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -661,35 +661,35 @@ The `translations` prop is optional, and each top-level property in the `transla

### `showCombinatorsBetweenRules`

`boolean` (default `false`) [_Click for demo_](https://react-querybuilder.github.io/react-querybuilder/#showCombinatorsBetweenRules=true)
`boolean` (default `false`) [_Click for demo_](https://react-querybuilder.js.org/react-querybuilder/#showCombinatorsBetweenRules=true)

Pass `true` to show the combinators (and/or) between rules and rule groups instead of at the top of rule groups. This can make some queries easier to understand as it encourages a more natural style of reading.

### `showNotToggle`

`boolean` (default `false`) [_Click for demo_](https://react-querybuilder.github.io/react-querybuilder/#showNotToggle=true)
`boolean` (default `false`) [_Click for demo_](https://react-querybuilder.js.org/react-querybuilder/#showNotToggle=true)

Pass `true` to show the "Not" (aka inversion) toggle switch for each rule group.

### `showCloneButtons`

`boolean` (default `false`) [_Click for demo_](https://react-querybuilder.github.io/react-querybuilder/#showCloneButtons=true)
`boolean` (default `false`) [_Click for demo_](https://react-querybuilder.js.org/react-querybuilder/#showCloneButtons=true)

### `showLockButtons`

`boolean` (default `false`) [_Click for demo_](https://react-querybuilder.github.io/react-querybuilder/#showLockButtons=true)
`boolean` (default `false`) [_Click for demo_](https://react-querybuilder.js.org/react-querybuilder/#showLockButtons=true)

Pass `true` to show the "Lock rule" and "Lock group" buttons. When a rule is locked, all elements within the rule will be disabled (except for the lock button, so the user can unlock it). When a group is locked, all elements within the group header (except the lock button), as well as all child rule/group elements, will be disabled.

### `resetOnFieldChange`

`boolean` (default `true`) [_Click for demo with this feature disabled_](https://react-querybuilder.github.io/react-querybuilder/#resetOnFieldChange=false)
`boolean` (default `true`) [_Click for demo with this feature disabled_](https://react-querybuilder.js.org/react-querybuilder/#resetOnFieldChange=false)

Pass `false` to avoid resetting the operator and value when the field changes.

### `resetOnOperatorChange`

`boolean` (default `false`) [_Click for demo_](https://react-querybuilder.github.io/react-querybuilder/#resetOnOperatorChange=true)
`boolean` (default `false`) [_Click for demo_](https://react-querybuilder.js.org/react-querybuilder/#resetOnOperatorChange=true)

Pass `true` to reset the value when the operator changes.

Expand All @@ -701,25 +701,25 @@ Pass `false` to disable the `onQueryChange` call on mount of the component which

### `autoSelectField`

`boolean` (default `true`) [_Click for demo with this feature disabled_](https://react-querybuilder.github.io/react-querybuilder/#autoSelectField=false)
`boolean` (default `true`) [_Click for demo with this feature disabled_](https://react-querybuilder.js.org/react-querybuilder/#autoSelectField=false)

Pass `false` to add an empty option (`"------"`) to the `fields` array as the first element (which will be selected by default for new rules). When the empty field option is selected, the operator and value components will not display for that rule.

### `addRuleToNewGroups`

`boolean` (default `false`) [_Click for demo_](https://react-querybuilder.github.io/react-querybuilder/#addRuleToNewGroups=true)
`boolean` (default `false`) [_Click for demo_](https://react-querybuilder.js.org/react-querybuilder/#addRuleToNewGroups=true)

Pass `true` to automatically add a rule to new groups. If a `query` prop is not passed in, a rule will be added to the root group when the component is mounted. If a `query` prop is passed in with an empty `rules` array, no rule will be added automatically.

### `independentCombinators`

`boolean` (default `false`) [_Click for demo_](https://react-querybuilder.github.io/react-querybuilder/#independentCombinators=true)
`boolean` (default `false`) [_Click for demo_](https://react-querybuilder.js.org/react-querybuilder/#independentCombinators=true)

Pass `true` to insert an independent combinator selector between each rule/group in a rule group. The combinator selector at the group level will not be available. Visually, this is similar to the [`showCombinatorsBetweenRules`](#showcombinatorsbetweenrules) option, except that each combinator selector is independently controlled. You may find that users take to this configuration more easily, as it can allow them to express queries more like they would in natural language.

### `enableDragAndDrop`

`boolean` (default `false`) [_Click for demo_](https://react-querybuilder.github.io/react-querybuilder/#enableDragAndDrop=true)
`boolean` (default `false`) [_Click for demo_](https://react-querybuilder.js.org/react-querybuilder/#enableDragAndDrop=true)

Pass `true` to display a drag handle to the left of each group header and rule. Clicking and dragging the handle element allows visual reordering of rules and groups.

Expand All @@ -731,12 +731,18 @@ Pass `true` to display a drag handle to the left of each group header and rule.

### `disabled`

`boolean | number[][]` (default `false`) [_Click for demo_](https://react-querybuilder.github.io/react-querybuilder/#disabled=true)
`boolean | number[][]` (default `false`) [_Click for demo_](https://react-querybuilder.js.org/react-querybuilder/#disabled=true)

Pass `true` to disable all subcomponents and prevent changes to the query. Pass an array of paths to disable specific rules and/or groups, e.g. `disabled={[[0]]}` will disable the first rule and its subcomponents but nothing else.

### `debugMode`

`boolean` (default `false`) [_Click for demo_](https://react-querybuilder.js.org/react-querybuilder/#debugMode=true)

Pass `true` to log debugging information to the console.

### `validator`

`QueryValidator` [_Click for demo_](https://react-querybuilder.github.io/react-querybuilder/#validateQuery=true)
`QueryValidator` [_Click for demo_](https://react-querybuilder.js.org/react-querybuilder/#validateQuery=true)

This is a callback function that is executed each time `QueryBuilder` renders. The return value should be a boolean (`true` for valid queries, `false` for invalid) or an object whose keys are the `id`s of each rule and group in the query tree. If such an object is returned, the values associated to each key should be a boolean (`true` for valid rules/groups, `false` for invalid) or an object with a `valid` boolean property and an optional `reasons` array. The full object will be passed to each rule and group component, and all sub-components of each rule/group will receive the value associated with the rule's or group's `id`. See the [Validation](./validation) documentation for more information.
4 changes: 2 additions & 2 deletions docs/api/validation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ If you provide a query- or field-level validator function then the wrapper `<div

:::tip See it in action

In the [demo](https://react-querybuilder.github.io/react-querybuilder/), check the "Use validation" option and create an empty group or a text input without a value. Empty groups will show a message where the rules usually appear (using the `:after` pseudo-selector), and text fields without values will have a [purple](https://meyerweb.com/eric/thoughts/2014/06/19/rebeccapurple/) outline.
In the [demo](https://react-querybuilder.js.org/react-querybuilder/), check the "Use validation" option and create an empty group or a text input without a value. Empty groups will show a message where the rules usually appear (using the `:after` pseudo-selector), and text fields without values will have a [purple](https://meyerweb.com/eric/thoughts/2014/06/19/rebeccapurple/) outline.

:::

Expand All @@ -120,4 +120,4 @@ See the [validation section on the Export page](./export#validation) for more in

## Default validator

You can pass the provided [`defaultValidator`](./misc#defaultvalidator) to the `validator` prop to check for invalid combinators, empty groups, or (if `independentCombinators` is true) out-of-sequence `rules` arrays. The [demo](https://react-querybuilder.github.io/react-querybuilder/) uses the default validator.
You can pass the provided [`defaultValidator`](./misc#defaultvalidator) to the `validator` prop to check for invalid combinators, empty groups, or (if `independentCombinators` is true) out-of-sequence `rules` arrays. The [demo](https://react-querybuilder.js.org/react-querybuilder/) uses the default validator.
2 changes: 1 addition & 1 deletion docs/api/valueeditor.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ This query builder has been specially configured in two ways:

:::tip

The [compatibility packages](../compat) also implement these options using appropriate components from the associated style library ([see the demo](https://react-querybuilder.github.io/react-querybuilder/)).
The [compatibility packages](../compat) also implement these options using appropriate components from the associated style library ([see the demo](https://react-querybuilder.js.org/react-querybuilder/)).

:::

Expand Down
47 changes: 43 additions & 4 deletions docs/intro.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ In the query builder below, click the "+Rule" button and then the fields selecto
<SandpackRQB options={{ editorHeight: 240 }}>

```tsx
import QueryBuilder from 'react-querybuilder';
import { QueryBuilder } from 'react-querybuilder';
import 'react-querybuilder/dist/query-builder.scss';

const fields: Field[] = [
Expand All @@ -56,7 +56,7 @@ The state variable `query` will be passed to the `query` prop, and the setter me

```tsx
import { useState } from 'react';
import QueryBuilder, { Field, RuleGroupType } from 'react-querybuilder';
import { QueryBuilder, Field, RuleGroupType } from 'react-querybuilder';
import 'react-querybuilder/dist/query-builder.scss';

const fields: Field[] = [
Expand Down Expand Up @@ -84,7 +84,7 @@ export default () => {

```jsx
import { useState } from 'react';
import QueryBuilder from 'react-querybuilder';
import { QueryBuilder } from 'react-querybuilder';
import 'react-querybuilder/dist/query-builder.scss';

const fields = [
Expand Down Expand Up @@ -113,9 +113,48 @@ This documentation primarily demonstrates use of the ESM and CommonJS builds of

:::

## Exporting queries

To convert a query object into other formats like [SQL](https://en.wikipedia.org/wiki/SQL), [MongoDB](https://www.mongodb.com/), and [CEL](https://github.com/google/cel-spec), you can use the `formatQuery` function ([full documentation here](./api/export)). The example below demonstrates the conversion of a query to its equivalent SQL form. Modify the query by manipulating the form elements and the SQL will update accordingly.

<SandpackRQB options={{ editorHeight: 480 }}>

```tsx
import { useState } from 'react';
import { QueryBuilder, Field, formatQuery, RuleGroupType } from 'react-querybuilder';
import 'react-querybuilder/dist/query-builder.scss';

const fields: Field[] = [
{ name: 'firstName', label: 'First Name' },
{ name: 'lastName', label: 'Last Name' },
];

export default () => {
const [query, setQuery] = useState<RuleGroupType>({
combinator: 'and',
rules: [
{ field: 'firstName', operator: 'beginsWith', value: 'Stev' },
{ field: 'lastName', operator: 'in', value: 'Vai,Vaughan' },
],
});

return (
<>
<QueryBuilder fields={fields} query={query} onQueryChange={q => setQuery(q)} />
<h4>
SQL as result of <code>formatQuery(query, 'sql')</code>:
</h4>
<pre>{formatQuery(query, 'sql')}</pre>
</>
);
};
```

</SandpackRQB>

## Onward and upward!

To discover all the options of React Query Builder, check out the [API documentation](./api/querybuilder). To play around with various configurations, check out the ["kitchen sink" demo](https://react-querybuilder.github.io/react-querybuilder/).
To discover all the options of React Query Builder, check out the [API documentation](./api/querybuilder). To play around with various configurations, including other export formats and [importing from SQL](./api/import), check out the ["kitchen sink" demo](https://react-querybuilder.js.org/react-querybuilder/).

## Training

Expand Down
Loading