searching with lazy loading data

I want to search into the grid with the built-in function search of the grid.

I lazy load the data inside the grid.

When i try to search, the spinning image show in the middle in the grid and nothing else happen.

here is my code :

      <ejs-grid #grid id='Grid' [dataSource]='data' [allowPaging]="true" [pageSettings]="pageSettings" showColumnMenu='true' [filterSettings]='filterOptions'

                [toolbar]='toolbarOptions' [editSettings]='editSettings' [allowFiltering]='true'

                [allowPdfExport]='true' (toolbarClick)='toolbarClick($event)' (actionBegin)='actionBegin($event)' (actionComplete)='actionComplete($event)'>

        <e-columns>

          <e-column field='id' headerText='id' width=0 [visible]='false'></e-column>

          <e-column field='idUser' headerText='idUser' width=0 [visible]='false'></e-column>

          <e-column field='date' headerText='Date' width=150 type='date' [format]='formatOptions'></e-column>

          <e-column field='description' headerText='description' width=150></e-column>

          <e-column field='type' headerText='typeId' width=0 [visible]='false'></e-column>

          <e-column field='typeName' headerText='type' width=90></e-column>

          <e-column field='name' headerText='Nom' width=90></e-column>

        </e-columns>

      </ejs-grid>


  loadData() {

    this.unsubscribe.push(this.logsService.getTotal().subscribe(tot => {

      this.total = tot;

      this.getData(1);

    }));

  }

  getData(currentPage: number) {

    this.unsubscribe.push(this.logsService.getAll((currentPage - 1) * this.grid.pageSettings.pageSize, this.grid.pageSettings.pageSize).subscribe(val => {

      this.spinnerService.hide();

      this.data = { result: val, count: this.total };

    }));

  }


ngOnInit() {

    this.formatOptions = { type: 'date', format: "dd-MM-yyyy hh:mm" };

    this.pageSettings = { pageSizes: [25, 40, 55, 70, 85], pageSize: 40 };

    this.loadData();

    this.editSettings = { allowDeleting: true, mode: 'Dialog', showDeleteConfirmDialog: true };

    this.toolbarOptions = ['PdfExport', 'Search', { text: 'Delete', tooltipText: 'Delete', prefixIcon: 'e-expand', id: 'delete' }];

    this.filterOptions = {

      type: 'Menu'

    };

  }


  async actionBegin(args) {

if (args.requestType === "searching") {

      const searchText: string = (document.getElementById('Grid_searchbar') as any).value;

      this.grid.search(searchText);

    }

  }


8 Replies

RS Rajapandiyan Settu Syncfusion Team September 24, 2021 10:54 AM UTC

Hi Frédéric,  
  
Thanks for contacting Syncfusion support. 

Before proceeding with query we need some clarification on your requirement. So kindly share the below details to provide a better solution. 

  1. Which type of service you are using in your project? (WebAPI service/ OData/ SQL/ Own Custom service)
  2. Are you want to perform all the Grid actions like Searching, Sorting, etc., from your custom service or in the client side?

Also, we would like to share the available Data-Binding support in the EJ2 Grid.  

  • Local data
  • Remote data
  • Custom binding
  • Ajax binding

** Local Data Binding **  

If you are using local data in your project, then you can bind array of object to the Grid. 


** Remote Data Binding ** 

If you are using  WebAPI service or OData or SQL or any DataTable  or List binding in your application, then we suggest you to use Syncfusion inbuilt adaptor of DataManager to perform action on your service. 
 
You can choose the adaptors based on your Database. For each Grid data-action like Filtering, Sorting, Paging, Scrolling etc., we send the correspond query to the server based on the data-adaptors. You can execute the queries with your data and return results with required format to the Grid. 
 
Refer to the below documentation which detailly illustrates available data adaptors in EJ2. 




** Custom Binding ** 

If you are using any custom service, we suggest you use custom-binding feature to bind the data to the Grid. We would like to share the behavior of custom-binding in EJ2 Grid. 

