Set the name of the required input for Batch in query widget using new conditions

Hi,

We are using Webix Pro Edition (Webix UI v.10.2.1) , Is there any option to set the name of the required input for Batch as ‘select’ or ‘combo’ or ‘richselect’ or ‘richtext’?.

https://snippet.webix.com/awefqd96

Only ‘text’, ‘number’, ‘date’ working as expected

Ex:
var maxLength = {
id: “max-length”,
value: “Max Length”,
batch: “richselect”,
handler: (a, v) => a.length <= v,
};

Other than ‘text’ , above mentioned batch values are not working for me in Query widget,

Old Sample:

image
We have the same functionality in lower version (Webix UI v.7.3.5) with querybuilder as like below given snippet , FYI.

var coulmnCountEditor = { view: “richselect”, options: [“Column Count”] };
var associatedFileListEditor = { view: “richselect”, options: $scope.associatedFileLists };
var recordDelimiter = { view: “richselect”, options: [“Header Delimiter”] };

$scope.operators = [
{ view: “select”, name: “equal”, id: “RecordColumnCount”, type: { “RecordColumnCount”: coulmnCountEditor } },
{ view: “select”, name: “contains”, id: “AssociatedFileList”, type: { “AssociatedFileList”: associatedFileListEditor } },
{ view: “select”, name: “equal”, id: “RecordDelimiter”, type: { “RecordDelimiter”: recordDelimiter } }
]

webix.ui({
container: “rule-builder-control”,
view: “querybuilder”,
id: “querybuilder”,
fields: $scope.fields,
filters: $scope.operators,
maxLevel: $scope.maxlevel,
inputMaxWidth: 350
});

So we need to achieve same functionality using query widget.

Thanks

Hello @vinoshmani,

As querybuilder is a complitly diffrent widget, which was based not on the Webix Jet (as cirrent view: query), previous functionality is not expected to work.

In order to implement the functionality you described in a Query, Query customization is requested. It is necessary to rewrite the CreateFilter function of FilterView with the:

conditions.map(id => {
			if (id === 'richselect_name') {
				return 
      id: "Name",
      value: "Richselect Name",
      batch: "richselect_name",
      handler: function(a, b) {
        return a == b;
      },
      on: {
		onChange: function() {
			const filter = this.queryView("filter", "parent");
         	filter.applyFilter();
		}
      }
  }
			}
			return id;
		})

Please, check out the snippet with the example: Code Snippet

Hi Team & NatashaS,
Good day,

From the code snippet sample you have shared in your reply, We need some input. What is ‘query’ while have the CustomFilter class.
CustomFilter extends query.views.filter

Because query is undefined in my end,




image

We have reference of the require("@xbs/query") inside webix.ready as well

Below my react component code for reference:

import React, { Component } from "react";

import ReactDOM from "react-dom";

import * as webix from "@xbs/webix-pro";

import "@xbs/webix-pro/webix.css";

import "@xbs/query/codebase/query.css";

class QueryBuilder extends Component {

    constructor(props) {

        super(props);

        this.uiContainer = React.createRef();

    }

    handleSaveQuery = () => {

        if (this.ui) {

            return this.ui.getState().value; // Get the generated query

        }

    };

    render() {

        return <div ref={this.uiContainer} style={{ height: "100%" }} ></div>;

    }

    componentDidUpdate() {

        const container = ReactDOM.findDOMNode(this.uiContainer.current);

       

            webix.ready(() => {

                require("@xbs/query");

                if (this.ui) {

                    this.ui.destructor();

                    this.ui = null;

                }

                               

                const richselectConditions = {

                    id: "Name",

                    value: "Richselect Name",

                    batch: "richselect_name",

                    handler: function(a, b) {

                      return a == b;

                    },

                    on: {

                      onChange: function() {

                          const filter = this.queryView("filter", "parent");

                           filter.applyFilter();

                      }

                    }

                };

       

                const inputs = [

                    'text',

                    {

                        view: 'richselect',

                        options:[

                            'Alex',

                            'Diana',

                            'Max'

                        ],

                        moveTitle: false,

                        batch: 'richselect_name',

                        title: (obj) => obj.value,

                        on: {

                            onChange: function() {

                                const filter = this.queryView('filter', 'parent');

                                filter.applyFilter();

                            }

                        }

                    },

                ];

            class CustomFilter extends query.views.filter {

                    CreateFilter(field, type, format, conditions, place) {

                      const newConditions = conditions.map(id => {

                          if (id === 'richselect_name') {

                              return richselectConditions;

                          }

                          return id;

                      });

                      const ui = {

                          view: 'filter',

                          localId: 'filter',

                          inputs: inputs,

                          conditions: newConditions,

                          field,

                          mode: type,

                          template: (o) => {

                              let str = o[field];

                              const parser = o.format || (type == 'date' ? webix.i18n.dateFormatStr : null);

                              if (parser) str = parser(str);

                              return str;

                            },

                          margin: 6,

                      };

             

                      const filter = webix.ui(ui, place);

                      const data = this.app.getService("backend").data(field);

                      filter.parse(data);

                      return filter;

                    }

                }

                const queryUI = webix.ui({

                    view: "query",

                    id: "query",

                    maxLevel: 3,

                    width: 340,

                    override: new Map([[query.views.filter, CustomFilter]]),

                    fields: this.props.field,

                    value: this.props.value,

                    simple: this.props.simpleMode,

                    container,

                });

                this.ui = queryUI;

            });

        this.resObserver = new ResizeObserver(() => {

            if (this.ui) this.ui.adjust();

        });

        this.resObserver.observe(container);

    }

    componentWillUnmount() {

        const container = ReactDOM.findDOMNode(this.uiContainer.current);

        if (this.ui) {

            this.ui.destructor();

            this.ui = null;

        }

        if (this.resObserver) {

            this.resObserver.disconnect();

        }

    }

}

export default QueryBuilder;

Good day @vinoshmani ,

As far as I can see, you are facing an issue with a query reference: require("@xbs/query");

To use this module for the later customizations, you could:

  1. Assign imported module to a variable, for example:
const query = require("@xbs/query");
class CustomFilter extends query.views.filter {
...
}

or

  1. You can use the ProvidePlugin from Webpack to define Webix/Query/Other widgets globally.

The second variant is described in our demo of using Complex widgets in React: GitHub - webix-hub/react-demo-complex: This demo shows how to init Webix complex widgets in React components.
The Webpack config can be found in the config folder (see https://github.com/webix-hub/react-demo-complex/blob/97b76fc2eb45d483c9d63935588fe106347c3ae4/config/webpack.config.js#L750). Here, the core library is available as a global script - in such cases, you can use the import (or require) keyword to import modules in the upper scope.

If you are using create-react-app, you can call the yarn eject command to access the Webpack config.