Query Builder - Custom operators and values for the same field

Hello,

Is it possible to change the value template for one column based on the selected operator?

For instance, for a field called Team, if the operator is Like or Not Like, I want to have a text box where the user can write in their own text. But if it is Equals or Not Equals, I want to display a dropdown so the user can select a value from a list. Is that possible?

Additionally, can I define my own SQL format for a particular operator? For instance, an operator Next Month for a Date column, where the SQL output is supposed to be "Date = '$(NextMonth)'". In this case, there would not be any value input necessary.

Thank you,

KS


7 Replies

YA YuvanShankar Arunagiri Syncfusion Team August 9, 2023 11:31 AM UTC

Hi KS,


Query: Is it possible to change the value template for one column based on the selected operator?


Using the value template feature of QueryBuilder component, we can change value column element based on the operator.


paymentTemplateTemplateColumn = {

        create: () => {

            return createElement('input', { attrs: { 'type': 'text' } });

        },

        destroy: (args: { elementIdstring }) => {

            let dropdownDropDownList = (getComponent(document.getElementById(args.elementId), 'dropdownlist'as DropDownList);

            let textboxTextBox = (getComponent(document.getElementById(args.elementId), 'textbox'as TextBox);

            if (dropdown) {

                dropdown.destroy();

            }

            if (textbox) {

                textbox.destroy();

            }

        },

        write: (args: { elementsElementvaluesstring[] | stringoperatorstring }) => {

            if (args.operator !== "startswith" ) {

                let dsstring[] = ['Cash''Debit Card''Credit Card''Net Banking''Wallet'];

                let dropDownObjDropDownList = new DropDownList({

                        dataSource: ds,

                        value: args.values as string,

                        change: (eany=> {

                            this.qryBldrObj.notifyChange(e.itemData.valuee.element);

                        }

                    });

                dropDownObj.appendTo('#' + args.elements.id);

            } else {

                let textboxInstance = new TextBox({

                    value: args.values as string,

                    change: (e=> {

                      this.qryBldrObj.notifyChange(e.valuee.event.target);

                    },

                });

                textboxInstance.appendTo('#' + args.elements.id);

            }

        }

    };


Query: Additionally, can I define my own SQL format for a particular operator? 

Using the change event and custom operator support of QueryBuilder , we can customize the data column like your requirement.


dateOperators = [

        { key: 'Next Month'value: 'nextmonth'sqlOperator: "=" },

        { key: 'Today'value: 'today'sqlOperator: "=" }

    ];

….

  change(args) {

        if ((args.type === "field" && args.value === "Date") || args.type === "operator" && (args.value === "today" || args.value === "nextmonth")) {

            var valElem = this.qryBldrObj.element.querySelector("#" + this.qryBldrObj.element.id + "_" + args.ruleID);

            (valElem.querySelector(".e-rule-value"as any).style.display = "none";

            args.type === "operator" ? this.qryBldrObj.getRule(args.ruleID).value = args.value : this.qryBldrObj.getRule(args.ruleID).value = "nextmonth";

        }

    }


Sample link: https://stackblitz.com/edit/angular-jmdz2h-rfot1a?file=src%2Fapp.component.ts


Get back to us, if you need any further assistance on this. 


Regards,

YuvanShankar A



KS KS August 9, 2023 03:32 PM UTC

Hello,

Thank you for your examples.

To expand on the first template, would it be possible to create an operator that displays a duration input that uses days, hours, and minutes, as shown below:

Image_9954_1691594974834


Also, when setting the value for the operator in the query, is it always in the format "Field operation value" (Date = 'nextmonth')? Or could it be set to something like an operator of Is Modified would result in the value being "Modified({field}, true)"?

Thank you,

KS



SD Saranya Dhayalan Syncfusion Team August 13, 2023 05:43 AM UTC

Hi KS


Query - would it be possible to create an operator that displays a duration input that uses days, hours, and minutes


Yes, it’s possible to create the input that uses days, hours, minutes by using the MaskedTextbox component. Please select the payment mode in the below sample


Sample link - https://stackblitz.com/edit/angular-cmaqzs-mbwanx?file=app.component.ts


Code snippet:

     paymentTemplate: TemplateColumn = {

         create: () => {

             return createElement('input', { attrs: { 'type': 'text' } });

         },

         destroy: (args: { elementId: string }) => {

             let masktxt: MaskedTextBox = (getComponent(document.getElementById(args.elementId), 'masktextbox') as MaskedTextBox);

             if (masktxt) {

                masktxt.destroy();

             }

         },

         write: (args: { elements: Element, values: string[] | string, operator: string }) => {

             let masktxtObj: MaskedTextBox = new MaskedTextBox({

              mask: '00-00-0000'

            });

                 masktxtObj.appendTo('#' + args.elements.id);

         }

     };


Screenshot:



Exporting allows you to save or maintain the created conditions through the Query Builder. You can export the defined conditions by the JSON and Sql. Please check the below documentation link


https://ej2.syncfusion.com/angular/documentation/query-builder/import-export#exporting-to-json


Regards,

Saranya D



KS KS August 25, 2023 12:50 PM UTC

Hello,

Thank you for the example.

In terms of the mask, is there a way to make sure that the separate sections of the text box don't go over a certain number? I.e. the hours are limited to 0-23, and the minutes are limited to 0-59.

I saw the examples where each digit can have its own regex, but I want to make sure the values stay within a given range.

Thank you,

KS



SD Saranya Dhayalan Syncfusion Team August 31, 2023 03:47 PM UTC

Hi KS,


In masked text box, we have maintained the separate mask for time format. Please check the below demo sample link

Sample link - https://ej2.syncfusion.com/angular/demos/#/material3/maskedtextbox/custom-mask


Documentation link - https://ej2.syncfusion.com/angular/documentation/maskedtextbox/mask-configuration#custom-mask-elements


Regards,

Saranya D



KS KS September 5, 2023 01:53 PM UTC

Hello,

When I use the template from your example a couple replies up, I am getting lines leftover when switching the operator for the field that uses the MaskTextbox template, which persist even when I switch the column for that condition. This is reproducible in your sample link as well.

This is what I see after switching operators multiple times:

Image_9131_1693921953398

It seems like the destroy is not removing the e-mask element that is outside the textbox element. Is there something that can be done for this?

Thank you,

KS



KV Keerthikaran Venkatachalam Syncfusion Team September 12, 2023 06:49 AM UTC

Hi KS,


We have checked the reported query, and we have fixed the issue at the sample level. Please refer to the below code snippet and sample.


destroy: (args: { elementId: string }) => {

             let masktxt: MaskedTextBox = (getComponent(document.getElementById(args.elementId), 'maskedtextbox') as MaskedTextBox);

             if (masktxt) {

                masktxt.destroy();

             }

         },


Sample Link: https://stackblitz.com/edit/angular-cmaqzs-3dmr8y?file=app.component.ts


Get back to us if you need any further assistance on this.


Loader.
Up arrow icon