├── .babelrc ├── .eslintignore ├── .eslintrc ├── .gitignore ├── .npmignore ├── .travis.yml ├── LICENSE.txt ├── README.md ├── css ├── compact_styles.scss ├── denormalize.scss ├── reset.scss └── styles.scss ├── examples ├── demo │ ├── config.js │ └── demo.js ├── index.html ├── index.js ├── webpack.config.js └── webpack.config.production.js ├── karma.conf.js ├── modules ├── actions │ ├── drag.js │ ├── group.js │ ├── index.js │ ├── rule.js │ └── tree.js ├── components │ ├── Builder.js │ ├── Field.js │ ├── Group.js │ ├── Item.js │ ├── Operator.js │ ├── OperatorOptions.js │ ├── Preview.js │ ├── Query.js │ ├── Rule.js │ ├── Widget.js │ ├── containers │ │ ├── GroupContainer.js │ │ ├── OperatorOptionsContainer.js │ │ ├── RuleContainer.js │ │ ├── SortableContainer.js │ │ └── WidgetContainer.js │ ├── operators │ │ ├── Proximity.js │ │ └── index.js │ └── widgets │ │ ├── Boolean.js │ │ ├── Date.js │ │ ├── DateTime.js │ │ ├── MultiSelect.js │ │ ├── Number.js │ │ ├── Range.js │ │ ├── Select.js │ │ ├── Slider.js │ │ ├── Text.js │ │ ├── Time.js │ │ ├── ValueField.js │ │ └── index.js ├── constants.js ├── index.js ├── stores │ └── tree.js └── utils │ ├── configUtils.js │ ├── defaultUtils.js │ ├── index.js │ ├── mongodbFormat.js │ ├── queryBuilderFormat.js │ ├── queryString.js │ ├── stuff.js │ ├── treeUtils.js │ ├── uuid.js │ └── validation.js ├── package.json ├── scripts └── gh-pages.sh ├── tests └── webpack.js └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "react", 4 | "es2015", 5 | "stage-0" 6 | ], 7 | "plugins": [ 8 | ["transform-decorators-legacy"], 9 | ["import", { libraryName: "antd", style: "css" }], 10 | ["transform-es2015-modules-commonjs", { 11 | "allowTopLevelThis": true, 12 | "loose": true 13 | }] 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | build 2 | node_modules -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint-config-airbnb", 3 | "env": { 4 | "browser": true, 5 | "mocha": true, 6 | "node": true 7 | }, 8 | "rules": { 9 | "react/jsx-uses-react": 2, 10 | "react/jsx-uses-vars": 2, 11 | "react/react-in-jsx-scope": 2, 12 | 13 | //Temporarirly disabled due to a possible bug in babel-eslint (todomvc example) 14 | "block-scoped-var": 0, 15 | // Temporarily disabled for test/* until babel/babel-eslint#33 is resolved 16 | "padded-blocks": 0, 17 | // We sometimes create setter callbacks in a loop to obscure the delta of a value. 18 | "no-loop-func": 0 19 | }, 20 | "plugins": [ 21 | "react" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | package-lock.json 4 | .idea 5 | yarn.lock 6 | build 7 | examples/*.ttf 8 | examples/*.svg 9 | examples/*.eot 10 | examples/*.woff 11 | examples/*.woff2 12 | examples/bundle.js 13 | examples/bundle.js.map 14 | .DS_Store 15 | 16 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | examples 2 | scripts 3 | bower.json 4 | karma.conf.js 5 | tests.webpack.js 6 | webpack.config.js 7 | .babelrc 8 | .eslintrc 9 | .eslintignore 10 | .gitignore -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "6.10" 4 | before_install: 5 | install: 6 | - npm install 7 | - npm run build-examples 8 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2016 Sebastian Siemssen 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-awesome-query-builder 2 | 3 | 4 | User-friendly React component to build queries. 5 | 6 | Forked from [https://github.com/fubhy/react-query-builder](https://github.com/fubhy/react-query-builder) 7 | 8 | Inspired by [jQuery QueryBuilder](http://querybuilder.js.org/) 9 | 10 | Using awesome [Ant Design](https://ant.design/) for widgets 11 | 12 | Master branch uses [antd v2](https://2x.ant.design/docs/react/introduce) (because of more compact style). 13 | For [antd v3](https://ant.design/docs/react/introduce) see [branch antd-3](https://github.com/ukrbublik/react-awesome-query-builder/tree/antd-3). 14 | 15 | 16 | ### Features 17 | - Highly configurable 18 | - Fields can be of type: 19 | - simple (string, number, bool, date/time/datetime, list) 20 | - structs (will be displayed in selectbox as tree of members) 21 | - custom type (dev should add its own widget component for this) (it's not complex, you can add slider for example) 22 | - Comparison operators can be: 23 | - binary (== != < > ..) 24 | - unary (is empty, is null) 25 | - 'between' (for numbers) 26 | - complex operators like 'proximity' 27 | - Values of fields can be compared with values -or- another fields (of same type) 28 | - Reordering support for rules and groups of rules 29 | - Using awesome [Ant Design](https://ant.design/) 30 | - Export to MongoDb or SQL 31 | 32 | 33 | ### Demo 34 | [Live Demo](https://ukrbublik.github.io/react-awesome-query-builder) 35 | 36 | ![Screenshot](https://ukrbublik.github.io/react-awesome-query-builder/screenshot.png) 37 | 38 | 39 | ### Install 40 | Install: `npm i react-awesome-query-builder` 41 | 42 | See `examples/demo` as example of usage and configuration. 43 | 44 | For full reordering support you need to add class `query-builder-container` for dom-element which is holding your querybuilder component AND has scrolling. If there is no such dom-element (only body) you can do nothing. 45 | 46 | 47 | ## Use 48 | ```javascript 49 | import React, {Component} from 'react'; 50 | import {Query, Builder, Utils as QbUtils} from 'react-awesome-query-builder'; 51 | import config from './config'; //see below 'Config format' 52 | import 'react-awesome-query-builder/css/styles.scss'; 53 | import 'react-awesome-query-builder/css/compact_styles.scss'; 54 | import 'react-awesome-query-builder/css/denormalize.scss'; 55 | 56 | class DemoQueryBuilder extends Component { 57 | render() { 58 | return ( 59 |
60 | 67 |
68 | ); 69 | } 70 | 71 | getChildren(props) { 72 | return ( 73 |
74 |
75 | 76 |
77 |
Query string: {QbUtils.queryString(props.tree, props.config)}
78 |
Mongodb query: {QbUtils.mongodbFormat(props.tree, props.config)}
79 |
80 | ) 81 | } 82 | 83 | onChange(tree) { 84 | //here you can save tree object: 85 | //var treeJSON = transit.toJSON(tree) 86 | } 87 | } 88 | ``` 89 | 90 | Use can save tree as serialized Immutable object with `transit.toJSON`/`transit.fromJSON` 91 | -or- as plain JS, see `loadTree = function(serTree) {...}` 92 | at `examples/demo/demo.js` (using `Immutable.fromJS` with a little trick) 93 | 94 | 95 | 96 | ## Config format 97 | ```javascript 98 | import {Widgets, Operators} from 'react-awesome-query-builder'; 99 | const { 100 | TextWidget, 101 | NumberWidget, 102 | SelectWidget, 103 | MultiSelectWidget, 104 | DateWidget, 105 | BooleanWidget, 106 | TimeWidget, 107 | DateTimeWidget, 108 | ValueFieldWidget 109 | } = Widgets; 110 | import en_US from 'antd/lib/locale-provider/en_US'; 111 | 112 | export default { 113 | conjunctions: { 114 | 'AND': { 115 | label: 'And', //label for conjunctions swicther 116 | //(for building query string) function to join rules into group 117 | // children - list of already formatted queries (strings) to be joined with conjuction 118 | // isForDisplay - false by default, for building query string for SQL/expression/etc., 119 | // true can be used to format query string displayed on collapsed query group 120 | // (not used for now, see Issue #2) 121 | formatConj: (Immultable.List children, string conj, bool not, bool isForDisplay) => string, 122 | reversedConj: 'OR', //'AND' reverses to 'OR' 123 | //for building mongodb query: 124 | mongoConj: '$and', 125 | }, 126 | 'OR': ...same as for 'AND' 127 | }, 128 | 129 | fields: { 130 | //Example of atomic field: 131 | name: { 132 | label: 'Quantity', 133 | type: 'number', //one of types described below in section 'types' 134 | //Settings for widgets 135 | // Available settings for Number widget: min, max, step 136 | fieldSettings: { 137 | min: 2, 138 | }, 139 | //List of values for Select widget 140 | listValues: { 141 | //: