diff --git a/samples/grids/grid/remote-paging-grid/index.html b/samples/grids/grid/remote-paging-grid/index.html index bfa5c1c1c3..ff57f4a2e5 100644 --- a/samples/grids/grid/remote-paging-grid/index.html +++ b/samples/grids/grid/remote-paging-grid/index.html @@ -26,56 +26,43 @@ moving="true" paging-mode="Remote"> + id="paginator"> + name="customerId" + id="customerId" + field="customerId" + hidden="true"> + name="companyName" + id="companyName" + field="companyName" + header="Company Name"> + name="contactName" + id="contactName" + field="contactName" + header="Contact Name"> + name="contactTitle" + id="contactTitle" + field="contactTitle" + header="Contact Title"> + name="address?.country" + id="address.country" + field="address.country" + header="Country"> - - - - + name="address.phone" + id="address.phone" + field="address.phone" + header="Phone"> diff --git a/samples/grids/grid/remote-paging-grid/src/CustomersWithPageResponseModel.ts b/samples/grids/grid/remote-paging-grid/src/CustomersWithPageResponseModel.ts new file mode 100644 index 0000000000..6976b77c4d --- /dev/null +++ b/samples/grids/grid/remote-paging-grid/src/CustomersWithPageResponseModel.ts @@ -0,0 +1,7 @@ +export interface CustomersWithPageResponseModel { + items: any[]; + totalRecordsCount: number; + pageSize: number; + pageNumber: number; + totalPages: number; +} \ No newline at end of file diff --git a/samples/grids/grid/remote-paging-grid/src/RemotePagingService.ts b/samples/grids/grid/remote-paging-grid/src/RemotePagingService.ts index 6b2a6442f5..89c63bb554 100644 --- a/samples/grids/grid/remote-paging-grid/src/RemotePagingService.ts +++ b/samples/grids/grid/remote-paging-grid/src/RemotePagingService.ts @@ -1,49 +1,31 @@ -import { BehaviorSubject, Observable, from } from 'rxjs'; -import { map, catchError } from 'rxjs/operators'; - - export class RemotePagingService { - public remoteData: BehaviorSubject = new BehaviorSubject([]); - public dataLength: BehaviorSubject = new BehaviorSubject(0); - public url = 'https://www.igniteui.com/api/products'; - - constructor() {} + public static CUSTOMERS_URL = `https://data-northwind.indigo.design/Customers/GetCustomersWithPage`; + constructor() {} - public async getData(index?: number, perPage?: number): Promise { - let qS = ''; - - if (index !== undefined && perPage !== undefined) { - qS = `?$skip=${index}&$top=${perPage}&$count=true`; + 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)); } - - try { - const response = await fetch(`${this.url + qS}`); - if (!response.ok) { - throw new Error('Network response was not ok'); + + private static buildUrl(baseUrl: string, pageIndex?: number, pageSize?: number) { + let qS = ""; + if (baseUrl) { + qS += `${baseUrl}`; } - const data = await response.json(); - return data; - } catch (error) { - console.error('Error fetching data:', error); - throw error; // Propagate the error further - } -} -public async getDataLength(): Promise { - try { - const response = await fetch(this.url); - if (!response.ok) { - throw new Error('Network response was not ok'); + // 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}`; } - const data = await response.json(); - return data.length; // Assuming the length is directly accessible in the JSON response - } catch (error) { - console.error('Error fetching data length:', error); - throw error; // Propagate the error further - } -} - + return `${qS}`; + } } diff --git a/samples/grids/grid/remote-paging-grid/src/index.ts b/samples/grids/grid/remote-paging-grid/src/index.ts index 148ed763e3..0d4d06775a 100644 --- a/samples/grids/grid/remote-paging-grid/src/index.ts +++ b/samples/grids/grid/remote-paging-grid/src/index.ts @@ -3,76 +3,80 @@ import { IgcGridComponent, IgcPaginatorComponent } from 'igniteui-webcomponents- import "igniteui-webcomponents-grids/grids/themes/light/bootstrap.css"; import "./index.css"; import { RemotePagingService } from './RemotePagingService'; +import { CustomersWithPageResponseModel } from './CustomersWithPageResponseModel'; export class Sample { - public data: any[] = []; - public dataLength: number = 0; - private grid: IgcGridComponent; - private _bind: () => void; - private remotePagingService: RemotePagingService = new RemotePagingService(); - public page = 0; - private _perPage = 10; - private pager: IgcPaginatorComponent; + public data: any[] = []; + public page: number = 0; + private grid: IgcGridComponent; + private _bind: () => void; + private _perPage: number = 15; + private pager: IgcPaginatorComponent; + private _totalRecordsCount: number; - public get perPage(): number { - return this.pager.perPage || 10; - } - - private _totalRecordsCount: number; - - public get totalRecordsCount(): number { + public get perPage(): number { + return this.pager.perPage || this._perPage; + } + public set perPage(val: number) { + this._perPage = val; + } + public get totalRecordsCount(): number { return this._totalRecordsCount; - } - - public set totalRecordsCount(value: number) { + } + public set totalRecordsCount(value: number) { this._totalRecordsCount = value; this.grid.totalRecords = value; - } + } - constructor() { - this.pager = document.getElementById('paginator') as IgcPaginatorComponent; + constructor() { this.grid = document.getElementById('grid') as IgcGridComponent; - + this.pager = document.getElementById('paginator') as IgcPaginatorComponent; + this._bind = () => { - this.remotePagingService.getDataLength().then((length) => { - this.totalRecordsCount = length; - this.pager.totalRecords = this.totalRecordsCount; - }); window.addEventListener("load", () => { - this.pager.totalRecords = this.totalRecordsCount; - this.paginate(0); - }); - this.pager.addEventListener("perPageChange", ()=> { - this.paginate(0); - }) - this.pager.addEventListener("pageChange", ((args: CustomEvent) => { - this.paginate(args.detail);}) as EventListener); - } - this._bind(); - } + this.loadData(this.page,this.perPage); + }); - public paginate(page: number) { - this.page = page; - const skip = this.page * this.perPage; - const top = this.perPage; + this.pager.addEventListener("perPageChange", ((args: CustomEvent) => { + this.perPage = args.detail; + this.loadData(this.page, this.perPage); + }) as EventListener); - this.remotePagingService.getData(skip, top).then((data)=> { - this.data = data; // Assign received data to this.data - this.grid.isLoading = false; - this.updateUI(); // Update the UI after receiving data - }); - } + this.pager.addEventListener("pageChange", ((args: CustomEvent) => { + this.page = args.detail; + this.loadData(this.page, this.perPage); + }) as EventListener); + } + + this._bind(); + } - public set perPage(val: number) { - this._perPage = val; - this.paginate(val); + private updateUI(): void { + if (this.grid && this.data) { // Check if grid and data are available + this.grid.data = this.data; } + } - private updateUI() { - if (this.grid && this.data) { // Check if grid and data are available - this.grid.data = this.data; - } + 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(); + }) } } diff --git a/samples/grids/hierarchical-grid/remote-paging-sample/index.html b/samples/grids/hierarchical-grid/remote-paging-sample/index.html index 43cf95bad2..a70ddaf9da 100644 --- a/samples/grids/hierarchical-grid/remote-paging-sample/index.html +++ b/samples/grids/hierarchical-grid/remote-paging-sample/index.html @@ -19,7 +19,12 @@
- + diff --git a/samples/grids/hierarchical-grid/remote-paging-sample/src/CustomersWithPageResponseModel.ts b/samples/grids/hierarchical-grid/remote-paging-sample/src/CustomersWithPageResponseModel.ts new file mode 100644 index 0000000000..6976b77c4d --- /dev/null +++ b/samples/grids/hierarchical-grid/remote-paging-sample/src/CustomersWithPageResponseModel.ts @@ -0,0 +1,7 @@ +export interface CustomersWithPageResponseModel { + items: any[]; + totalRecordsCount: number; + pageSize: number; + pageNumber: number; + totalPages: number; +} \ No newline at end of file diff --git a/samples/grids/hierarchical-grid/remote-paging-sample/src/RemoteService.ts b/samples/grids/hierarchical-grid/remote-paging-sample/src/RemoteService.ts index 7f75ebd1b6..9d0e64a650 100644 --- a/samples/grids/hierarchical-grid/remote-paging-sample/src/RemoteService.ts +++ b/samples/grids/hierarchical-grid/remote-paging-sample/src/RemoteService.ts @@ -1,66 +1,36 @@ -import { BehaviorSubject } from 'rxjs'; -const URL = `https://data-northwind.indigo.design/`; - -function buildUrl(dataState: any, index?: number, perPage?: number): string { - let qS = ""; - if (dataState) { - if (dataState.rootLevel) { - qS += `${dataState.key}`; - } else { - qS += `${dataState.parentKey}/${dataState.parentID}/${dataState.key}`; - } - } - - // Add index and perPage to the query string if they are defined - if (index !== undefined) { - qS += `?index=${index}`; - if (perPage !== undefined) { - qS += `&perPage=${perPage}`; - } - } else if (perPage !== undefined) { - qS += `?perPage=${perPage}`; - } - - return `${URL}${qS}`; -} - export class RemotePagingService { - public remoteData: BehaviorSubject = new BehaviorSubject([]); - public dataLength: BehaviorSubject = new BehaviorSubject(0); - public url = 'https://www.igniteui.com/api/products'; + public static BASE_URL = 'https://data-northwind.indigo.design/'; + public static CUSTOMERS_URL = `${RemotePagingService.BASE_URL}Customers/GetCustomersWithPage`; constructor() {} - public async getData(dataState?: any, index?: number, perPage?: number): Promise { - try { - const response = await fetch(buildUrl(dataState, index, perPage)); - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - const data = await response.json(); - return data; - } catch (error) { - console.error('Error fetching data:', error); - throw error; - } + 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()); } - public async getDataLength(dataState: any): Promise { - try { - const response = await fetch(buildUrl(dataState)); - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - const data = await response.json(); - if (Array.isArray(data)) { - return data.length; - } else { - console.error('Data is not an array:', data); - return 0; + 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}`; } - } catch (error) { - console.error('Error fetching data length:', error); - return 0; + } else if (pageSize !== undefined) { + qS += `?perPage=${pageSize}`; } + + return `${qS}`; } } \ No newline at end of file diff --git a/samples/grids/hierarchical-grid/remote-paging-sample/src/index.ts b/samples/grids/hierarchical-grid/remote-paging-sample/src/index.ts index ab99da0fb7..3e8b04965d 100644 --- a/samples/grids/hierarchical-grid/remote-paging-sample/src/index.ts +++ b/samples/grids/hierarchical-grid/remote-paging-sample/src/index.ts @@ -3,39 +3,35 @@ import 'igniteui-webcomponents-grids/grids/combined'; import 'igniteui-webcomponents-grids/grids/themes/light/bootstrap.css'; import { html } from 'lit-html'; import { RemotePagingService } from './RemoteService'; +import { CustomersWithPageResponseModel } from './CustomersWithPageResponseModel'; export class Sample { public data: any[] = []; - public page = 0; - private _perPage = 10; - public pager: IgcPaginatorComponent; + public page: number = 0; public hierarchicalGrid: IgcHierarchicalGridComponent; - private remoteService: RemotePagingService = new RemotePagingService(); - + private _bind: () => void; + private _perPage = 15; + public pager: IgcPaginatorComponent; + private _totalRecordsCount: number; + public get perPage(): number { - return this.pager?.perPage || 10; + return this.pager?.perPage || this._perPage; } public set perPage(val: number) { this._perPage = val; - this.paginate(val); } - - private _totalRecordsCount: number; - public get totalRecordsCount(): number { - return this._totalRecordsCount; + return this._totalRecordsCount; } - public set totalRecordsCount(value: number) { - this._totalRecordsCount = value; - this.hierarchicalGrid.totalRecords = value; + this._totalRecordsCount = value; + this.hierarchicalGrid.totalRecords = value; } constructor() { - this.hierarchicalGrid = document.getElementById("hGrid") as IgcHierarchicalGridComponent; this.pager = document.getElementById('paginator') as IgcPaginatorComponent; const ordersRowIsland = document.getElementById("ordersRowIsland") as IgcRowIslandComponent; @@ -44,79 +40,89 @@ export class Sample { ordersRowIsland.paginatorTemplate = this.webHierarchicalGridPaginatorTemplate; orderDetailsRowIsland.paginatorTemplate = this.webHierarchicalGridPaginatorTemplate; - this.pager.addEventListener("perPageChange", ()=> { - this.paginate(0); - }); - this.pager.addEventListener("pageChange", ((args: CustomEvent) => { - this.paginate(args.detail);}) as EventListener); - - ordersRowIsland.addEventListener("gridCreated", (event: any) => { - this.gridCreated(event, "Customers"); - }); - - orderDetailsRowIsland.addEventListener("gridCreated", (event: any) => { - this.gridCreated(event, "Orders"); - }); - - window.addEventListener("load", () => { - this.pager.totalRecords = this.totalRecordsCount; - this.paginate(0); - }); - - this.hierarchicalGrid.data = this.data; - - this.hierarchicalGrid.isLoading = true; - this.remoteService.getData({ parentID: null, rootLevel: true, key: "Customers" }, this.page, this._perPage).then((data: any) => { - this.hierarchicalGrid.isLoading = false; - this.hierarchicalGrid.data = data; - this.hierarchicalGrid.markForCheck(); - }); - this.remoteService.getDataLength({ parentID: null, rootLevel: true, key: "Customers" }).then((length: number) => { - if(length !== undefined) { - this.totalRecordsCount = length; - this.pager.totalRecords = this.totalRecordsCount; - } - }); + 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(); } - public gridCreated(event: CustomEvent, _parentKey: string) { + public gridCreated(event: CustomEvent, parentKey: string) { const context = event.detail; - - const dataState = { - key: context.owner.childDataKey, - parentID: context.parentID, - parentKey: _parentKey, - rootLevel: false - }; + const parentId: string = context.parentID; + const childDataKey: string = context.owner.childDataKey; context.grid.isLoading = true; - this.remoteService.getDataLength(dataState).then((length: number) => { - if(length !== undefined) { - this.pager.totalRecords = length; - } - - this.remoteService.getData(dataState, this.page, this.perPage).then((data: any[]) => { - context.grid.isLoading = false; - context.grid.data = data; - context.grid.markForCheck(); - });}); - } - - public paginate(page: number) { - this.page = page; - const skip = this.page * this.perPage; - const top = this.perPage; - this.remoteService.getData({ parentID: null, rootLevel: true, key: 'Customers' }, skip, top).then((data:any)=> { - this.data = data; // Assign received data to this.data - this.hierarchicalGrid.isLoading = false; - this.hierarchicalGrid.markForCheck();// Update the UI after receiving data + 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` + // Child level grids have LOCAL paging + // They can be set to REMOTE if there are endpoints with paging for each hierarchy level data. + return html ` + ` } + + 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(); + }) + } } new Sample();