Skip to content

Commit

Permalink
Infinite scroll sample (#438)
Browse files Browse the repository at this point in the history
* Infinite scroll initial commit.

* Update sample with some workarounds.

* Rename some classes to prevent class name collisions.

* Apply review comments. Add same divs as in generated samples for unknown reasons.
  • Loading branch information
MayaKirova authored Dec 19, 2023
1 parent c59d5f8 commit c35e908
Show file tree
Hide file tree
Showing 10 changed files with 383 additions and 0 deletions.
135 changes: 135 additions & 0 deletions samples/grids/grid/infinite-scroll/App.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
@using IgniteUI.Blazor.Controls
@using System.Net.Http;
@using Newtonsoft.Json;

<div class="container vertical">
<div class="container vertical fill">
<IgbGrid AutoGenerate="false"
Height="480px"
Name="grid"
Id="grid"
Data="LocalData"
@ref="grid"
DataPreLoad="OnDataPreLoad">
<IgbColumn Name="ID"
Field="ProductID"
Header="ID">
</IgbColumn>

<IgbColumn Name="ProductName"
Field="ProductName"
Header="Product Name">
</IgbColumn>

<IgbColumn Name="QuantityPerUnit"
Field="QuantityPerUnit"
Header="Quantity Per Unit">
</IgbColumn>

<IgbColumn Name="UnitPrice"
Field="UnitPrice"
Header="Unit Price">
</IgbColumn>

<IgbColumn Name="OrderDate"
Field="OrderDate"
Header="Order Date">
</IgbColumn>

<IgbColumn Name="Discontinued"
Field="Discontinued"
Header="Discontinued">
</IgbColumn>

</IgbGrid>
</div>
</div>

@code {
@code {
protected readonly HttpClient Http = new HttpClient();
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
var grid = this.grid;
grid.IsLoading = true;
double dataViewSize = 480.0 / 50.0;
this.PageSize = Convert.ToInt32(Math.Floor(dataViewSize * 1.5));
// additional delay for TotalItemCount setter.
await Task.Delay(500);
var data = await GetDataRemote(1, this.PageSize);


this.CachedData = data;
this.LocalData = this.CachedData;

// for some reason if TotalItemCount is the same as the loaded records count it does not trigger loading events.
// so setting it to number of records + 1
grid.TotalItemCount = (this.PageSize * this.Page) + 1;
double pageCount = Math.Ceiling((double)this.TotalItems / (double)this.PageSize);
this.TotalPageCount = (int)pageCount;
grid.IsLoading = false;
StateHasChanged();
}

}

public async Task<List<NwinCustomdDataItem>> GetDataRemote(int page, int pageSize)
{
var url = "https://services.odata.org/V4/Northwind/Northwind.svc/Products";
int skip = (page - 1) * pageSize;
string query = String.Format("{0}?$count=true&$skip={1}&$top={2}", url, skip, pageSize);
NwindModel res = await Http.GetFromJsonAsync<NwindModel>(query);
this.TotalItems = res.Count;
return res.Value;

}

public async void OnDataPreLoad(IgbForOfStateEventArgs e)
{
int chunkSize = (int)e.Detail.ChunkSize;
int startIndex = (int)e.Detail.StartIndex;
int totalCount = (int)this.grid.TotalItemCount;

bool isLastChunk = totalCount == startIndex + chunkSize;
// when last chunk reached load another page of data
if (isLastChunk)
{
if (this.TotalPageCount == this.Page)
{
this.LocalData = this.CachedData.Skip(startIndex).Take(chunkSize).ToList();
return;
}

// add next page of remote data to cache
this.grid.IsLoading = true;
this.Page++;
var remoteData = await GetDataRemote(this.Page, this.PageSize);
this.CachedData.AddRange(remoteData);

var data = this.CachedData.Skip(startIndex).Take(chunkSize);
this.LocalData = data.ToList();
this.grid.IsLoading = false;
this.grid.TotalItemCount = Math.Min(this.Page * this.PageSize, this.TotalItems);
}
else
{
var data = this.CachedData.Skip(startIndex).Take(chunkSize).ToList();
this.LocalData = data;
}
}

private IgbGrid grid;
private int Page = 1;
private int PageSize = 0;
private int ChunkSize = 10;
private int TotalPageCount = 0;
private int TotalItems = 0;
public List<NwinCustomdDataItem> CachedData = new List<NwinCustomdDataItem>();

public List<NwinCustomdDataItem> LocalData = new List<NwinCustomdDataItem>();

}

}
22 changes: 22 additions & 0 deletions samples/grids/grid/infinite-scroll/BlazorClientApp.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RazorLangVersion>3.0</RazorLangVersion>
<AssemblyName>Infragistics.Samples</AssemblyName>
<RootNamespace>Infragistics.Samples</RootNamespace>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<NoWarn>1701;1702,IDE0028,BL0005,0219,CS1998</NoWarn>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="IgniteUI.Blazor" Version="23.1.37" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="6.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.Net.Http.Json" Version="6.0.0" />
</ItemGroup>

