@@ -8,17 +8,299 @@ Inspired by [jQuery QueryBuilder](http://querybuilder.js.org/)
8
8
Using awesome [ Ant Design] ( https://ant.design/ ) for widgets
9
9
10
10
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
+
11
33
### Install & use
12
34
Install: ` npm i react-awesome-query-builder `
13
35
14
36
See ` examples/demo ` as example of usage and configuration
15
37
16
38
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' ;
19
47
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
+ }
21
302
303
+ ```
22
304
23
305
### Development
24
306
To build the component locally, clone this repo then run:
@@ -29,7 +311,7 @@ To build the component locally, clone this repo then run:
29
311
Then open localhost:3001 in a browser.
30
312
31
313
Scripts:
32
- - ` prepublish ` - Builds a npm module. Output path: ` build/npm `
314
+ - ` npm run build-npm ` - Builds a npm module. Output path: ` build/npm `
33
315
- ` npm run build-global ` - Builds with webpack the self contained pack of the component. Output path: ` build/global `
34
316
- ` npm run build-examples ` - Builds with webpack the examples. Output path: ` examples `
35
317
- ` npm run examples ` - Builds with webpack the examples and runs a dev-server on localhost:3001.
0 commit comments