User-friendly React component to build queries.
Inspired by jQuery QueryBuilder
Using awesome Ant Design for widgets
Master branch uses antd v3.
For antd v2 (which has more compact style) see branch antd-2 and versions 0.1.*
.
- Highly configurable
- Fields can be of type:
- simple (string, number, bool, date/time/datetime, list)
- structs (will be displayed in selectbox as tree)
- custom type (dev should add its own widget component in config for this)
- Comparison operators can be:
- binary (== != < > ..)
- unary (is empty, is null)
- 'between' (for numbers)
- complex operators like 'proximity'
- Values of fields can be compared with:
- values
- another fields (of same type)
- function (argumentss also can be values/fields/funcs)
- Reordering (drag-n-drop) support for rules and groups of rules
- Using awesome Ant Design (but using custom widgets of another framework is possible)
- Export to MongoDb, SQL, JsonLogic or your custom format
- Import from JsonLogic
- TypeScript support (see types and demo in TS)
Install: npm i react-awesome-query-builder
See basic usage and API below.
Also see examples/demo
(TS) or sandbox/src/demo
(JS) for more advanced usage and configuration.
import React, {Component} from 'react';
import {Query, Builder, BasicConfig, Utils as QbUtils} from 'react-awesome-query-builder';
import 'react-awesome-query-builder/css/antd.less';
// or import "antd/dist/antd.css";
import 'react-awesome-query-builder/css/styles.scss';
import 'react-awesome-query-builder/css/compact_styles.scss'; //optional, for more compact styles
// You need to provide your own config. See below 'Config format'
const config = {
...BasicConfig,
fields: {
qty: {
label: 'Qty',
type: 'number',
fieldSettings: {
min: 0,
},
valueSources: ['value'],
preferWidgets: ['number'],
},
price: {
label: 'Price',
type: 'number',
valueSources: ['value'],
fieldSettings: {
min: 10,
max: 100,
},
preferWidgets: ['slider', 'rangeslider'],
},
color: {
label: 'Color',
type: 'select',
valueSources: ['value'],
listValues: [
{ value: 'yellow', title: 'Yellow' },
{ value: 'green', title: 'Green' },
{ value: 'orange', title: 'Orange' }
],
},
is_promotion: {
label: 'Promo?',
type: 'boolean',
operators: ['equal'],
valueSources: ['value'],
},
}
};
// You can load query value from your backend storage (for saving see `Query.onChange()`)
const queryValue = {"id": QbUtils.uuid(), "type": "group"};
class DemoQueryBuilder extends Component {
state = {
tree: QbUtils.checkTree(QbUtils.loadTree(queryValue), config),
config: config
};
render = () => (
<div>
<Query
{...config}
value={this.state.tree}
onChange={this.onChange}
renderBuilder={this.renderBuilder}
/>
{this.renderResult(this.state)}
</div>
)
renderBuilder = (props) => (
<div className="query-builder-container" style={{padding: '10px'}}>
<div className="query-builder qb-lite">
<Builder {...props} />
</div>
</div>
)
renderResult = ({tree: immutableTree, config}) => (
<div className="query-builder-result">
<div>Query string: <pre>{JSON.stringify(QbUtils.queryString(immutableTree, config))}</pre></div>
<div>MongoDb query: <pre>{JSON.stringify(QbUtils.mongodbFormat(immutableTree, config))}</pre></div>
<div>SQL where: <pre>{JSON.stringify(QbUtils.sqlFormat(immutableTree, config))}</pre></div>
<div>JsonLogic: <pre>{JSON.stringify(QbUtils.jsonLogicFormat(immutableTree, config))}</pre></div>
</div>
)
onChange = (immutableTree, config) => {
// Tip: for better performance you can apply `throttle` - see `examples/demo`
this.setState({tree: immutableTree, config: config});
const jsonTree = QbUtils.getTree(immutableTree);
console.log(jsonTree);
// `jsonTree` can be saved to backend, and later loaded to `queryValue`
}
}
Props:
{...config}
- destructured queryCONFIG
value
- query value in internal Immutable formatonChange
- callback when value changed. Params:value
(in Immutable format),config
.renderBuilder
- function to render query builder itself. Takes 1 paramprops
you need to pass into<Builder {...props} />
.
Notes:
- If you put query builder component inside Material-UI's
<Dialog />
or<Popover />
, please:- use prop
disableEnforceFocus={true}
for dialog or popver - set css
.MuiPopover-root, .MuiDialog-root { z-index: 1000 !important; }
- use prop
Render this component only inside Query.renderBuilder()
like in example above:
renderBuilder = (props) => (
<div className="query-builder-container">
<div className="query-builder qb-lite">
<Builder {...props} />
</div>
</div>
)
Wrapping <Builder />
in div.query-builder
is necessary.
Optionally you can add class .qb-lite
to it for showing action buttons (like delete rule/group, add, etc.) only on hover, which will look cleaner.
Wrapping in div.query-builder-container
is necessary if you put query builder inside scrollable block.
- Save, load:
Convert query value from internal Immutable format to JS format.
You can use it to save value on backend in
onChange
callback of<Query>
. Convert query value from JS format to internal Immutable format. You can use it to load saved value from backend and pass asvalue
prop to<Query>
(don't forget to also applycheckTree()
). Validate query value corresponding to config. Invalid parts of query (eg. if field was removed from config) will be deleted. - Export:
Convert query value to custom string representation.
isForDisplay
= true can be used to make string more "human readable". Convert query value to MongoDb query object. Convert query value to SQL where string. Convert query value to JsonLogic format. If there are noerrors
,logic
will be rule object anddata
will contain all used fields with null values ("template" data). - Import: Convert query value from JsonLogic format to internal Immutable format.
See CONFIG
See CHANGELOG
To build the component locally, clone this repo then run:
npm install
npm run examples
Then open localhost:3001 in a browser.
Scripts:
npm run examples
- Builds with webpack the examples and runs a dev-server on localhost:3001.npm run build-examples
- Builds with webpack the examples. Output path:examples
npm run build-npm
- Builds a npm module. Output path:build/npm
The repo sticks in general to the Airbnb JavaScript Style Guide.
Feel free to open PR to add new reusable types/widgets/operators (eg., regex operator for string, IP type & widget).
Pull Requests are always welcomed :)
MIT. See also LICENSE.txt
Forked from https://github.com/fubhy/react-query-builder