</Project>
25 changes: 25 additions & 0 deletions samples/grids/grid/infinite-scroll/BlazorClientApp.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29613.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlazorClientApp", "BlazorClientApp.csproj", "{F69CC3F0-BCD1-4CE6-9F39-CBED14E7FA78}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F69CC3F0-BCD1-4CE6-9F39-CBED14E7FA78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F69CC3F0-BCD1-4CE6-9F39-CBED14E7FA78}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F69CC3F0-BCD1-4CE6-9F39-CBED14E7FA78}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F69CC3F0-BCD1-4CE6-9F39-CBED14E7FA78}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FC52AAC8-4488-40AE-9621-75F6BA744B18}
EndGlobalSection
EndGlobal
33 changes: 33 additions & 0 deletions samples/grids/grid/infinite-scroll/NwindDataModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
public class NwinCustomdDataItem
{
public double ProductID { get; set; }
public string ProductName { get; set; }
public double SupplierID { get; set; }
public double CategoryID { get; set; }
public string QuantityPerUnit { get; set; }
public double UnitPrice { get; set; }
public double UnitsInStock { get; set; }
public double UnitsOnOrder { get; set; }
public double ReorderLevel { get; set; }
public bool Discontinued { get; set; }
public string OrderDate { get; set; }
public double Rating { get; set; }
public List<NwinCustomdDataItem_LocationsItem> Locations { get; set; }
}
public class NwinCustomdDataItem_LocationsItem
{
public string Shop { get; set; }
public string LastInventory { get; set; }
}

public class NwindModel
{
[JsonProperty("@odata.count")]
public int Count { get; set; } = 77;

[JsonProperty("value")]
public List<NwinCustomdDataItem> Value { get; set; }
}
30 changes: 30 additions & 0 deletions samples/grids/grid/infinite-scroll/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Net.Http;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Text;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using IgniteUI.Blazor.Controls; // for registering Ignite UI modules

namespace Infragistics.Samples
{
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
// registering Ignite UI modules
builder.Services.AddIgniteUIBlazor(
typeof(IgbInputModule),
typeof(IgbPropertyEditorPanelModule),
typeof(IgbGridModule)
);
await builder.Build().RunAsync();
}
}
}
27 changes: 27 additions & 0 deletions samples/grids/grid/infinite-scroll/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:4200",
"sslPort": 44385
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"BlazorSamples": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:5001;http://localhost:4200"
}
}
}
67 changes: 67 additions & 0 deletions samples/grids/grid/infinite-scroll/ReadMe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<!-- NOTE: do not change this file because it's auto re-generated from template: -->
<!-- https://github.com/IgniteUI/igniteui-blazor-examples/tree/vnext/templates/sample/ReadMe.md -->