For every grid actions(such as FilterPage, etc.,), we have triggered the dataStateChange event and, in that event arguments we have send the corresponding action details(like skip, take, filter field, value, sort direction, etc.,) based on that, you can perform the action in your service and return the data as a result and count object.  

Note: ‘dataStateChange’ event is not triggered at the Grid initial render. If you are using a remote service, you need to call your remote service by manually with a pagination query (need to set skip value as 0 and take value based on your pageSize of pageSettings in Grid. If you are not defined pageSize in pageSettings, you need to send the default value 12 ) in ngOnInit. Please return the result like as “{result: […], count: …}” format to Grid. 

dataSourceChanged’ event is triggered when performing CRUD action in Grid. You can perform the CRUD action in your service using action details from this event and, you need to call the endEdit method to indicate the completion of save operation. 


** Ajax Binding ** 

By using ajax binding, you can get all the data from service and bind the result data (array of objects) to the grid instances. It works as local data. i.e. All the Grid data actions like Paging, Sorting, Filtering, etc., are performed only at client side. 
 

Kindly choose the data-binding based on your service. Please let us know if you have any concerns. 
 
Regards, 
Rajapandiyan S 



DO Denis Ortega July 26, 2022 06:01 PM UTC

Hello there,

I have a similar issue with my grid. I am doing custom binding by initially returning the datasource  as “{result: […], count: …}”.​ I would like to filter and sort locally, and on the dataStateChange​ event I am getting the paginated data with the arguments passed. 

The issue I have is with the Excel filters and the programmatic grid search functionality this.grid.search(string). ​When searching with this method, the grid doesn't stop loading and is stuck.


When using the Excel filter it has the same issue, until I passed a datasource in the filterchoicerequest event. However, the datasource I passed back was just the same grid datasource because I want to filter locally. This stopped the loading but now it shows no values in the excel filter.




this.templates is my datasource with the correct format with result and count fields.

If you could help resolve this I would appreciate it.

Thanks



RR Rajapandi Ravi Syncfusion Team July 27, 2022 01:23 PM UTC

Hi Denis,


Thanks for your update


Currently we are validating your query with your shared information, and we will update you the details on or before 29th July 2022. Until then we appreciate your patience.


Regards,

Rajapandi R



RR Rajapandi Ravi Syncfusion Team July 29, 2022 02:46 PM UTC

Hi Denis,


Thanks for your patience


We have checked your shared information and we could see that you are facing the spinner problem while searching. When you perform the search action, the dataStateChange event will be triggered and, in that event, you need to execute your service with search query and should return the data to resolve the spinner problem.


 

  dataStateChange(state: DataStateChangeEventArgs): void {

      const take = state.take;

      const skip = state.skip;

      if (state.search){

        this.dataService.search(state.search[0].key, take, skip);

     } else {

        this.dataService.search(‘’, take, skip);

     }

  }

 


