@@ -8,17 +8,299 @@ Inspired by [jQuery QueryBuilder](http://querybuilder.js.org/)
88Using 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
1234Install: ` npm i react-awesome-query-builder `
1335
1436See ` 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
24306To build the component locally, clone this repo then run:
@@ -29,7 +311,7 @@ To build the component locally, clone this repo then run:
29311Then open localhost:3001 in a browser.
30312
31313Scripts:
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