This folder contains implementation of Blazor application with example of Remote Paging Data feature using [Grid](https://www.infragistics.com/products/ignite-ui-blazor/blazor/components/general-getting-started.html) component.


<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<body>
<!-- https://static.infragistics.com/xplatform/images/browsers -->
<a target="_blank" href="https://www.infragistics.com/products/ignite-ui-blazor/blazor/components/general-getting-started.html" rel="noopener noreferrer">
<img height="40px" style="border-radius: 0rem" alt="View Docs" src="https://github.com/IgniteUI/igniteui-blazor-examples/raw/vnext/templates/sample/images/button-docs.png"/>
</a>
<a target="_blank" href="./App.razor" rel="noopener noreferrer">
<img height="40px" style="border-radius: 0rem; max-width: 100%;" alt="View Code" src="https://github.com/IgniteUI/igniteui-blazor-examples/raw/vnext/templates/sample/images/button-code.png"/>
</a>
<a target="_blank" href="https://infragistics.com/blazor-client/samples/grids/grid/remote-paging-data" rel="noopener noreferrer">
<img height="40px" style="border-radius: 0rem; max-width: 100%;" alt="Run Sample" src="https://github.com/IgniteUI/igniteui-blazor-examples/raw/vnext/templates/sample/images/button-run.png"/>
</a>
<!-- <a target="_blank" href="https://codesandbox.io/s/github/IgniteUI/igniteui-blazor-examples/tree/master/samples/grids/grid/remote-paging-data?fontsize=14&hidenavigation=1&theme=dark&view=preview&file=/src/App.razor" rel="noopener noreferrer">
<img height="40px" style="border-radius: 0rem; max-width: 100%;" alt="Run Sample" src="https://github.com/IgniteUI/igniteui-blazor-examples/raw/vnext/templates/sample/images/button-sandbox.png"/>
</a> -->
</body>
</html>

## Setup

- instal **.NET SDK** from this [website](https://dotnet.microsoft.com/learn/aspnet/blazor-tutorial/install)


## Running App in Visual Studio 2019

NOTE: VS 2019 has better code highlighting and error detection than VS Code does.

- open **Visual Studio 2019** as an administrator

- open the **BlazorClientApp.sln** solution

- right click solution and select **Restore NuGet Packages** menu item

- click **Debug** menu and select **Start Debugging** or press **F5** key


## Running App in VS Code

- open **VS Code** as an administrator

- open this folder in **VS Code**

- open a terminal window

- to restore assemblies, run this command:
```dotnet restore```

- to run samples, run this command:
```dotnet watch run```

- wait for for message:
**Now listening on: http://localhost:4200**

- open **http://localhost:4200** in your browser


## Resources

- [Razor Component Models](https://www.codemag.com/article/1911052)
- [Razor Syntax](https://docs.microsoft.com/en-us/aspnet/core/blazor/components/?view=aspnetcore-3.1#razor-syntax)
- [Getting reference to components](https://docs.microsoft.com/en-us/aspnet/core/blazor/components/?view=aspnetcore-3.1#capture-references-to-components)
9 changes: 9 additions & 0 deletions samples/grids/grid/infinite-scroll/_Imports.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// these namespaces are global to the app
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.JSInterop
@using Infragistics.Samples
4 changes: 4 additions & 0 deletions samples/grids/grid/infinite-scroll/wwwroot/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/*
CSS styles are loaded from the shared CSS file located at:
https://static.infragistics.com/xplatform/css/samples/
*/
31 changes: 31 additions & 0 deletions samples/grids/grid/infinite-scroll/wwwroot/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<meta name="description" content="Explore samples of IgniteUI for Blazor components.">
<meta name="keywords" content="Sample, Example, Blazor, IgniteUI for Blazor, Components, Infragistics">
<meta name="author" content="Infragistics">
<title>Samples | IgniteUI for Blazor | Infragistics</title>
<base href="/" />
<link href="https://static.infragistics.com/xplatform/images/browsers/blazor.ico" rel="icon" type="image/x-icon">
<link href="https://static.infragistics.com/xplatform/css/samples/shared.v6.css" rel="stylesheet" />
<link href="https://static.infragistics.com/xplatform/css/samples/blazor.css" rel="stylesheet" />
<link href="_content/IgniteUI.Blazor/themes/grid/light/bootstrap.css" rel="stylesheet" />
<link href="index.css" rel="stylesheet" />
</head>

<body>
<app class="app"><img class="app-loading" src="https://static.infragistics.com/xplatform/images/browsers/loading.gif" /></app>
<div class="app-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="app-error-dismiss">🗙</a>
</div>
<!-- importing blazor bundle for IG controls: -->
<script src="_content/IgniteUI.Blazor/app.bundle.js"></script>
<script src="_framework/blazor.webassembly.js"></script>
</body>

</html>

0 comments on commit c35e908

Please sign in to comment.