And also, in your query we could see that while opening the filer dialog you are facing no matches found from validating your shared information, we found that you are binding this.templates as result and count format. In filter request you need to bind the datasource as array of objects format. Please refer the below code example for more information.


 

  dataStateChange(state: DataStateChangeEventArgs): void {

 

      if (state.action && (state.action.requestType == 'filterchoicerequest' ||

        state.action.requestType == 'filtersearchbegin' ||

        state.action.requestType == 'stringfilterrequest')) {

 

          args.dataSource(this.templates.result) // bind array of Objects 

        }

 


Regards,

Rajapandi R



DO Denis Ortega August 3, 2022 06:08 PM UTC

Thank you Rajapandi,

I see the events that you mentioned. However, is it possible to use custom binding while doing client-side filtering and searching?

I was hoping I can use the grid's built in search and filtering functionality, while using my service for pagination only.



RR Rajapandi Ravi Syncfusion Team August 4, 2022 01:05 PM UTC

Hi Denis,


Thanks for your update


By default, when we are using custom binding in our Application, we can handle all actions like Paging, Filtering, Sorting in our service by our own. We cannot perform the specific actions in the client-side when we are using custom binding. It was the default behavior.


However, if you need all the actions to be handled by the Grid itself in the client-side, then we suggest you to directly set the JSON data to the Grid’s dataSource property. And if you are using this local data binding and need to access an event on data change, then you can use the dataBound event which will be triggered on each data change.


By using ajax binding, you can get all the data from service and bind the result data (array of objects) to the grid instances. It works as local data. i.e., All the Grid data actions like Paging, Sorting, Filtering, etc., are performed only at client side.


Documentation: https://ej2.syncfusion.com/angular/documentation/grid/data-binding/data-binding/#binding-with-ajax


API: https://ej2.syncfusion.com/angular/documentation/api/grid/#databound


Regards,

Rajapandi R



DO Denis Ortega August 4, 2022 06:23 PM UTC

Hi Rajapandi,

Thank you I understand, I'll be working on having the filtering and search through the API. I think I have one more question.

Is there documentation on what the `filterchoicerequest` dataSource method requires?

(args.action.requestType === 'filterchoicerequest' ||
args.action.requestType === 'filtersearchbegin' ||
args.action.requestType == 'stringfilterrequest')
args.dataSource(filters);


I have preset filter values for each column that I aggregated into an array. For example, for Column1 I have A, B. And for column2 I have D, E.

The array of objects I send to .dataSource() is [{ column1: 'A' }, { column1: 'B'}, {column2: 'C'}, {column2: 'D'}].

This gives me the correct options in each column filter. However once I select a filter option on one column, all the filter options disappear from the rest of the columns, although I am passing the same data to the .dataSource() everytime. Once I clear the filter on the column, the options reappear on all the columns.


If you could clear this up, I'd appreciate it. Thanks!



RR Rajapandi Ravi Syncfusion Team August 5, 2022 12:01 PM UTC

Hi Denis,

When you open the filter dialog, the dataStateChange event with requestType (‘filterchoicerequest/stingfilterrequest’) will be triggered. In that event, you need to execute your service and bind the array of object to the state.dataSource method. 

 When you search the value in the filter dialog, the dataStateChange event with requestType (‘filtersearchbegin’) will be triggered. In that event, you need to filter the value from your service based on the event argument and bind the array of objects to the state.dataSource method. 

 [app.component.ts] 

  public dataStateChange(state) { 

    if ( 

      state.action && 

      (state.action.requestType == 'filterchoicerequest' || 

        state.action.requestType == 'filtersearchbegin' || 

        state.action.requestType == 'stringfilterrequest'

    ) { 

   // below code will be executed when open the filter dialog and perform search in the filter dialog 

      state.skip = 0

      // execute your service and bind the data for other columns 

      if (state.where) { 

        new DataManager({ url: SERVICE_URIadaptor: new ODataAdaptor() }).executeQuery

            new Query().where( state.where[0].field, state.where[0].operator, state.where[0].value

          ).then((eany=> { 

            // bind array of Objects 

            state.dataSource(e.result); 

          }); 

      } else { 

        new DataManager({ url: SERVICE_URIadaptor: new ODataAdaptor() }) 

          .executeQuery(new Query()) 

          .then((eany=> { 

            // bind array of Objects 

            state.dataSource(e.result); 

          }); 

      } 

    } else { 

      // exectue your own service and perform the action with state queries and return the result and count data to the Grid 

      this.getAsyncData(state); 

    } 

  } 

Find the below sample and documentation for your reference. 

Documentation: https://ej2.syncfusion.com/angular/documentation/grid/observables/#provide-excel-filter-data-source

Sample: https://stackblitz.com/edit/angular-ws2fqv-qdjkkq?file=app.component.html,app.component.ts


Regards,

Rajapandi R


Loader.
Up arrow icon