Skip to content

Commit d275638

Browse files
committed
Merged branch master into master
2 parents ea9480f + b10bac0 commit d275638

File tree

1 file changed

+286
-4
lines changed

1 file changed

+286
-4
lines changed

README.md

Lines changed: 286 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,299 @@ Inspired by [jQuery QueryBuilder](http://querybuilder.js.org/)
88
Using awesome [Ant Design](https://ant.design/) for widgets
99

1010

11+
### Features
12+
- Highly configurable
13+
- Fields can be of type:
14+
- simple (string, number, bool, date/time/datetime, list)
15+
- structs (will be displayed in selectbox as tree of members)
16+
- custom type (dev should add its own widget component for this) (it's not complex, you can add slider for example)
17+
- Comparison operators can be:
18+
- binary (== != < > ..)
19+
- unary (is empty, is null)
20+
- 'between' (for numbers)
21+
- complex operators like 'proximity'
22+
- Values of fields can be compared with values -or- another fields (of same type)
23+
- Reordering support for rules and groups of rules
24+
- Using awesome [Ant Design](https://ant.design/)
25+
26+
27+
### Demo
28+
[Live Demo](https://ukrbublik.github.io/react-awesome-query-builder)
29+
30+
![Screenshot](https://ukrbublik.github.io/react-awesome-query-builder/screenshot.png)
31+
32+
1133
### Install & use
1234
Install: `npm i react-awesome-query-builder`
1335

1436
See `examples/demo` as example of usage and configuration
1537

1638

17-
### Demo
18-
[Demo](https://ukrbublik.github.io/react-awesome-query-builder)
39+
## Use
40+
```javascript
41+
import React, {Component} from 'react';
42+
import {Query, Builder, Utils as QbUtils} from 'react-awesome-query-builder';
43+
import config from './config'; //see below 'Config format'
44+
import 'react-awesome-query-builder/css/styles.scss';
45+
import 'react-awesome-query-builder/css/compact_styles.scss';
46+
import 'react-awesome-query-builder/css/denormalize.scss';
1947

20-
![Screenshot](https://ukrbublik.github.io/react-awesome-query-builder/screenshot.png)
48+
class DemoQueryBuilder extends Component {
49+
render() {
50+
return (
51+
<div>
52+
<Query
53+
{...config}
54+
//value={you can pass object here, see tree at onChange}
55+
get_children={this.getChildren}
56+
onChange={this.onChange}
57+
></Query>
58+
</div>
59+
);
60+
}
61+
62+
getChildren(props) {
63+
return (
64+
<div>
65+
<div className="query-builder">
66+
<Builder {...props} />
67+
</div>
68+
<div>Query string: {QbUtils.queryString(props.tree, props.config)}</div>
69+
</div>
70+
)
71+
}
72+
73+
onChange(tree) {
74+
//here you can save tree object
75+
}
76+
}
77+
```
78+
79+
## Config format
80+
```javascript
81+
import {Widgets, Operators} from 'react-awesome-query-builder';
82+
const {
83+
TextWidget,
84+
NumberWidget,
85+
SelectWidget,
86+
MultiSelectWidget,
87+
DateWidget,
88+
BooleanWidget,
89+
TimeWidget,
90+
DateTimeWidget,
91+
ValueFieldWidget
92+
} = Widgets;
93+
import en_US from 'antd/lib/locale-provider/en_US';
94+
95+
export default {
96+
conjunctions: {
97+
'AND': {
98+
label: 'And', //label for conjunctions swicther
99+
//(for building query string) function to join rules into group
100+
// children - list of already formatted queries (strings) to be joined with conjuction
101+
// isForDisplay - false by default, for building query string for SQL/expression/etc.,
102+
// true can be used to format query string displayed on collapsed query group
103+
// (not used for now, see Issue #2)
104+
formatConj: (Immultable.List children, string conj, bool isForDisplay) => string,
105+
},
106+
'OR': ...same as for 'AND'
107+
},
108+
109+
fields: {
110+
//Example of atomic field:
111+
name: {
112+
label: 'Quantity',
113+
type: 'number', //one of types described below in section 'types'
114+
//Settings for widgets
115+
// Available settings for Number widget: min, max, step
116+
fieldSettings: {
117+
min: 2,
118+
},
119+
//List of values for Select widget
120+
listValues: {
121+
//<key>: <label to display at list of options>,
122+
yellow: 'Yellow',
123+
green: 'Green',
124+
},
125+
//(optional) You can override here some options of config of corresponding type:
126+
// 'operators', 'defaultOperator', 'widgets', 'valueSources' (see below at section 'types')
127+
},
128+
//Example of special struct field:
129+
members: { //key of field
130+
label: 'Members', //label to display at list of fields
131+
type: '!struct', //special type for struct
132+
subfields: { //only for type == '!struct'
133+
subname: { //key of subfield
134+
label: 'Subname', //label for list of fields
135+
//label for field menu's toggler (for config.renderFieldAndOpAsDropdown == true)
136+
label2: 'MemberName',
137+
type: 'text', //one of types described below in section 'types'
138+
},
139+
},
140+
},
141+
...other fields
142+
},
143+
144+
types: {
145+
number: { //type key
146+
//(optional) Values of fields can be compared with values or another fields
147+
// (see settings.valueSourcesInfo). If you want to compare values of this type
148+
// only with values or other fields of this type, edit:
149+
valueSources: ['value'],
150+
//Available widgets for type and its configs:
151+
widgets: {
152+
number: { //widget key, see section 'widgets' below
153+
//List of operators can be applied to this type (see section 'operators' below)
154+
operators: ['greater', 'less'],
155+
defaultOperator: 'greater', //default operator to be selected for this type
156+
//Config for this widget (all optional):
157+
widgetProps: {
158+
//for example, here you can overwrire 'valueLabel', 'valuePlaceholder',
159+
// for date/time: 'timeFormat', 'dateFormat', 'valueFormat'
160+
},
161+
//Config for operators for this widget (all optional):
162+
opProps: {
163+
between: { //operator key
164+
//for example, here you can overwrire 'valueLabels'
165+
},
166+
...other ops
167+
},
168+
},
169+
//Most of types can have only 1 widget, but for list there can be 2:
170+
// single-select widget (for op ==) and multi-select widget (for op 'in')
171+
...other widgets if applicable
172+
//'field' is special widget to compare values of field of this type
173+
// with another fields (of this type)
174+
field: {
175+
...you can overwrire 'operators' for example
176+
}
177+
}
178+
},
179+
...other types
180+
},
181+
182+
operators: {
183+
equal: { //operator key
184+
label: '==', //label for selectbox
185+
labelForFormat: '==', //string used for formatting query, only if 'formatOp' is not present
186+
reversedOp: 'not_equal', //operator opposite to current
187+
cardinality: 1, //number of right operands (1 for binary, 2 for 'between')
188+
isUnary: true,
189+
//(for building query string) function to format rule
190+
// value - string (already formatted value) for cardinality==1
191+
// -or- Immutable.List of strings for cardinality!=1
192+
formatOp: (string field, string op, mixed value, string valueSrc, string valueType,
193+
Object opDef, Object operatorOptions, bool isForDisplay) => string,
194+
//for cardinality==2 ('between')
195+
valueLabels: ['Value from', {label: 'Value to', placeholder: 'Enter value to'}],
196+
textSeparators: [null, 'and'],
197+
...also see examples/demo for config of 'proximity' operator
198+
},
199+
},
200+
201+
widgets: {
202+
text: {
203+
type: "text", //see 'types' section
204+
valueSrc: 'value', //'value' or 'field' (only for special 'field' widget)
205+
factory: (props) => <TextWidget {...props} />, //React component
206+
//(for building query string) function to format widget's value
207+
formatValue: (mixed val, Object fieldDef, Object wgtDef, bool isForDisplay) => string,
208+
//func to validate widget's value
209+
validateValue: (mixed val, Object fieldDef) => bool,
210+
//Options:
211+
// common:
212+
valueLabel: "Text",
213+
valuePlaceholder: "Enter text",
214+
// for date/time widgets:
215+
timeFormat: 'HH:mm',
216+
dateFormat: 'YYYY-MM-DD',
217+
valueFormat: 'YYYY-MM-DD HH:mm',
218+
// ...for your custom widgets you can add here your options
219+
},
220+
...other widgets (you can add your custom ones here)
221+
...also there should be special 'field' widget, see examples/demo
222+
},
223+
224+
settings: {
225+
//Locale used for AntDesign widgets
226+
locale: {
227+
short: 'en',
228+
full: 'en-US',
229+
antd: en_US,
230+
},
231+
//Don't show conjunctions switcher for only 1 rule?
232+
hideConjForOne: true,
233+
//Size of AntDesign components
234+
renderSize: 'small',
235+
//How to render conjunctions switcher? true - use RadioGroup, false - use ButtonGroup
236+
renderConjsAsRadios: false,
237+
//How to render fields/ops list? true - use Dropdown/Menu, false - use Select
238+
renderFieldAndOpAsDropdown: false,
239+
//Strategies for selecting operator for new field (used by order until success)
240+
// 'default' (default if present), 'keep' (keep prev from last field), 'first', 'none'
241+
setOpOnChangeField: ['keep', 'default'],
242+
//Clear value on field change? false - if prev & next fields have same type (widget), keep
243+
clearValueOnChangeField: false,
244+
//Clear value on operator change?
245+
clearValueOnChangeOp: false,
246+
//?
247+
setDefaultFieldAndOp: false,
248+
//Max nesting for rule groups
249+
maxNesting: 10,
250+
//Separaor for struct fields
251+
fieldSeparator: '.', //also used for formatting
252+
fieldSeparatorDisplay: '->', //used for toggler's text for renderFieldAndOpAsDropdown==true
253+
//Show labels under all ui fields?
254+
showLabels: false,
255+
//Next options are for localization:
256+
valueLabel: "Value",
257+
valuePlaceholder: "Value",
258+
fieldLabel: "Field",
259+
operatorLabel: "Operator",
260+
fieldPlaceholder: "Select field",
261+
operatorPlaceholder: "Select operator",
262+
deleteLabel: null,
263+
addGroupLabel: "Add group",
264+
addRuleLabel: "Add rule",
265+
delGroupLabel: null,
266+
valueSourcesPopupTitle: "Select value source",
267+
//Leave empty group after deletion or add 1 clean rule immediately?
268+
canLeaveEmptyGroup: true, //after deletion
269+
//(for building query string) function to format rule with reverse operator
270+
// which haven't 'formatOp'
271+
// q - already formatted rule for opposite operator (which have 'formatOp')
272+
// return smth like "NOT(" + q + ")"
273+
formatReverse: (string q, string operator, string reversedOp, Object operatorDefinition,
274+
Object revOperatorDefinition, bool isForDisplay) => string,
275+
//(for building query string) function to format field
276+
// parts - for struct field
277+
// label2 - with using of 'fieldSeparatorDisplay'
278+
//just return field (or label2 for isForDisplay==true)
279+
formatField: (string field, Array parts, string label2, Object fieldDefinition, Object config,
280+
bool isForDisplay) => string,
281+
//Values of fields can be compared with values or another fields
282+
//If you want to disable this feature and leave only comparing with values, remove 'field'
283+
valueSourcesInfo: {
284+
value: {
285+
label: "Value"
286+
},
287+
field: {
288+
label: "Field",
289+
widget: "field",
290+
}
291+
},
292+
//Activate reordering support for rules and groups of rules?
293+
canReorder: true,
294+
//(For comparing field with field) Function for building right list of fields to compare
295+
canCompareFieldWithField: (string leftField, Object leftFieldConfig, string rightField,
296+
Object rightFieldConfig) => {
297+
//for type == 'select'/'multiselect' you can check listValues
298+
return true;
299+
},
300+
},
301+
}
21302

303+
```
22304

23305
### Development
24306
To build the component locally, clone this repo then run:
@@ -29,7 +311,7 @@ To build the component locally, clone this repo then run:
29311
Then open localhost:3001 in a browser.
30312

31313
Scripts:
32-
- `prepublish` - Builds a npm module. Output path: `build/npm`
314+
- `npm run build-npm` - Builds a npm module. Output path: `build/npm`
33315
- `npm run build-global` - Builds with webpack the self contained pack of the component. Output path: `build/global`
34316
- `npm run build-examples` - Builds with webpack the examples. Output path: `examples`
35317
- `npm run examples` - Builds with webpack the examples and runs a dev-server on localhost:3001.

0 commit comments

Comments
 (0)