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
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.
|
paymentTemplate: TemplateColumn = { create: () => { return createElement('input', { attrs: { 'type': 'text' } }); }, destroy: (args: { elementId: string }) => { let dropdown: DropDownList = (getComponent(document.getElementById(args.elementId), 'dropdownlist') as DropDownList); let textbox: TextBox = (getComponent(document.getElementById(args.elementId), 'textbox') as TextBox); if (dropdown) { dropdown.destroy(); } if (textbox) { textbox.destroy(); } }, write: (args: { elements: Element, values: string[] | string, operator: string }) => { if (args.operator !== "startswith" ) { let ds: string[] = ['Cash', 'Debit Card', 'Credit Card', 'Net Banking', 'Wallet']; let dropDownObj: DropDownList = new DropDownList({ dataSource: ds, value: args.values as string, change: (e: any) => { this.qryBldrObj.notifyChange(e.itemData.value, e.element); } }); dropDownObj.appendTo('#' + args.elements.id); } else { let textboxInstance = new TextBox({ value: args.values as string, change: (e) => { this.qryBldrObj.notifyChange(e.value, e.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
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:
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
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
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
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
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:
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
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.