diff --git a/doc/en/components/grids/_shared/remote-data-operations.md b/doc/en/components/grids/_shared/remote-data-operations.md
index 137b92ee4..38ee9e898 100644
--- a/doc/en/components/grids/_shared/remote-data-operations.md
+++ b/doc/en/components/grids/_shared/remote-data-operations.md
@@ -251,9 +251,6 @@ public handlePreLoad() {
`sample="/{ComponentSample}/infinite-scroll", height="550", alt="{Platform} {ComponentTitle} Remote Data Operations Infinite Scroll Example"`
-
-
-
## Remote Sorting/Filtering
@@ -492,12 +489,16 @@ BLAZOR CODE SNIPPET HERE
+
+
## Remote Paging
The paging feature can operate with remote data. In order to demonstrate this let's first declare our service that will be responsible for data fetching. We will need the count of all data items in order to calculate the page count. This logic will be added to our service.
+
+
```typescript
@Injectable()
export class RemotePagingService {
@@ -529,16 +530,103 @@ export class RemotePagingService {
}
}
```
+
+
+
+
+```ts
+export class RemotePagingService {
+ public static CUSTOMERS_URL = `https://data-northwind.indigo.design/Customers/GetCustomersWithPage`;
+ constructor() {}
+
+ public static getDataWithPaging(pageIndex?: number, pageSize?: number) {
+ return fetch(RemotePagingService.buildUrl(RemotePagingService.CUSTOMERS_URL, pageIndex, pageSize))
+ .then((result) => result.json())
+ .catch((error) => console.error(error.message));
+ }
+
+ private static buildUrl(baseUrl: string, pageIndex?: number, pageSize?: number) {
+ let qS = "";
+ if (baseUrl) {
+ qS += `${baseUrl}`;
+ }
+
+ // Add pageIndex and size to the query string if they are defined
+ if (pageIndex !== undefined) {
+ qS += `?pageIndex=${pageIndex}`;
+ if (pageSize !== undefined) {
+ qS += `&size=${pageSize}`;
+ }
+ } else if (pageSize !== undefined) {
+ qS += `?perPage=${pageSize}`;
+ }
+
+ return `${qS}`;
+ }
+}
+```
+
+
+
+
+As Blazor Server is already a remote instance, unlike the demos in the other platforms we do not need to set another remote instance for the data, as the data is already remote. In order to do remote paging, we just need to set a couple of methods ins the data class
```razor
-BLAZOR CODE SNIPPET HERE
+ public Task> GetData(int index, int perPage)
+ {
+ var itemsToReturn = items.Skip(index).Take(perPage).ToList();
+ return Task.FromResult(itemsToReturn);
+ }
+
+ public Task GetDataLength()
+ {
+ return Task.FromResult(items.Count);
+ }
+```
+
+
+
+```tsx
+const CUSTOMERS_URL = `https://data-northwind.indigo.design/Customers/GetCustomersWithPage`;
+
+export class RemoteService {
+
+ public static getDataWithPaging(pageIndex?: number, pageSize?: number) {
+ return fetch(this.buildUrl(CUSTOMERS_URL, pageIndex, pageSize))
+ .then((result) => result.json());
+ }
+
+ private static buildUrl(baseUrl: string, pageIndex?: number, pageSize?: number) {
+ let qS = "";
+ if (baseUrl) {
+ qS += `${baseUrl}`;
+ }
+
+ // Add pageIndex and size to the query string if they are defined
+ if (pageIndex !== undefined) {
+ qS += `?pageIndex=${pageIndex}`;
+ if (pageSize !== undefined) {
+ qS += `&size=${pageSize}`;
+ }
+ } else if (pageSize !== undefined) {
+ qS += `?perPage=${pageSize}`;
+ }
+
+ return `${qS}`;
+ }
+}
```
+
+
+
+
The paging feature can operate with remote data. In order to demonstrate this let's first declare our service that will be responsible for data fetching. We will need the count of all data items in order to calculate the page count. This logic will be added to our service.
+
```typescript
@Injectable()
export class RemotePagingService {
@@ -571,15 +659,113 @@ export class RemotePagingService {
}
```
+
+
+
+```ts
+export class RemotePagingService {
+ public static BASE_URL = 'https://data-northwind.indigo.design/';
+ public static CUSTOMERS_URL = `${RemotePagingService.BASE_URL}Customers/GetCustomersWithPage`;
+
+ constructor() {}
+
+ public static getDataWithPaging(pageIndex?: number, pageSize?: number) {
+ return fetch(RemotePagingService.buildUrl(RemotePagingService.CUSTOMERS_URL, pageIndex, pageSize))
+ .then((result) => result.json())
+ .catch((error) => console.error(error.message));
+ }
+
+ public static getHierarchyDataById(parentEntityName: string, parentId: string, childEntityName: string) {
+ return fetch(`${RemotePagingService.BASE_URL}${parentEntityName}/${parentId}/${childEntityName}`)
+ .then((result) => result.json());
+ }
+
+ private static buildUrl(baseUrl: string, pageIndex?: number, pageSize?: number) {
+ let qS = "";
+ if (baseUrl) {
+ qS += `${baseUrl}`;
+ }
+
+ // Add pageIndex and size to the query string if they are defined
+ if (pageIndex !== undefined) {
+ qS += `?pageIndex=${pageIndex}`;
+ if (pageSize !== undefined) {
+ qS += `&size=${pageSize}`;
+ }
+ } else if (pageSize !== undefined) {
+ qS += `?perPage=${pageSize}`;
+ }
+
+ return `${qS}`;
+ }
+}
+```
+
+
+
+As Blazor Server is already a remote instance, unlike the demos in the other platforms we do not need to set another remote instance for the data, as the data is already remote. In order to do remote paging, we just need to set a couple of methods ins the data class
+
```razor
-BLAZOR CODE SNIPPET HERE
+ public Task> GetData(int index, int perPage)
+ {
+ var itemsToReturn = items.Skip(index).Take(perPage).ToList();
+ return Task.FromResult(itemsToReturn);
+ }
+
+ public Task GetDataLength()
+ {
+ return Task.FromResult(items.Count);
+ }
+```
+
+
+
+
+```tsx
+const BASE_URL = `https://data-northwind.indigo.design/`;
+const CUSTOMERS_URL = `${BASE_URL}Customers/GetCustomersWithPage`;
+
+export class RemoteService {
+
+ public static getCustomersDataWithPaging(pageIndex?: number, pageSize?: number) {
+ return fetch(this.buildUrl(CUSTOMERS_URL, pageIndex, pageSize))
+ .then((result) => result.json());
+ }
+
+ public static getHierarchyDataById(parentEntityName: string, parentId: string, childEntityName: string) {
+ return fetch(`${BASE_URL}${parentEntityName}/${parentId}/${childEntityName}`)
+ .then((result) => result.json());
+ }
+
+ private static buildUrl(baseUrl: string, pageIndex?: number, pageSize?: number) {
+ let qS = "";
+ if (baseUrl) {
+ qS += `${baseUrl}`;
+ }
+
+ // Add pageIndex and size to the query string if they are defined
+ if (pageIndex !== undefined) {
+ qS += `?pageIndex=${pageIndex}`;
+ if (pageSize !== undefined) {
+ qS += `&size=${pageSize}`;
+ }
+ } else if (pageSize !== undefined) {
+ qS += `?perPage=${pageSize}`;
+ }
+
+ return `${qS}`;
+ }
+}
```
+
+
After declaring the service, we need to create a component, which will be responsible for the `{ComponentName}` construction and data subscription.
+
```typescript
export class RemotePagingGridSample implements OnInit, AfterViewInit, OnDestroy {
public data: Observable;
@@ -603,13 +789,208 @@ export class RemotePagingGridSample implements OnInit, AfterViewInit, OnDestroy
}
}
```
+
+
+
+First we need to bind to the relevant events so when we change pages and the amount of records shown per page, the remote service will fetch the correct amount of data
+```ts
+ constructor() {
+ this.grid = document.getElementById('grid') as IgcGridComponent;
+ this.pager = document.getElementById('paginator') as IgcPaginatorComponent;
+
+ this._bind = () => {
+ window.addEventListener("load", () => {
+ this.loadData(this.page,this.perPage);
+ });
+
+ this.pager.addEventListener("perPageChange", ((args: CustomEvent) => {
+ this.perPage = args.detail;
+ this.loadData(this.page, this.perPage);
+ }) as EventListener);
+
+ this.pager.addEventListener("pageChange", ((args: CustomEvent) => {
+ this.page = args.detail;
+ this.loadData(this.page, this.perPage);
+ }) as EventListener);
+ }
+
+ this._bind();
+ }
+```
+We also need to set the method for loading data and update the UI accordingly:
+```ts
+ private loadData(pageIndex?: number, pageSize?: number): void {
+ this.grid.isLoading = true;
+
+ RemotePagingService.getDataWithPaging(pageIndex,pageSize)
+ .then((response: CustomersWithPageResponseModel) => {
+ this.totalRecordsCount = response.totalRecordsCount;
+ this.pager.perPage = pageSize;
+ this.pager.totalRecords = this.totalRecordsCount;
+ this.page = response.pageNumber;
+ this.data = response.items;
+ this.grid.isLoading = false;
+ this.updateUI(); // Update the UI after receiving data
+ })
+ .catch((error) => {
+ console.error(error.message);
+ // Stop loading even if error occurs. Prevents endless loading
+ this.grid.isLoading = false;
+ this.updateUI();
+ })
+ }
+
+ private updateUI(): void {
+ if (this.grid && this.data) { // Check if grid and data are available
+ this.grid.data = this.data;
+ }
+ }
+```
+
+
+For further reference, please check the demo bellow:
+
+### Grid Remote Paging Demo
+
+`sample="/{ComponentSample}/remote-paging-grid", height="550", alt="{Platform} {ComponentTitle} Grid Remote Paging Example"`
+
+
+
+
+First we should load some data to the grid. It is best to do after the grid has been rendered to avoid any timing issues.
```razor
-BLAZOR CODE SNIPPET HERE
+ protected override async Task OnAfterRenderAsync(bool firstRender)
+ {
+ if (firstRender)
+ {
+ await Paginate(0, PerPage);
+ totalRecordsCount = await NwindDataService.GetDataLength();
+ StateHasChanged();
+ }
+ }
+```
+After that we just need to bind the paging events to our custom methods, and remote paging is set:
+
+```razor
+
+
+....
+
+@code {
+ private async void OnPerPageChange(IgbNumberEventArgs e)
+ {
+ PerPage = e.Detail;
+ await Paginate(0, e.Detail);
+ }
+
+ private async void OnPageChange(IgbNumberEventArgs e)
+ {
+ await Paginate(e.Detail, PerPage);
+ }
+ ...
+ private async Task Paginate(double page, double perPage)
+ {
+ this.page = page;
+ double skip = this.page * PerPage;
+ double top = PerPage;
+
+ try
+ {
+ data = await NwindDataService.GetData(Convert.ToInt32(skip), Convert.ToInt32(perPage));
+ isLoading = false;
+ UpdateUI();
+ }
+ catch (Exception ex)
+ {
+ Console.Error.WriteLine($"Error fetching data: {ex.Message}");
+ }
+ }
+}
```
+For further reference please check the full demo bellow:
+
+### Grid Remote Paging Demo
+
+`sample="/{ComponentSample}/remote-paging-grid", height="550", alt="{Platform} {ComponentTitle} Grid Remote Paging Example"`
+
+
+
+
+```tsx
+
+
+
+
+
+
+
+
+
+
+```
+
+then set up the state:
+```tsx
+ const grid = useRef(null);
+ const paginator = useRef(null);
+ const [data, setData] = useState([]);
+ const [page, setPage] = useState(0);
+ const [perPage, setPerPage] = useState(15);
+ const [isLoading, setIsLoading] = useState(true);
+
+ useEffect(() => {
+ loadGridData(page, perPage);
+ }, [page, perPage]);
+```
+
+and finally set up the method for loading the data:
+```tsx
+ function loadGridData(pageIndex?: number, pageSize?: number) {
+ // Set loading state
+ setIsLoading(true);
+
+ // Fetch data
+ RemoteService.getDataWithPaging(pageIndex, pageSize)
+ .then((response: CustomersWithPageResponseModel) => {
+ setData(response.items);
+ // Stop loading when data is retrieved
+ setIsLoading(false);
+ paginator.current.totalRecords = response.totalRecordsCount;
+ })
+ .catch((error) => {
+ console.error(error.message);
+ setData([]);
+ // Stop loading even if error occurs. Prevents endless loading
+ setIsLoading(false);
+ })
+ }
+```
+
+For further reference please check the full sample bellow:
+
+### Grid Remote Paging Demo
+
+`sample="/{ComponentSample}/remote-paging-grid", height="550", alt="{Platform} {ComponentTitle} Grid Remote Paging Example"`
+
+
+
+
+
```typescript
export class HGridRemotePagingSampleComponent implements OnInit, AfterViewInit, OnDestroy {
public data: BehaviorSubject = new BehaviorSubject([]);
@@ -633,13 +1014,309 @@ export class HGridRemotePagingSampleComponent implements OnInit, AfterViewInit,
}
}
```
+
+
+
+First we need to bind to the relevant events so when we change pages and the amount of records shown per page, the remote service will fetch the correct amount of data
+```ts
+ constructor() {
+ this.hierarchicalGrid = document.getElementById("hGrid") as IgcHierarchicalGridComponent;
+ this.pager = document.getElementById('paginator') as IgcPaginatorComponent;
+ const ordersRowIsland = document.getElementById("ordersRowIsland") as IgcRowIslandComponent;
+ const orderDetailsRowIsland = document.getElementById("orderDetailsRowIsland") as IgcRowIslandComponent;
+
+ ordersRowIsland.paginatorTemplate = this.webHierarchicalGridPaginatorTemplate;
+ orderDetailsRowIsland.paginatorTemplate = this.webHierarchicalGridPaginatorTemplate;
+
+ this._bind = () => {
+ window.addEventListener("load", () => {
+ this.pager.perPage = this._perPage;
+ this.loadCustomersData(this.page,this.perPage);
+ });
+
+ this.pager.addEventListener("perPageChange", ((args: CustomEvent) => {
+ this.perPage = args.detail;
+ this.loadCustomersData(this.page, this.perPage);
+ }) as EventListener);
+
+ this.pager.addEventListener("pageChange", ((args: CustomEvent) => {
+ this.page = args.detail;
+ this.loadCustomersData(this.page, this.perPage);
+ }) as EventListener);
+
+ ordersRowIsland.addEventListener("gridCreated", (event: any) => {
+ this.gridCreated(event, "Customers");
+ });
+
+ orderDetailsRowIsland.addEventListener("gridCreated", (event: any) => {
+ this.gridCreated(event, "Orders");
+ });
+ }
+
+ this._bind();
+ }
+```
+We also need to set the method for loading data and update the UI accordingly:
+```ts
+ private updateUI(): void {
+ if (this.hierarchicalGrid && this.data) { // Check if grid and data are available
+ this.hierarchicalGrid.data = this.data;
+ }
+ }
+
+ private loadCustomersData(pageIndex?: number, pageSize?: number): void {
+ this.hierarchicalGrid.isLoading = true;
+
+ RemotePagingService.getDataWithPaging(pageIndex,pageSize)
+ .then((response: CustomersWithPageResponseModel) => {
+ this.totalRecordsCount = response.totalRecordsCount;
+ this.pager.perPage = pageSize;
+ this.pager.totalRecords = this.totalRecordsCount;
+ this.page = response.pageNumber;
+ this.data = response.items;
+ this.hierarchicalGrid.isLoading = false;
+ this.updateUI(); // Update the UI after receiving data
+ })
+ .catch((error) => {
+ console.error(error.message);
+ this.hierarchicalGrid.data = [];
+ this.hierarchicalGrid.isLoading = false;
+ this.updateUI();
+ })
+ }
+```
+
+And finally we need to handle the behaviour behind the actual hierarchy levels of the Hierarchical Gird
+```ts
+ public gridCreated(event: CustomEvent, parentKey: string) {
+ const context = event.detail;
+ const parentId: string = context.parentID;
+ const childDataKey: string = context.owner.childDataKey;
+
+ context.grid.isLoading = true;
+ RemotePagingService.getHierarchyDataById(parentKey, parentId, childDataKey)
+ .then((data: any) => {
+ context.grid.data = data;
+ context.grid.isLoading = false;
+ context.grid.markForCheck();
+ })
+ .catch((error) => {
+ console.error(error.message);
+ context.grid.data = [];
+ context.grid.isLoading = false;
+ context.grid.markForCheck();
+ });
+ }
+
+ public webHierarchicalGridPaginatorTemplate = () => {
+ return html `
+
+ `
+ }
+```
+
+For further reference, please check the demo bellow:
+
+### Grid Remote Paging Demo
+
+`sample="/{ComponentSample}/remote-paging-hgrid", height="550", alt="{Platform} {ComponentTitle} Hierarchical Grid Remote Paging Example"`
+
+
+
+
+First we should load some data to the grid. It is best to do after the grid has been rendered to avoid any timing issues.
```razor
-BLAZOR CODE SNIPPET HERE
+ protected override async Task OnAfterRenderAsync(bool firstRender)
+ {
+ if (firstRender)
+ {
+ await Paginate(0, PerPage);
+ totalRecordsCount = await NwindDataService.GetDataLength();
+ StateHasChanged();
+ }
+ }
+```
+After that we just need to bind the paging events to our custom methods, and remote paging is set:
+
+```razor
+
+
+....
+
+@code {
+ private async void OnPerPageChange(IgbNumberEventArgs e)
+ {
+ PerPage = e.Detail;
+ await Paginate(0, e.Detail);
+ }
+
+ private async void OnPageChange(IgbNumberEventArgs e)
+ {
+ await Paginate(e.Detail, PerPage);
+ }
+ ...
+ private async Task Paginate(double page, double perPage)
+ {
+ this.page = page;
+ double skip = this.page * PerPage;
+ double top = PerPage;
+
+ try
+ {
+ data = await NwindDataService.GetData(Convert.ToInt32(skip), Convert.ToInt32(perPage));
+ isLoading = false;
+ UpdateUI();
+ }
+ catch (Exception ex)
+ {
+ Console.Error.WriteLine($"Error fetching data: {ex.Message}");
+ }
+ }
+}
+```
+For further reference please check the full demo bellow:
+
+### Grid Remote Paging Demo
+
+`sample="/{ComponentSample}/remote-paging-grid", height="550", alt="{Platform} {ComponentTitle} Hierarchical Grid Remote Paging Example"`
+
+
+
+
+```tsx
+
+
+
+
+
+
+
+
+
+
+ gridCreated(rowIsland, e, "Customers")}
+ >
+
+
+
+
+
+
+ gridCreated(rowIsland, e, "Orders")}
+ >
+
+
+
+
+
+
+
+```
+then set up the state:
+```tsx
+ const hierarchicalGrid = useRef(null);
+ const paginator = useRef(null);
+
+ const [data, setData] = useState([]);
+ const [page, setPage] = useState(0);
+ const [perPage, setPerPage] = useState(15);
+ const [isLoading, setIsLoading] = useState(true);
+
+ useEffect(() => {
+ loadGridData(page, perPage);
+ }, [page, perPage]);
+```
+
+next set up the method for loading the data:
+```tsx
+ function loadGridData(pageIndex?: number, pageSize?: number) {
+ // Set loading state
+ setIsLoading(true);
+
+ // Fetch data
+ RemoteService.getCustomersDataWithPaging(pageIndex, pageSize)
+ .then((response: CustomersWithPageResponseModel) => {
+ setData(response.items);
+ // Stop loading when data is retrieved
+ setIsLoading(false);
+ paginator.current.totalRecords = response.totalRecordsCount;
+ })
+ .catch((error) => {
+ console.error(error.message);
+ setData([]);
+ // Stop loading even if error occurs. Prevents endless loading
+ setIsLoading(false);
+ })
+ }
+```
+
+
+
+
+
+
+and finally set up the behaviour for the RowIslands:
+
+```tsx
+ function gridCreated(rowIsland: IgrRowIsland, event: IgrGridCreatedEventArgs, parentKey: string) {
+ const context = event.detail;
+ const parentId: string = context.parentID;
+ const childDataKey: string = rowIsland.childDataKey;
+
+ RemoteService.getHierarchyDataById(parentKey, parentId, childDataKey)
+ .then((data: any) => {
+ context.grid.data = data;
+ context.grid.isLoading = false;
+ context.grid.markForCheck();
+ })
+ .catch((error) => {
+ console.error(error.message);
+ context.grid.data = [];
+ context.grid.isLoading = false;
+ context.grid.markForCheck();
+ })
+ }
```
+
+
+For further reference please check the full sample bellow:
+
+### Grid Remote Paging Demo
+
+`sample="/{ComponentSample}/remote-paging-hgrid", height="550", alt="{Platform} {ComponentTitle} Hierarchical Grid Remote Paging Example"`
+
+
+
+
+
In this sample we will demonstrate how to display a certain number of root records per page no matter how many child records they have. In order to cancel the built-in Tree Grid paging algorithm, which displays a certain number of records no matter their level (root or child), we have to set the `PerPage` property to `Number.MAX_SAFE_INTEGER`.
@@ -1009,7 +1686,6 @@ As you can see in the `Paginate` method, custom pagination logic is performed, b
`sample="/{ComponentSample}/remote-paging-batch-editing", height="620", alt="{Platform} {ComponentTitle} Remote Paging Batch Editing Example"`
-
diff --git a/docfx/en/components/toc.json b/docfx/en/components/toc.json
index 1d4b28156..2f3294094 100644
--- a/docfx/en/components/toc.json
+++ b/docfx/en/components/toc.json
@@ -477,7 +477,7 @@
"href": "grids/hierarchical-grid/paging.md"
},
{
- "exclude": ["Angular", "Blazor", "React", "WebComponents"],
+ "exclude": ["Angular"],
"name": "Remote Data Operations",
"href": "grids/hierarchical-grid/remote-data-operations.md"
},