App.component.ts
export class AppComponent {
public data: DataManager;
public initialPage: Object;
ngOnInit(): void {
this.data = new DataManager({
url: 'https://js.syncfusion.com/demos/ejServices/Wcf/Northwind.svc/Orders',
adaptor: new ODataAdaptor(),
crossDomain: true
});
}
}
|
how we need to call a api instead of url to get the data from the server
Hi Rajapandi Ravi,
Thank you for your reply.
How do we get, on scroll event in infinite scrolling. I want to fetch the data from custom service on end of every scroll.
[App.component.html]
<div class="control-section">
<ejs-grid [dataSource]='data | async' #grid [height]=400 [enableInfiniteScrolling]='true' [pageSettings]='pageOptions' (dataStateChange)= 'dataStateChange($event)'>
<e-columns>
<e-column field= "OrderID" headerText="Order ID" width="130" ></e-column>
<e-column field= "CustomerID" headerText="Customer Name" width="150"></e-column>
<e-column field= "ShipName" headerText="Ship Name" width="200"></e-column>
<e-column field= "ShipCity" headerText="Ship City" width="150"></e-column>
</e-columns>
</ejs-grid>
</div> |
[App.component.ts]
import { Component, OnInit, Inject,ViewChild } from '@angular/core';
import { Observable } from 'rxjs';
import { OrdersService } from './order.service';
import { DataStateChangeEventArgs,PdfExportProperties,ExcelExportProperties,ToolbarItems,IFilter,Filter } from '@syncfusion/ej2-grids';
import { GridComponent } from '@syncfusion/ej2-angular-grids';
import { ClickEventArgs } from '@syncfusion/ej2-navigations'
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
providers: [OrdersService],
})
export class AppComponent {
public data: Observable<DataStateChangeEventArgs>;
public pageOptions: Object;
public count = 0;
public printData: Object[];
@ViewChild('grid', {static: true})
public grid: GridComponent;
public state: DataStateChangeEventArgs;
public toolbarOptions: ToolbarItems[];
constructor( public service: OrdersService) {
this.data = service;
}
public dataStateChange(state: DataStateChangeEventArgs): void {
// for each time the scroller reaches the end this event will be invoked
with the parameters of skip and take
// here instead using the service you can apply the data and return as result and count here
this.service.execute(state);
}
public ngOnInit(): void {
this.pageOptions = { pageSize: 50 };
// for initial rendering define the records to binding the Grid
let state = { skip: 0, take: 50 };
this.service.execute(state);
}
}
|
[OrderService.ts]
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { DataStateChangeEventArgs, Sorts, DataResult } from '@syncfusion/ej2-angular-grids'
import { Observable } from 'rxjs';
import { Subject } from 'rxjs';
import { map } from 'rxjs/operators';
@Injectable()
export class OrdersService extends Subject<DataStateChangeEventArgs> {
private BASE_URL = 'https://js.syncfusion.com/demos/ejServices/Wcf/Northwind.svc/Orders';
constructor(private http: Http) {
super();
}
public execute(state: any): void {
this.getData(state).subscribe(x => super.next(x));
}
public getData(state: DataStateChangeEventArgs): Observable<DataStateChangeEventArgs> {
console.log(state.action)
const pageQuery = `$skip=${state.skip}&$top=${state.take}`;
let sortQuery: string = '';
if ((state.sorted || []).length) {
sortQuery = `&$orderby=` + state.sorted.map((obj: Sorts) => {
return obj.direction === 'descending' ? `${obj.name} desc` : obj.name;
}).reverse().join(',');
}
return this.http
.get(`${this.BASE_URL}?${pageQuery}${sortQuery}&$inlinecount=allpages&$format=json`)
.pipe(map((response: any) => response.json()))
.pipe(map((response: any) => (<DataResult>{
// here we are returning the 50 records to be displayed in the Grid
result: response['d']['results'],
count: parseInt(response['d']['__count'], 10)
// here we are returning the data as Object of result and count
})))
.pipe((data: any) => data);
}
} |
Hello Rajapandi Ravi,
I have implemented the above example but I have to add filtering functionality with the type 'Menu' and filter 'CheckBox' but after clicking on the filter icon it's just showing loader it's not able to get all the values for the filtering. Can't it just show all the loaded values for that column?
Here is the Url of implementation: https://stackblitz.com/edit/angular-infine-scroll-custombinding-r8yc4e?file=app.component.html
Thanks in advance.
Regards,
Ganesh Harihar
Hi Ganesh,
Thanks for the update.
Currently, we are validating your query with your shared information, and we will update you the details on or before 20th June 2022. Until then we appreciate your patience.
Rajapandi R
Hi Ganesh,
Thanks for your patience
In custom binding when the filter/sort/page actions are performed in the Grid, the action details will be returned in the dataStateChange event as shown in the below image(shows filter action details),
From this event you need to form the filter/page/sort queries in the format as required by your server, process the action and bind the result to the Grid dataSource as an object of ‘result’ and ‘count’.
More details on custom binding can be checked in the below documentation link,
Custom binding: https://ej2.syncfusion.com/angular/documentation/grid/observables/#handling-grid-actions
Regards,
Rajapandi R
Hello Rajapandi Ravi,
Thank you for the response but if you have noticed I did the same thing in sample prepared after clicking on the filter icon it throws an error. Following is the sample URL if possible edit that sample and make filters work on 'Customer Name' column.
https://stackblitz.com/edit/angular-infine-scroll-custombinding-r8yc4e?file=app.component.html
Attached screenshot of the error also.
Regards,
Ganesh Harihar
Hi Ganesh,
Thanks for the update.
We have
checked your query and we could see that you like to use the Excel Filter in
the Custom binding. 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-mxcxjs?file=app.component.html,app.component.ts
Custom-Binding: https://ej2.syncfusion.com/angular/documentation/grid/observables/
Excel Filtering in Custom-Binding: https://ej2.syncfusion.com/angular/documentation/grid/observables/#provide-excel-filter-data-source
Regards,
Rajapandi R
Hello Rajapandi Ravi,
Thanks for the guidance and prepared sample.
Regards,
Ganesh Harihar
Most Welcome.
Hello Rajapandi Ravi,
I have checked the prepared sample and tried to implement but I get to know that when we are fetching data to show in the filter popup we get all the records. which is not a great choice because of the time required for getting all the records from the database.
Is there any way we can apply virtual scroll with pagination for getting filter popup values or can we create a custom filter popup?
Regards,
Ganesh Harihar
Hi Ganesh,
Thanks for the update.
By default, in our EJ2 Grid the Virtualization works without Paging, The Virtualization feature is used to render the rows on scrolling content and Paging feature is used to render the rows on navigating to another page. Both are different features; we have to use only one feature at a time in the Grid. So, you cannot use the Paging feature with the Virtualization option. As a result, combining Virtualization and Paging is not a valid case.
Regards,
Rajapandi R
Hello Rajapandi Ravi,
That's correct but I want to fetch the first 10 records initially from the server. if the user scrolls down will call an API with page index 1 and get the next 10 records and merge the first 10 records and the next 10 records and assign them to the data and so on for other records.
Regards,
Ganesh Harihar
Hi Ganesh,
Thanks for your update
Our provided sample works like the same behavior you want “if the user scrolls down will call an API with page index 1 and get the next 10 records and merge the first 10 records”. Please share the sample and video demo for more information.
Sample: https://stackblitz.com/edit/angular-ws2fqv-zwxqgb?file=app.component.html,app.component.ts
Video demo: https://www.syncfusion.com/downloads/support/directtrac/general/ze/scroll-463552276.zip
Regards,
Rajapandi R
Hello Rajapandi Ravi,
It works for getting records of the grid but I am talking about values in the filter popup.
Regards,
Ganesh Harihar
Hi Ganesh,
Currently we are validating query with your shared information, and we will update you the details on or before 18th July 2022. Until then we appreciate your patience.
Rajapandi R
Hi Ganesh,
Since you like to fetch the records while scrolling in the filter popup , So we have logged a feature task as “OnDemand concept for Checkbox, Excel Filter Type” for this requirement. At Syncfusion, we are committed to fixing all validated defects (subject to technical feasibility and Product Development Life Cycle ). This feature will be included in any of our upcoming release.
You can now track the current status of your request, review the proposed resolution timeline, and contact us for any further inquiries through this link.
Feedback Link : https://www.syncfusion.com/feedback/34647/ondemand-concept-for-checkbox-excel-filter-type
Regards,
Rajapandi R
Hello Rajapandi Ravi,
Thanks for the response.
Regards,
Ganesh Harihar
Hi Ganesh,
Most Welcome
Regards,
Rajapandi R
Hello,
I'm having a problem with fetching new data, whenever new data comes in it calls actionBegin of requestType=refresh, and I loose the state of what has been selected and it scrolls to the top and it resets back to first 75 rows which is my the initial state of the grid.
How can I prevent this or any workarounds?
Note I have this as my columns are auto-generated,
This is my grid:
I have been trying to make it work like this:
but it doesn't seem to work just right.
Gustav,
Before we start providing solution to your query, we need some information for our clarification. So, please share the below details that will be helpful for us to provide better solution.
1) Please share your exact requirement scenario with detailed description.
2) Please share your complete Grid rendering code, in your Grid you are binding the events, so we would like to check the events and complete codes.
3) Share your syncfusion package version.
4) Share the issue scenario in video demonstration format.
Hi,
So the problem that I'm having is when I fetch new data with infinite scrolling, when it fetches new data it resets the table and it leaves me at the top of the table with only the first initial rows that are rendered in the beginning.
I'm also using NGRX.
grid.html:
grid.ts :
this.fetchMore emitter is what triggers a call to backend. and what it loads the new data.
On the file that I have attached below its what happens after I reach the end and when the call is made.
Gustav,
From your shared information we could see that in dataBound event, you are invoking refresh() & freezeRefresh() method of Grid. When you reach the bottom and the infinite scrolling fetch the next page records and then the dataBound event gets triggered, since you are invoking refresh() & freezeRefresh() method the entire Grid will get refreshed. So only the scroller was moved to the top again, it was the cause of the problem.
Please share the details about what you are trying to achieve in the dataBound event, please share your requirement scenario with detailed description.
Hi,
It's true in the dataBound event I invoke both of them, but I have a if() that it goes only once in that function.
But I'm seeing this in actionBegin() after I get an args.requestType of infiniteScroll event then the event as shown in the screenshot takes place and then it refreshes everything.
Which I cannot find a way to stop it.
Gustav,
Before proceeding to the solution, we would like you to share the below details.