Angular Combo Box with WebMethodAdoptor

Dear Team,

I have implemented WebMethodAdoptor in Combo box but I am facing some problems.

1. Row Template is going blank when scrolling, selecting and re opening the popup
2. How to Fetch Current Total Record Count in Combo Box
3. How to Clear Data of Combo Box from External Button Using Data Manager
4. How to Clear Data of Combo Box from Clear Button
5. How to Repopulate Fresh Data on Dropdown Icon Click
6. How to identity user filtered inside processQuery

HTML

<ejs-combobox #select [attr.id]='control.FieldName' [dataSource]='data' [query]='query'
                sortOrder='Ascending'
                [fields]='{text:control.AutoCompleteModel.TextColumn, value: control.AutoCompleteModel.ValueColumn}'
                cssClass="e-outline" [showClearButton]="true"
                formControlName="{{index!=undefined? control?.FieldName+index: control?.FieldName}}" autocomplete="off"
                [ngClass]="{ 'is-invalid':  control.form.submitted, disabled: control?.IsReadOnly }"
                [enabled]="!control?.IsReadOnly" [noRecordsTemplate]="noRecordsTemplate"
                [popupWidth]="popupWidth" [popupHeight]='popupHeight' [placeholder]="control?.PlaceHolder"
                [itemTemplate]='itemTemplate' (open)="onPopupOpen($event, select)"
                (focus)="onFocus($event, select)"
                (filtering)="onFiltering($event, select)"
                (blur)="onBlur($event, select, control)"
                (change)="onChange($event, select, control)"
                [allowFiltering]='true'
                (keydown)="onKeyDown($event, select)"
                (select)="onSelect($event, control, select)" 
                >
                <ng-template #itemTemplate="" let-data="">
                    <div class="sorder-dropdown autocomplete-online-box {{page.PageCode}}"
                        *ngIf="control.AutoCompleteModel.Columns!=null">
                        <div class="row ml-0 mr-0">
                            <div *ngFor="let d of control.AutoCompleteModel.Columns"
                                class="width{{d.Width}} overflow-hidden autobox pl-1 pr-1" style="overflow: hidden;">
                                {{data[d.FieldName]}}
                            div>
                        div>
                    div>
                    <div class="dropdown-rowtemplate column-text-indent"
                        *ngIf="control.AutoCompleteModel.Columns==null">
                        {{data[control.AutoCompleteModel.TextColumn]}}
                    div>
                ng-template>
                <ng-template #headerTemplate="" let-data="">
                    <div class="sorder-dropdown" *ngIf="control.AutoCompleteModel.Columns!=null">
                        <div class="pl-1 dropdown-bg-main" style="padding-right: 19px;">
                            <div class="row ml-0 mr-0 autocomplete-online-box">
                                <div *ngFor="let d of control.AutoCompleteModel.Columns"
                                    class="width{{d.Width}} columnfirst pl-0 pr-1 dropdown-bg">{{d['HeaderText']}}div>
                            div>
                        div>
                    div>
                ng-template>
            ejs-combobox>


Setting Up Data Manager on OnInit

//sample url:
        //http://localhost:1042//querysf/AC_ITEM?PAGE_CODE=Sale_Entry&SEARCH_STRING=ab&COUNT=0&TOP_RECORD=15&SELECTED_ARR=&FIELD_NAME=FINISH%20GOODS&STORE_ID=1&DOC_DATE=2021/03/08&AC_TYPE=TAXABLE&DIVISION_ID=&TOP_RECORDS=15&GIFT_TYPE=&PACK=&TAXABLE_EXEMPT=A

        let spName = this.control && this.control.AutoCompleteModel && this.control.AutoCompleteModel.SpName || '';
        const queryStringUrl = this.autoCompleteService.generateQueryStringForDataManager({
            control: this.control,
            page: this.page,
            routeData: this.routeData,
            currentCount: 0,
            searchText: '',
            selectedArr: [],
            topRecord: 15,
            spName: spName
        });
        let sfQueryAdptSFQueryQpiAdaptor = new SFQueryQpiAdaptor();
        sfQueryAdpt.processQuery = this.processQuery.bind(this);

        this.data = new DataManager({
            url: queryStringUrl,
            adaptor: sfQueryAdpt,
            crossDomain: true,
        });



