From d240910cd300658f3bce4704078b4b241ab7e700 Mon Sep 17 00:00:00 2001 From: Jake Boone Date: Mon, 27 Jun 2022 15:49:45 -0700 Subject: [PATCH 1/3] Add `listsAsArrays` prop and `rule-value-list-item` class documentation --- docs/api/classnames.mdx | 12 ++++++++++++ docs/api/querybuilder.mdx | 28 ++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/docs/api/classnames.mdx b/docs/api/classnames.mdx index ef6327ff61..3e6500fcc7 100644 --- a/docs/api/classnames.mdx +++ b/docs/api/classnames.mdx @@ -44,6 +44,17 @@ import { standardClassnames as sc } from 'react-querybuilder'; label: `.${sc.valueSource}`, valueSources: ['value', 'field'], }, + { + name: 'fb1', + label: `Value list`, + operators: [{ name: 'between', label: 'between' }], + valueSources: ['field', 'value'], + comparator: f => f.name === 'fb2', + }, + { + name: 'fb2', + label: `.${sc.valueListItem}`, + }, ]} combinators={[{ name: 'and', label: `.${sc.combinators}` }]} getOperators={() => [{ name: '=', label: `.${sc.operators}` }]} @@ -138,6 +149,7 @@ import { standardClassnames as sc } from 'react-querybuilder'; ], }, { field: 'f3', operator: '=', value: 'f1' }, + { field: 'fb1', operator: 'between', value: 'fb2,fb2', valueSource: 'field' }, ], }} /> diff --git a/docs/api/querybuilder.mdx b/docs/api/querybuilder.mdx index 3bb53ac475..49b503d271 100644 --- a/docs/api/querybuilder.mdx +++ b/docs/api/querybuilder.mdx @@ -720,6 +720,34 @@ Pass `false` to automatically add an "empty" option with value `"~"` and label ` 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. +### `listsAsArrays` + +`boolean` (default `false`) [_Click for demo_](https://react-querybuilder.js.org/react-querybuilder/#listsAsArrays=true) + +Pass `true` to update rule values that represent lists with proper arrays instead of comma-separated strings. Applies when `valueEditorType` is "multiselect" and when a rule's `operator` is "between", "notBetween", "in", or "notIn". + +For example, the default behavior for the "between" operator might produce this rule: + +```json {4} +{ + "field": "f1", + "operator": "between", + "value": "f2,f3", + "valueSource": "field" +} +``` + +When `listsAsArrays` is true, the rule's `value` will be an array: + +```json {4} +{ + "field": "f1", + "operator": "between", + "value": ["f2", "f3"], + "valueSource": "field" +} +``` + ### `independentCombinators` `boolean` (default `false`) [_Click for demo_](https://react-querybuilder.js.org/react-querybuilder/#independentCombinators=true) From e5e9ddd7213f1110e8d3ef69567fb58078f43a93 Mon Sep 17 00:00:00 2001 From: Jake Boone Date: Tue, 28 Jun 2022 15:49:23 -0700 Subject: [PATCH 2/3] Add note about `transformQuery` for mapping custom combinators/operators --- docs/api/export.mdx | 49 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/docs/api/export.mdx b/docs/api/export.mdx index 137146cb7d..6a97bcb3c4 100644 --- a/docs/api/export.mdx +++ b/docs/api/export.mdx @@ -50,6 +50,49 @@ const query: RuleGroupType = { }; ``` +:::tip + +_TL;DR: For best results, use the [default combinators and operators](./misc#defaults) or map custom combinators/operators to the defaults with [`transformQuery`](./misc#transformquery)._ + +While `formatQuery` technically accepts query objects of type `RuleGroupTypeAny` (i.e. `RuleGroupType` or `RuleGroupTypeIC`), it is not guaranteed to process a query correctly unless the query also conforms to the type `DefaultRuleGroupTypeAny` (i.e. `DefaultRuleGroupType` or `DefaultRuleGroupTypeIC`). + +In practice, this means that all `combinator` and `operator` properties in the query must match the `name` of an element in [`defaultCombinators` or `defaultOperators`](./misc#defaults), respectively. If you implement custom combinator/operator names, you can use the [`transformQuery` function](./misc#transformquery) to map your query properties to the defaults. + +For example, assume your implementation replaces the default "between" operator (`{ name: "between", label: "between" }`) with `{ name: "b/w", label: "b/w" }`. Any rules using this operator would have `operator: "b/w"` instead of `operator: "between"`. So if a query looked like this... + +```json +{ + "combinator": "and", + "rules": [ + { + "field": "someNumber", + "operator": "b/w", + "value": "12,14" + } + ] +} +``` + +...you could run it through `transformQuery` with the `operatorMap` option: + +```ts +const newQuery = transformQuery(query, { operatorMap: { 'b/w': 'between' } }); +// { +// "combinator": "and", +// "rules": [ +// { +// "field": "someNumber", +// "operator": "between", +// "value": "12,14" +// } +// ] +// } +``` + +The `newQuery` object would be ready for processing by `formatQuery`, including its special handling of the "between" operator. + +::: + ## Basic usage ### JSON @@ -260,17 +303,17 @@ To avoid information loss, this option is more strict about what qualifies as "n The following expressions all evaluate to `true`: ```ts -parseFloat('000111abcdef') === 111; +parseFloat('000111abcdef') === 111; // everything from the 'a' on is ignored by `parseFloat` formatQuery( { rules: [{ field: 'f', operator: '=', value: '000111abcdef' }] }, { format: 'sql', parseNumbers: true } -) === "(f = '000111abcdef')"; +) === "(f = '000111abcdef')"; // `value` contains non-numeric characters, so remains as-is formatQuery( { rules: [{ field: 'f', operator: '=', value: ' 000111 ' }] }, { format: 'sql', parseNumbers: true } -) === '(f = 111)'; +) === '(f = 111)'; // after trimming whitespace, `value` is wholly numeric ``` ::: From 126c18c62c3e6371d00f8ab9c9177baf5ecaa833 Mon Sep 17 00:00:00 2001 From: Jake Boone Date: Wed, 6 Jul 2022 08:42:00 -0700 Subject: [PATCH 3/3] Add more info about `independentCombinators` and `RuleGroupTypeIC` --- docs/api/querybuilder.mdx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/api/querybuilder.mdx b/docs/api/querybuilder.mdx index 49b503d271..5d4556120c 100644 --- a/docs/api/querybuilder.mdx +++ b/docs/api/querybuilder.mdx @@ -101,7 +101,7 @@ If the `independentCombinators` prop is provided, then the `query` argument will `RuleGroupTypeAny` -The query is an object of type `RuleGroupType` (or `RuleGroupTypeIC`, if [`independentCombinators`](#independentCombinators) is `true`). If this prop is provided, `` will be a controlled component. +The query is an object of type `RuleGroupType` (or `RuleGroupTypeIC`, if [`independentCombinators`](#independentcombinators) is `true`). If this prop is provided, `` will be a controlled component. The `query` prop follows the same format as the parameter passed to the [`onQueryChange`](#onquerychange) callback since they are meant to be used together to control the component. See [examples](https://github.com/react-querybuilder/react-querybuilder/blob/main/examples). @@ -752,7 +752,15 @@ When `listsAsArrays` is true, the rule's `value` will be an array: `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. +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 rendered. + +Visually, this option has a similar effect as 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. + +:::caution + +When the `independentCombinators` option is enabled, the `query` (or `defaultQuery`) prop _must_ be of type `RuleGroupTypeIC` instead of the default `RuleGroupType`. See [`onQueryChange`](#onquerychange) above, or the [Rules and groups section](../typescript#rules-and-groups) of the TypeScript documentation for more information. + +::: ### `enableDragAndDrop`