Hi,
I am trying to add searching and filtering functionality in a server-side-pagination(fetching data from API using skip and take with total count) enabled grid.
But both searching and
filtering shows a spinner indefinitely and the grid hangs up.
Please note that I am using DataResult: { result: Object[], count: number } as my data source to enable
server-side-pagination. I have created a minimum demo to reproduce the issue. Please have a look at these links: https://stackblitz.com/edit/angular-jby2xg?file=app%2Fpagination-grid%2Fpagination-grid.component.ts, https://angular-jby2xg.stackblitz.io/
You can have a look at the following screenshots also.
Please let me know what can be done to make this work.
Thanks!
Hello,
Is there any update regarding this?
Thanks!
Hi Shakir,
Greetings from Syncfusion support
Before we start providing solution on your
query, We would like to share the behavior of custom-binding in the EJ2
Grid.
For every grid action(such
as Filter, Page, etc.,), we have
triggered the dataStateChange event
and, in that event arguments, we have sent 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.
dataStateChange: https://ej2.syncfusion.com/angular/documentation/api/grid/#datastatechange
[app.component.ts]
public dataStateChange(state) { // exectue your own service and perform the action with state queries and return the result and count data to the Grid this.getAsyncData(state); } }
getAsyncData(state) { if (state.where) { var gridqueries = this.grid.getDataModule().generateQuery().queries; var wherequery; for (var i = 0; i < gridqueries.length; i++) { if (gridqueries[i].fn == 'onWhere') { wherequery = gridqueries[i].e; } } new DataManager({ url: SERVICE_URI, adaptor: new ODataAdaptor() }) .executeQuery(new Query().where(wherequery).take(state.take).skip(state.skip)) .then((e: any) => { // bind the result and count object to the Grid this.grid.dataSource = { result: e.actual['d']['results'], count: parseInt(e.actual['d']['__count'], 10) }; return e; }); } else { new DataManager({ url: SERVICE_URI, adaptor: new ODataAdaptor() }) .executeQuery(new Query().take(state.take).skip(state.skip)) .then((e: any) => { // bind the result and count object to the Grid this.grid.dataSource = { result: e.actual['d']['results'], count: parseInt(e.actual['d']['__count'], 10) }; return e; }); } }
|
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.
[app.component.ts]
public ngOnInit(): void { // load initial data by executing your own service with page query and bind result and count value to the Grid new DataManager({ url: SERVICE_URI, adaptor: new ODataAdaptor() }) .executeQuery(new Query().take(12).skip(0).expand(['Employee']) ) .then((e: any) => { // bind the current page data to the grid dataSource with result and object format this.grid.dataSource = { result: e.actual['d']['results'], count: parseInt(e.actual['d']['__count'], 10) }; }); }
|
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_URI, adaptor: new ODataAdaptor() }).executeQuery( new Query().where( state.where[0].field, state.where[0].operator, state.where[0].value) ).then((e: any) => { // bind array of Objects state.dataSource(e.result); }); } else { new DataManager({ url: SERVICE_URI, adaptor: new ODataAdaptor() }) .executeQuery(new Query()) .then((e: any) => { // 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.
Sample: https://stackblitz.com/edit/angular-ws2fqv-a7nlyd?file=app.component.ts
Custom-binding: https://ej2.syncfusion.com/angular/documentation/grid/observables/
Execl Filtering in Custom-Binding: https://ej2.syncfusion.com/angular/documentation/grid/observables/#provide-excel-filter-data-source
Demo: https://ej2.syncfusion.com/angular/demos/#/material/grid/async-pipe
Note: In the given sample, we have used DataManager to execute our service. You can use your own logic to execute your service and bind the required data to the Grid.
Please get back to us if you need further assistance with this.
Regards,
Rajapandi R