Custom Adoptor: 

class SFQueryQpiAdaptor extends WebMethodAdaptor {
    public beforeSend(dmDataManagerrequestXMLHttpRequest): void {
        const d = sessionStorage.getItem('data');
        if (d) {
            const jd = JSON.parse(d);
            if (jd) {
                const t = jd['token']
                request.setRequestHeader('Authorization''Bearer ' + t);
            }
        }
    }
}


Process Query: 

processQuery(dmDataManagerqueryQueryhierarchyFilters?: Object[]) {
        if (this.validateDependOnControl(true)) {
            const urlArr = dm.dataSource.url.split('?');
            let searchText = '';
            let currentCount = 0;
            if (this.selectObj) {
                if (this.selectObj['listData']) {
                    currentCount = this.selectObj['listData'].length as number;
                }
                if (this.selectObj['typedString']) {
                    searchText = this.selectObj['typedString'as string;
                }
            }
            if (this.isFiltering) {
                this.isFiltering = false;
                currentCount = 0;
            }
            let spName = this.control && this.control.AutoCompleteModel && this.control.AutoCompleteModel.SpName || '';
            const queryStringUrl = this.autoCompleteService.generateQueryStringForDataManager({
                control: this.control,
                page: this.page,
                routeData: this.routeData,
                currentCount: currentCount,
                searchText: searchText,
                selectedArr: [],
                topRecord: 15,
                spName: spName
            });

            let req: { [keystring]: Object } = {};
            return {
                type: 'GET',
                url: queryStringUrl,
                data: JSON.stringify(req),
            };
        } else {
            return {
                type: 'GET',
                url: '',
                data: JSON.stringify({}),
            }
        }
    }

Bind Scroll Event: 



25 Replies 1 reply marked as answer

NG Nagendra Gupta March 10, 2021 02:21 PM UTC

Please check stackbliz url:

https://stackblitz.com/edit/angular-sf-dropdown?file=app.component.ts


SN Sevvandhi Nagulan Syncfusion Team March 11, 2021 10:39 AM UTC

Hi Nagendra, 



Greetings from Syncfusion support. 


Thanks for the sample for the reported requirements. We checked the sample. Since you provided the localhost url in the queryStringUrl, we were unable to see the reported issues in the shared sample. So, for queries 2 to 5, we prepared a sample with the mentioned requirements and attached it below. Meanwhile, providing a runnable sample would be helpful in validating the issues mentioned in queries 1 and 6 


Query 2: How to Fetch Current Total Record Count in Combo Box 


In the action complete event arguments, we can get the current record count. Please refer the below code. 


    OnActionComplete(args) 
    { 
        console.log(args.result); 
    } 


Query 3: How to Clear Data of Combo Box from External Button Using Data Manager 


By setting the data source property to null, you can clear the current data source value .Please refer the below code. 


  OnClick(e) 
    { 
        this.comboBoj.dataSource = null; 
    } 


Query 4: How to Clear Data of Combo Box from Clear Button 


When the value is cleared with the clear button, the change event is triggered. You can clear the data source by using the code in Query 3. 


Query 5: How to Repopulate Fresh Data on Dropdown Icon Click 


The open event is triggered when the dropdown icon is pressed. We can modify the data source by explicitly assigning new data to the data source property. 


   onOpen(args) 
    { 
        this.comboBoj.dataSource = this.data1; 
    } 
 
 
Please find the sample link. 
 
 


Please check above suggestions and get back to us if you need further assistance. 


Regards, 
Sevvandhi N 



NG Nagendra Gupta March 15, 2021 10:21 AM UTC

Hello Team,

Thank you for the example but unfortunately, your provided example is not using WebMethodApi. Please provide Example with WebMethodApi and MultiColumn with Template


SN Sevvandhi Nagulan Syncfusion Team March 16, 2021 02:16 PM UTC


Hi Nagendra, 


We are currently validating the reported issue at our end. We will update further details on 18th March,2021. We appreciate your patience until then. 


Regards, 
Sevvandhi N 



NG Nagendra Gupta March 23, 2021 02:10 PM UTC

Hello Team,

Still Waiting for your response. I need this on an urgent basis, please provide me the sample example ASAP


SN Sevvandhi Nagulan Syncfusion Team March 23, 2021 04:22 PM UTC

Hi Nagendra, 


Sorry for the inconvenience caused. 


We checked your query. We prepared the sample with custom adaptor which overrides the WebMethodAdaptor and attached it below. We suggest that you to assign the empty array to data source property for clearing the data of ComboBox component. Kindly refer the below code. 

[app.component.ts] 

  OnClick(e) 
        { 
            this.comboBoj.value = null; 
            this.comboBoj.dataSource = []; 
            this.comboBoj.dataBind(); 
        } 


[HomeController.cs] 

public object GetData() 
        { 
 
            List<Countries> Data = new Countries().CountriesList(); 
            dynamic count = Data.Count; 
            return new 
            { 
                result = Data, 
                count = count 
            }; 
 
        } 

Please find the client and server sample below. 






Please check the above sample and get back to us if you need further assistance. 


Regards, 
Sevvandhi N 



Marked as answer

NG Nagendra Gupta March 25, 2021 09:17 AM UTC

Hi Sevvandhi,


Thanks for your update, Your given example working fine. But still, I want to implement multiple things.

Please provide me an example with the following points.

1. Implemented Row Template with Multiple Columns (As Mention in my Code Example Provided)
2. Implemented with WebMethodAdoptor 
3. API will return the next 15 Record after scroll (Request to API for next 15 records in scroll event)
4. Fetch New 15 Record After Filtering of Any Text
5. Prompt Message "Poor Connection" if API does not return any data within 5 seconds, 
7. Show Selected Record with All Record In Popup (with Blue Color) (After Selecting any record will show only a single record in the popup)

Please provide the same in the working code example





SN Sevvandhi Nagulan Syncfusion Team March 29, 2021 04:28 AM UTC

Hi Nagendra, 


We checked your reported queries.  


1. Implemented Row Template with Multiple Columns (As Mention in my Code Example Provided) 
2. Implemented with WebMethodAdoptor  
3. API will return the next 15 Record after scroll (Request to API for next 15 records in scroll event) 
4. Fetch New 15 Record After Filtering of Any Text 


We prepared the sample for above all the queries and attached it below. Please find the sample below. 



Back end sample link: https://www.syncfusion.com/downloads/support/directtrac/general/ze/WebMethodAdaptor-765485993


Query 5: Prompt Message "Poor Connection" if API does not return any data within 5 seconds. 


Using the actionBegin and actionComplete events, we can calculate the API result returning time. Please see the code below. 

OnActionBegin(e){ 
    this.startTime = new Date().getTime(); 
} 
OnActionComplete(args) { 
    this.endTime = new Date().getTime(); 
    console.log(args.result); 
    console.log("API returing time:" + ((this.endTime - this.startTime)/1000)) 
} 


Query 6:  Show Selected Record with All Record In Popup (with Blue Color) (After Selecting any record will show only a single record in the popup) 

if we select a value, the combobox component will show all of the records in the popup by default. Please refer the below screenshot. 

 

Regards, 
Sevvandhi N 




NG Nagendra Gupta April 8, 2021 01:50 PM UTC

Hi


Result Data Available but when executeLocal will blank all the data










CCombobox row template goes blank after scroll event









SN Sevvandhi Nagulan Syncfusion Team April 9, 2021 10:31 AM UTC

Hi Nagendra, 


We checked the provided screenshot. We were unable to replicate the reported issue at our end. We request that you provide a simple reproducing sample or modify the previously attached sample so that we can investigate the issue further and determine the cause of the reported issue. 


When scrolling, we can get the necessary data and the data displayed in the control. Kindly refer the below screenshot. 

 


Please find the sample below. 




Regards, 
Sevvandhi N 



NG Nagendra Gupta April 29, 2021 04:16 PM UTC

Hello Team

Template blank problem has been resolved. When I updated the angular version 8 to 9.
In your given example data come on page load. But my requirement is that data will come from API when I click on comboxbox caret sign instead of page load


SN Sevvandhi Nagulan Syncfusion Team April 30, 2021 08:48 AM UTC

Hi Nagendra, 


Thanks for your update. 


We checked your query of “Updating the datasource when the icon clicked”. ” Using the beforeOpen event, you can update the data source whenever the icon is pressed. Before the popup opens, the beforeOpen event will be triggered. Kindly refer the following code. 


    onbeforeOpen(args){ 
            this.comboBoj.dataSource=new DataManager({ 
            url: https://localhost:44358/Home/GetData, 
            adaptor: new CustomAdaptor(), 
            crossDomain: true 
          }); 
     } 



Please find the sample below. 




Kindly get back to us for further assistance. 


Regards, 
Sevvandhi N 



NG Nagendra Gupta May 3, 2021 10:23 AM UTC

Hello Team

If possible please give me solution for reactive form with Web Adaptor in combobox. Because I want to show text in combobox from ID which I will get from server.



SN Sevvandhi Nagulan Syncfusion Team May 4, 2021 08:20 AM UTC

Hi Nagendra, 


We checked your query. We modified the previously given sample for reactive form with Web Adaptor in ComboBox. Also dynamically updated the form value after the data source was updated to the component. Kindly refer the following code. 
 
[HTML] 

<div class="control-section"> 
  <div style="margin: 0px auto; width:250px; padding-top: 40px;"> 
  <form [formGroup]="skillForm" novalidate id="formId"> 
    <ejs-combobox #sample id='country' formControlName="combo"  [dataSource]='data' [fields]='fields' [popupHeight]='height' 
      [placeholder]='watermark' (open)="onOpen($event)" (beforeOpen)="onbeforeOpen($event)" [query]='query' 
      (actionBegin)="OnActionBegin($event)" (actionComplete)="OnActionComplete($event)" (change)="onChange($event)"> 
      <ng-template #itemTemplate let-data> 
        <div> 
          <span class="name"> {{data.Name}} </span> 
          <span class="code"> {{data.Code}} </span> 
        </div> 
      </ng-template> 
    </ejs-combobox> 
    <input type="button" value="ClearDataSource" (click)="OnClick($event)"> 
      </form> 
  </div> 
</div> 

 

[TS] 

createForm(): void { 
    this.skillForm = this.fb.group({ 
        combo: ['', Validators.required] 
    }); 
} 
onbeforeOpen(args){ 
  this.comboBoj.dataSource=new DataManager({ 
  adaptor: new CustomAdaptor(), 
  crossDomain: true 
}); 
  setTimeout(()=>{ 
    this.skillForm.setValue({ 
      combo:'1' 
    }) 
  },100) 
} 

 


Please find the modified sample below. 





Kindly get back to us for further assistance. 


Regards, 
Sevvandhi N 



NG Nagendra Gupta May 4, 2021 12:28 PM UTC

Hello Team,

Thanks for your reply.


Whenever I Type or click on dropdown icon request goes to api and new data bind to dropdown with the help of datamanager, but my requirement is i want to validate some other control before sending request to api for new data.

Imagine I have 2 controls on page one is Party Name and second is City, city dropdown populate their data only when party name is blank other wise show msg to user please enter party name first.


SN Sevvandhi Nagulan Syncfusion Team May 5, 2021 12:36 PM UTC

Hi Nagendra, 


We checked your query. Before the request is sent to the server, the actionBegin event of the ComboBox component will be triggered. So you can change the query in the action begin event depending on the condition, and you can also limit the data loading with the take property. We can show the user the personalised message by using the NoRecordsTemplate. We created a sample based on the requirement and have attached it below for your reference. Kindly refer the following code. 

[HTML] 

<ejs-combobox #city id='country1' formControlName="city" [dataSource]='data' [fields]='fields' [popupHeight]='height' 
              [placeholder]='watermark' (beforeOpen)="onbeforeOpen1($event)" [query]='query1' (actionBegin)="OnActionBegin($event)"> 
    <ng-template #itemTemplate let-data> 
        <div> 
            <span class="name"> {{data.Name}} </span> 
            <span class="code"> {{data.Code}} </span> 
        </div> 
    </ng-template> 
    <ng-template #noRecordsTemplate> 
        <span class='norecord'> Please enter party name first</span> 
    </ng-template> 
</ejs-combobox> 



[TS] 

    OnActionBegin(e) 
        { 
            if (this.partyObj.value) 
            { 
                e.query = new Query().take(0) 
            } 
            else if (!this.partyObj.value) 
            { 
                e.cancel = false; 
            } 
        } 


Please find the sample below. 




Kindly get back to us for further assistance. 


Regards, 
Sevvandhi N 



NG Nagendra Gupta May 7, 2021 05:36 PM UTC

Hello Team,

Thanks for your reply and solution. Your given solution work perfectly but not able to fulfill my all of the requirements.

Since 1 Year I am unable to create satisfactory module with the help of Syncfusion Combo Box which I have seen in Microsoft DevOps Azure Application. I am trying to create same combo box.

1. A Combo box must be fetch data from API only in case of user touch it. Either by typing or by mouse click

2. Combo box also will get predefined single record in oninit, that should be bind and selected. Required when user is editing any master record. Does not want to send any request to API. API will provide Single - single record at the time of page load for all 10 combo box implemented in particular page. Programmatically bind single record (JSON data) without API call

3. When User Click on Cross Button (X), Combo box will clear the selected record and send request to API for fresh new data.

4. Every time When User touch the combo box will generate the new URL with latest query string parameters. All Parameters will fetch selected id from other combo box (Cascading Style).

5.There should be multi column template used in the combo box

6. There should be textbox on each column, so that use can also search by other columns, like in grid

7. Popup should not close when user click in column text box

8. User can able to resize row template column like wise in grid.

9. Prompt Message "Poor Connection" if API does not return any data within 5 seconds,

10. Show Selected Record with All Record In Popup (with Blue Color) (After Selecting any record will show only a single record in the popup)

11. API will return the next 15 Record after scroll (Request to API for next 15 records in scroll event) and append to the existing data

12. Implemented with WebMethodAdoptor

13. Fetch New Fresh Record from API Call After Filtering of Any Text

14. Reactive Form should be implemented because, out the combo box. There is standard service in my application that will patch value to form with the help of form.patchValue

15. When we are clearing combobox through patch value than blank row is adding in combobox



SN Sevvandhi Nagulan Syncfusion Team May 10, 2021 03:05 PM UTC

Hi Nagendra, 


We checked your query.  Except for the second line in the fourth query, we addressed the first 5 query in the sample below. Please check the sample below and confirm that it meets the requirements for the first 5 query. Please let us know if there are any changes. Based on the information provided, we will proceed further and  address the remaining queries in the same sample. 


Note: You can see a list of requests sent to the server and returned data from the server in the corresponding request's response in the network tab of the browser window. 






Kindly get back to us for further assistance. 


Regards, 
Sevvandhi N 



NG Nagendra Gupta May 24, 2021 04:02 PM UTC

Hi Team,

We have achieve almost everything. Thanks for your updates and responses.

Just 2 more points 

1. I have a JSon List at the time of page load , I want to set selected value and data from offline json on init method and rest of the time combobox will use the query adaoptor.
2. Which is the best method to validate any other control , onbeforepop or focus. If validation failed i need to show any custom alert message to user and no request will sent to api and popup will not open. Also focus will remain on same control. 

Thanks


NG Nagendra Gupta May 25, 2021 06:50 AM UTC

Hello Team,

Unfortunately I'm not able to implement my all points together,  all point are conflicting with each other.

Like if I bind dataSource in html with Josn object then query manager will not work;. Please implement all 15 point sent to you in single example.

I have tired many things in last 1 year but unable to execute all my 15 points.


SN Sevvandhi Nagulan Syncfusion Team May 25, 2021 12:07 PM UTC

Hi Nagendra, 


We are currently preparing the sample for the requested requirements. We will update further details on 28th of May,2021. We appreciate your patience until then. 


Regards, 
Sevvandhi N 



NG Nagendra Gupta May 28, 2021 01:32 PM UTC

Thanks for your reply. Waiting for you example link


SN Sevvandhi Nagulan Syncfusion Team May 31, 2021 11:07 AM UTC

Hi Nagendra, 


Thanks for your patience. 


Please find the consolidated details below. 


6. There should be textbox on each column, so that use can also search by other columns, like in grid 

7. Popup should not close when user click in column text box 

8. User can able to resize row template column like wise in grid. 

Answer:  

We already considered this requirement as feature and it will be included in any one of the upcoming releases. We appreciate your patience until then. Please find the feedback link below. 




1. A Combo box must be fetch data from API only in case of user touch it. Either by typing or by mouse click 

2. Combo box also will get predefined single record in oninit, that should be bind and selected. Required when user is editing any master record. Does not want to send any request to API. API will provide Single - single record at the time of page load for all 10 combo box implemented in particular page. Programmatically bind single record (JSON data) without API call 

3. When User Click on Cross Button (X), Combo box will clear the selected record and send request to API for fresh new data. 

4. Every time When User touch the combo box will generate the new URL with latest query string parameters. All Parameters will fetch selected id from other combo box (Cascading Style). 

5.There should be multi column template used in the combo box 

9. Prompt Message "Poor Connection" if API does not return any data within 5 seconds, 

12. Implemented with WebMethodAdoptor 

14. Reactive Form should be implemented because, out the combo box. There is standard service in my application that will patch value to form with the help of form.patchValue 

15. When we are clearing combobox through patch value than blank row is adding in combobox 

Answer:  

We addressed all the above queries in the below sample.  Please find the sample eblow. 






We will provide the solution for the remaining queries 10,11 and 13 in the same sample and update on June 2nd,2021. We appreciate your patience until then. 


Regards, 
Sevvandhi N 



NG Nagendra Gupta June 1, 2021 07:44 AM UTC

Hi Sevvandhi,

Thanks for your update and for example link.


1. If api is not running (or no internet) poor connection  msg comes two times.
2. No Offline Json Data bind at the time of page load. 
               [{COUNTRY_ID:1, COUNTRY_NAME:INDIA}]
               SET VALUE TO 1
3. Where we are putting other control selected value to filter data
     Like: 2 combo box should show only state related to country selected


SN Sevvandhi Nagulan Syncfusion Team June 2, 2021 12:54 PM UTC


Hi Nagendra, 
 
 
We addressed all the query in the below sample.  Please refer the below sample link. 
 
 
 
 
Also, for the query “No Offline Json Data bind at the time of page load”. if the data has not loaded and tried to set the value property, then the value will be considered as custom value in the combobox component. So corresponding text will not be updated for the id. The raw Id will be added to the component. So, when the data is available, the corresponding text will be updated. This is default behavior of component.  
 
 
Regards, 
Sevvandhi N 


Loader.
Up arrow icon