0.1.3 • Published 6 years ago

r-query-builder v0.1.3

Weekly downloads
16
License
-
Repository
-
Last release
6 years ago

r-query-builder

User-friendly React component to build queries.

Inspired by jQuery QueryBuilder

Using awesome Ant Design for widgets

Features

  • Highly configurable
  • Fields can be of type:
    • simple (string, number, bool, date/time/datetime, list)
    • structs (will be displayed in selectbox as tree of members)
    • custom type (dev should add its own widget component for this) (it's not complex, you can add slider for example)
  • 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 -or- another fields (of same type)
  • Reordering support for rules and groups of rules
  • Using awesome Ant Design
  • Export to MongoDb or SQL

Install

Install: npm i r-query-builder yarn: yarn add r-query-builder

Use

import React from 'react';
import QueryBuilder from 'r-query-builder';
import config from './queryConfig';
import './App.css';

function App() {
  return (
    <QueryBuilder config={config} />
  );
}

export default App;

Config format

import {Widgets, Operators} from 'react-awesome-query-builder';
const {
    TextWidget,
    NumberWidget,
    SelectWidget,
    MultiSelectWidget,
    DateWidget,
    BooleanWidget,
    TimeWidget,
    DateTimeWidget,
    ValueFieldWidget
} = Widgets;
import en_US from 'antd/lib/locale-provider/en_US';

export default {
  conjunctions: {
    'AND': {
      label: 'And', //label for conjunctions swicther
      //(for building query string) function to join rules into group
      // children - list of already formatted queries (strings) to be joined with conjuction
      // isForDisplay - false by default, for building query string for SQL/expression/etc., 
      //  true can be used to format query string displayed on collapsed query group 
      //  (not used for now, see Issue #2)
      formatConj: (Immultable.List children, string conj, bool not, bool isForDisplay) => string,
      reversedConj: 'OR', //'AND' reverses to 'OR'
      //for building mongodb query:
      mongoConj: '$and',
    },
    'OR': ...same as for 'AND'
  },
  
  fields: {
    //Example of atomic field:
    qty: {
      label: 'Quantity',
      tooltip: 'This is quantity',
      type: 'number', //one of types described below in section 'types'
      //Settings for widgets
      // Available settings for Number widget: min, max, step
      fieldSettings: {
          min: 2,
      },
      //List of values for Select widget
      listValues: {
        //<key>: <label to display at list of options>,
        yellow: 'Yellow',
        green: 'Green',
      },
      //(optional) You can override here some options of config of corresponding type:
      // 'operators', 'defaultOperator', 'widgets', 'valueSources' (see below at section 'types')
    },
    //Example of special struct field:
    members: { //key of field
      label: 'Members', //label to display at list of fields
      type: '!struct', //special type for struct
      subfields: { //only for type == '!struct'
        subname: { //key of subfield
          label: 'Subname', //label for list of fields
          //label for field menu's toggler (for config.renderFieldAndOpAsDropdown == true)
          label2: 'MemberName',
          type: 'text', //one of types described below in section 'types'
        },
      },
    },
    ...other fields
  },
  
  types: {
    number: { //type key
      //(optional) Values of fields can be compared with values or another fields
      // (see settings.valueSourcesInfo). If you want to compare values of this type 
      // only with values or other fields of this type, edit:
      valueSources: ['value'],
      //Available widgets for type and its configs:
      widgets: {
        number: { //widget key, see section 'widgets' below
          //List of operators can be applied to this type (see section 'operators' below)
          operators: ['greater', 'less'],
          defaultOperator: 'greater', //default operator to be selected for this type
          //Config for this widget (all optional):
          widgetProps: {
            //for example, here you can overwrire 'valueLabel', 'valuePlaceholder', 
            // for date/time: 'timeFormat', 'dateFormat', 'valueFormat'

            //also you can pass props directly to widget, for example enable search for Select widget:
            customProps: {
                showSearch: true
            }
          },
          //Config for operators for this widget (all optional):
          opProps: {
            between: { //operator key
              //for example, here you can overwrire 'valueLabels'
            },
            ...other ops
          },
        },
        //Most of types can have only 1 widget, but for list there can be 2: 
        // single-select widget (for op ==) and multi-select widget (for op 'in')
        ...other widgets if applicable
        //'field' is special widget to compare values of field of this type
        // with another fields (of this type)
        field: {
          ...you can overwrire 'operators' for example
        }
      }
    },
    ...other types
  },
  
  operators: {
    equal: { //operator key
      label: '==', //label for selectbox
      labelForFormat: '==', //string used for formatting query, only if 'formatOp' is not present
      reversedOp: 'not_equal', //operator opposite to current
      cardinality: 1, //number of right operands (1 for binary, 2 for 'between')
      isUnary: true,
      //(for building query string) function to format rule
      // value - string (already formatted value) for cardinality==1 
      // -or- Immutable.List of strings for cardinality>1
      formatOp: (string field, string op, mixed value, string valueSrc, string valueType, 
        Object opDef, Object operatorOptions, bool isForDisplay) => string,
      //(for building mongodb query) function to format rule
      // value - mixed for cardinality==1 -or- Array for cardinality>2 
      mongoFormatOp: (string field, string op, mixed value, string valueSrc, string valueType, 
        Object opDef, Object operatorOptions) => object,
      //for cardinality==2 ('between')
      valueLabels: ['Value from', {label: 'Value to', placeholder: 'Enter value to'}],
      textSeparators: [null, 'and'],
      ...also see examples/demo for config of 'proximity' operator
    },
  },
  
  widgets: {
    text: {
      type: "text", //see 'types' section
      valueSrc: 'value', //'value' or 'field' (only for special 'field' widget)
      factory: (props) => <TextWidget {...props} />, //React component
      //(for building query string) function to format widget's value
      formatValue: (mixed val, Object fieldDef, Object wgtDef, bool isForDisplay) => string,
      //(for building mongodb query) function to convert widget's value
      mongoFormatValue: (mixed val, Object fieldDef, Object wgtDef) => object,
      //func to validate widget's value
      validateValue: (mixed val, Object fieldDef) => bool,
      //Options:
      // common:
      valueLabel: "Text",
      valuePlaceholder: "Enter text",
      // for date/time widgets:
      timeFormat: 'HH:mm',
      dateFormat: 'YYYY-MM-DD',
      valueFormat: 'YYYY-MM-DD HH:mm',
      // ...for your custom widgets you can add here your options
      // also you can pass customProps, for example to enable search for select widget:
      customProps: { showSearch: true }
    },
    ...other widgets (you can add your custom ones here)
    ...also there should be special 'field' widget, see examples/demo
  },
  
  settings: {
    //Locale used for AntDesign widgets
    locale: {
        short: 'en',
        full: 'en-US',
        antd: en_US,
    },
    //To shorten long labels of fields/values (by length, i.e. number of chars)
    maxLabelsLength: 50,
    //Placement of antdesign's dropdown pop-up menu (default: 'bottomLeft')
    dropdownPlacement: 'bottomRight',
    //Don't show conjunctions switcher for only 1 rule?
    hideConjForOne: true,
    //Size of AntDesign components
    renderSize: 'small',
    //How to render conjunctions switcher? true - use RadioGroup, false - use ButtonGroup
    renderConjsAsRadios: false,
    //How to render fields/ops list? true - use Dropdown/Menu, false - use Select
    renderFieldAndOpAsDropdown: false,
    //You can pass props to Select field widget
    customFieldSelectProps: {
        showSearch: true
    },
    // You can change the position of the group actions to the following:
    // oneOf [topLeft, topCenter, topRight (default), bottomLeft, bottomCenter, bottomRight]
    groupActionsPosition: 'topRight', 
    //Strategies for selecting operator for new field (used by order until success)
    // 'default' (default if present), 'keep' (keep prev from last field), 'first', 'none'
    setOpOnChangeField: ['keep', 'default'],
    //Clear value on field change? false - if prev & next fields have same type (widget), keep
    clearValueOnChangeField: false,
    //Clear value on operator change?
    clearValueOnChangeOp: false,
    //?
    setDefaultFieldAndOp: false,
    //Max nesting for rule groups
    maxNesting: 10,
    //Separaor for struct fields
    fieldSeparator: '.', //also used for formatting
    fieldSeparatorDisplay: '->', //used for toggler's text for renderFieldAndOpAsDropdown==true
    //Show labels under all ui fields?
    showLabels: false,
    //Show NOT together with AND/OR?
    showNot: true,
    //Next options are for localization:
    valueLabel: "Value",
    valuePlaceholder: "Value",
    fieldLabel: "Field",
    operatorLabel: "Operator",
    fieldPlaceholder: "Select field",
    operatorPlaceholder: "Select operator",
    deleteLabel: null,
    addGroupLabel: "Add group",
    addRuleLabel: "Add rule",
    readonlyMode: false,
    notLabel: "Not",
    //If you want to ask confirmation of removing non-empty rule/group, add these options
    //List of all valid properties: https://ant.design/components/modal/#API
    removeRuleConfirmOptions: {
        title: 'Are you sure delete this rule?',
        okText: 'Yes',
        okType: 'danger',
    },
    removeGroupConfirmOptions: {
        title: 'Are you sure delete this group?',
        okText: 'Yes',
        okType: 'danger',
    },
    delGroupLabel: null,
    valueSourcesPopupTitle: "Select value source",
    //Leave empty group after deletion or add 1 clean rule immediately?
    canLeaveEmptyGroup: true, //after deletion
    //(for building query string) function to format rule with reverse operator 
    // which haven't 'formatOp'
    // q - already formatted rule for opposite operator (which have 'formatOp')
    // return smth like "NOT(" + q + ")"
    formatReverse: (string q, string operator, string reversedOp, Object operatorDefinition, 
      Object revOperatorDefinition, bool isForDisplay) => string,
    //(for building query string) function to format field
    // parts - for struct field
    // label2 - with using of 'fieldSeparatorDisplay'
    //just return field (or label2 for isForDisplay==true)
    formatField: (string field, Array parts, string label2, Object fieldDefinition, Object config, 
      bool isForDisplay) => string,
    //Values of fields can be compared with values or another fields
    //If you want to disable this feature and leave only comparing with values, remove 'field'
    valueSourcesInfo: {
      value: {
        label: "Value"
      },
      field: {
        label: "Field",
        widget: "field",
      }
    },
    //Activate reordering support for rules and groups of rules?
    canReorder: true,
    //(For comparing field with field) Function for building right list of fields to compare
    canCompareFieldWithField: (string leftField, Object leftFieldConfig, string rightField, 
      Object rightFieldConfig) => {
        //for type == 'select'/'multiselect' you can check listValues
        return true;
    },
  },
}

License

MIT. See also LICENSE.txt

Forked from https://github.com/fubhy/react-query-builder