Infinite scrolling in ASP.NET Core Grid Component
16 Feb 202421 minutes to read
Infinite scrolling is used to load a huge amount of data without degrading the Grid performance. This feature works like the lazy loading concept, which means the buffer data is loaded only when the scrollbar reaches the end of the scroller.
To enable Infinite scrolling, set enableInfiniteScrolling
property as true.
NOTE
- In this feature, Grid will not make a new data request when you visit the same page again.
<ejs-button id="generate" cssClass="e-info" content="Load 100K Data"></ejs-button>
<ejs-grid id="InfiniteGrid" height="600" enableInfiniteScrolling="true">
<e-grid-columns>
<e-grid-column field="Field1" headerText="PlayerName" width="140"></e-grid-column>
<e-grid-column field="Field2" headerText="Year" textAlign="Right" width="120"></e-grid-column>
<e-grid-column field="Field3" headerText="Stint" textAlign="Right" width="120"></e-grid-column>
<e-grid-column field="Field4" headerText="TMID" textAlign="Right" width="120"></e-grid-column>
</e-grid-columns>
</ejs-grid>
<script>
var infiniteData = [], date1 = null, date2 = null, flag = true;
var names = ['hardire', 'abramjo01', 'aubucch01', 'Hook', 'Rumpelstiltskin', 'Belle', 'Emma', 'Regina', 'Aurora', 'Elsa',
'Anna', 'Snow White', 'Prince Charming', 'Cora', 'Zelena', 'August', 'Mulan', 'Graham', 'Discord', 'Will', 'Robin Hood',
'Jiminy Cricket', 'Henry', 'Neal', 'Red', 'Aaran', 'Aaren', 'Aarez', 'Aarman', 'Aaron', 'Aaron-James', 'Aarron', 'Aaryan', 'Aaryn',
'Aayan', 'Aazaan', 'Abaan', 'Abbas', 'Abdallah', 'Abdalroof', 'Abdihakim', 'Abdirahman', 'Abdisalam', 'Abdul', 'Abdul-Aziz',
'Abdulbasir', 'Abdulkadir', 'Abdulkarem', 'Abdulkhader', 'Abdullah', 'Abdul-Majeed', 'Abdulmalik', 'Abdul-Rehman', 'Abdur',
'Abdurraheem', 'Abdur-Rahman', 'Abdur-Rehmaan', 'Abel', 'Abhinav', 'Abhisumant', 'Abid', 'Abir', 'Abraham', 'Abu', 'Abubakar',
'Ace', 'Adain', 'Adam', 'Adam-James', 'Addison', 'Addisson', 'Adegbola', 'Adegbolahan', 'Aden', 'Adenn', 'Adie', 'Adil', 'Aditya',
'Adnan', 'Adrian', 'Adrien', 'Aedan', 'Aedin', 'Aedyn', 'Aeron', 'Afonso', 'Ahmad', 'Ahmed', 'Ahmed-Aziz', 'Ahoua', 'Ahtasham',
'Aiadan', 'Aidan', 'Aiden', 'Aiden-Jack', 'Aiden-Vee'];
document.getElementById("generate").addEventListener('click', () => {
var grid = document.getElementById("InfiniteGrid").ej2_instances[0];
if (!infiniteData.length) {
dataSource();
date1 = new Date().getTime();
grid.dataSource = infiniteData;
} else {
flag = true;
show();
date1 = new Date().getTime();
grid.refresh();
}
})
function dataSource() {
for (var i = 0; i < 100000; i++) {
infiniteData.push({
'Field1': names[Math.floor(Math.random() * names.length)],
'Field2': 1967 + (i % 10),
'Field3': Math.floor(Math.random() * 200),
'Field4': Math.floor(Math.random() * 100),
'Field5': Math.floor(Math.random() * 2000)
});
}
}
</script>
public IActionResult Index()
{
return View();
}
InitialBlocks
You can define the initial loading pages count by using infiniteScrollSettings.initialBlocks
property. By default, this feature loads three pages in initial rendering.
In the below demo, we have changed this property value to load five page records instead of three.
<ejs-button id="generate" cssClass="e-info" content="Load 100K Data"></ejs-button>
<ejs-grid id="InfiniteGrid" height="600" enableInfiniteScrolling="true">
<e-grid-infiniteScrollSettings initialBlocks="5"></e-grid-infiniteScrollSettings>
<e-grid-columns>
<e-grid-column field="Field1" headerText="PlayerName" width="140"></e-grid-column>
<e-grid-column field="Field2" headerText="Year" textAlign="Right" width="120"></e-grid-column>
<e-grid-column field="Field3" headerText="Stint" textAlign="Right" width="120"></e-grid-column>
<e-grid-column field="Field4" headerText="TMID" textAlign="Right" width="120"></e-grid-column>
</e-grid-columns>
</ejs-grid>
<script>
var infiniteData = [], date1 = null, date2 = null, flag = true;
var names = ['hardire', 'abramjo01', 'aubucch01', 'Hook', 'Rumpelstiltskin', 'Belle', 'Emma', 'Regina', 'Aurora', 'Elsa',
'Anna', 'Snow White', 'Prince Charming', 'Cora', 'Zelena', 'August', 'Mulan', 'Graham', 'Discord', 'Will', 'Robin Hood',
'Jiminy Cricket', 'Henry', 'Neal', 'Red', 'Aaran', 'Aaren', 'Aarez', 'Aarman', 'Aaron', 'Aaron-James', 'Aarron', 'Aaryan', 'Aaryn',
'Aayan', 'Aazaan', 'Abaan', 'Abbas', 'Abdallah', 'Abdalroof', 'Abdihakim', 'Abdirahman', 'Abdisalam', 'Abdul', 'Abdul-Aziz',
'Abdulbasir', 'Abdulkadir', 'Abdulkarem', 'Abdulkhader', 'Abdullah', 'Abdul-Majeed', 'Abdulmalik', 'Abdul-Rehman', 'Abdur',
'Abdurraheem', 'Abdur-Rahman', 'Abdur-Rehmaan', 'Abel', 'Abhinav', 'Abhisumant', 'Abid', 'Abir', 'Abraham', 'Abu', 'Abubakar',
'Ace', 'Adain', 'Adam', 'Adam-James', 'Addison', 'Addisson', 'Adegbola', 'Adegbolahan', 'Aden', 'Adenn', 'Adie', 'Adil', 'Aditya',
'Adnan', 'Adrian', 'Adrien', 'Aedan', 'Aedin', 'Aedyn', 'Aeron', 'Afonso', 'Ahmad', 'Ahmed', 'Ahmed-Aziz', 'Ahoua', 'Ahtasham',
'Aiadan', 'Aidan', 'Aiden', 'Aiden-Jack', 'Aiden-Vee'];
document.getElementById("generate").addEventListener('click', () => {
var grid = document.getElementById("InfiniteGrid").ej2_instances[0];
if (!infiniteData.length) {
dataSource();
date1 = new Date().getTime();
grid.dataSource = infiniteData;
} else {
flag = true;
show();
date1 = new Date().getTime();
grid.refresh();
}
})
function dataSource() {
for (var i = 0; i < 100000; i++) {
infiniteData.push({
'Field1': names[Math.floor(Math.random() * names.length)],
'Field2': 1967 + (i % 10),
'Field3': Math.floor(Math.random() * 200),
'Field4': Math.floor(Math.random() * 100),
'Field5': Math.floor(Math.random() * 2000)
});
}
}
</script>
public IActionResult Index()
{
return View();
}
Cache Mode
Cache is used to store the loaded rows object in the Grid instance which can be reused for creating the row elements whenever you scroll to already visited page. Also, this mode maintains row elements based on the infiniteScrollSettings.maxBlocks
count value, once this limit exceeds then it will remove row elements from DOM for new rows.
To enable the cache mode in Infinite scrolling, set infiniteScrollSettings.enableCache
property as true.
<ejs-button id="generate" cssClass="e-info" content="Load 100K Data"></ejs-button>
<ejs-grid id="InfiniteGrid" height="600" enableInfiniteScrolling="true">
<e-grid-infiniteScrollSettings enableCache="true"></e-grid-infiniteScrollSettings>
<e-grid-columns>
<e-grid-column field="Field1" headerText="PlayerName" width="140"></e-grid-column>
<e-grid-column field="Field2" headerText="Year" textAlign="Right" width="120"></e-grid-column>
<e-grid-column field="Field3" headerText="Stint" textAlign="Right" width="120"></e-grid-column>
<e-grid-column field="Field4" headerText="TMID" textAlign="Right" width="120"></e-grid-column>
</e-grid-columns>
</ejs-grid>
<script>
var infiniteData = [], date1 = null, date2 = null, flag = true;
var names = ['hardire', 'abramjo01', 'aubucch01', 'Hook', 'Rumpelstiltskin', 'Belle', 'Emma', 'Regina', 'Aurora', 'Elsa',
'Anna', 'Snow White', 'Prince Charming', 'Cora', 'Zelena', 'August', 'Mulan', 'Graham', 'Discord', 'Will', 'Robin Hood',
'Jiminy Cricket', 'Henry', 'Neal', 'Red', 'Aaran', 'Aaren', 'Aarez', 'Aarman', 'Aaron', 'Aaron-James', 'Aarron', 'Aaryan', 'Aaryn',
'Aayan', 'Aazaan', 'Abaan', 'Abbas', 'Abdallah', 'Abdalroof', 'Abdihakim', 'Abdirahman', 'Abdisalam', 'Abdul', 'Abdul-Aziz',
'Abdulbasir', 'Abdulkadir', 'Abdulkarem', 'Abdulkhader', 'Abdullah', 'Abdul-Majeed', 'Abdulmalik', 'Abdul-Rehman', 'Abdur',
'Abdurraheem', 'Abdur-Rahman', 'Abdur-Rehmaan', 'Abel', 'Abhinav', 'Abhisumant', 'Abid', 'Abir', 'Abraham', 'Abu', 'Abubakar',
'Ace', 'Adain', 'Adam', 'Adam-James', 'Addison', 'Addisson', 'Adegbola', 'Adegbolahan', 'Aden', 'Adenn', 'Adie', 'Adil', 'Aditya',
'Adnan', 'Adrian', 'Adrien', 'Aedan', 'Aedin', 'Aedyn', 'Aeron', 'Afonso', 'Ahmad', 'Ahmed', 'Ahmed-Aziz', 'Ahoua', 'Ahtasham',
'Aiadan', 'Aidan', 'Aiden', 'Aiden-Jack', 'Aiden-Vee'];
document.getElementById("generate").addEventListener('click', () => {
var grid = document.getElementById("InfiniteGrid").ej2_instances[0];
if (!infiniteData.length) {
dataSource();
date1 = new Date().getTime();
grid.dataSource = infiniteData;
} else {
flag = true;
show();
date1 = new Date().getTime();
grid.refresh();
}
})
function dataSource() {
for (var i = 0; i < 100000; i++) {
infiniteData.push({
'Field1': names[Math.floor(Math.random() * names.length)],
'Field2': 1967 + (i % 10),
'Field3': Math.floor(Math.random() * 200),
'Field4': Math.floor(Math.random() * 100),
'Field5': Math.floor(Math.random() * 2000)
});
}
}
</script>
public IActionResult Index()
{
return View();
}
Limitations for Infinite Scrolling
- Due to the element height limitation in browsers, the maximum number of records loaded by the grid is limited due to the browser capability.
- Initial loading rows total height must be greater than the viewport height.
- Cell selection will not be persisted in cache mode.
- Infinite scrolling is not compatible with batch editing, detail template, autofill and hierarchy features.
- The group records cannot be collapsed in cache mode.
- The aggregated information and total group items are displayed based on the current view items. To get these information regardless of the view items, refer to the
Group with Page
topic. - Programmatic selection using the
selectRows
andselectRow
method is not supported in infinite scrolling. - Limitations of row drag and drop with infinite scrolling
- In cache mode, the grid refreshes automatically if the content’s tr element count exceeds the cache limit of the grid’s content after the drop action.
- When performing row drag and drop with lazy load grouping, the grid will refresh automatically.
- In remote data, changes are applied only in the UI. They will be lost once the grid is refreshed. To restore them, you need to update the changes in your database. By using the rowDrop event, you can send the request to the server and apply the changes in your database. After this, you need to refresh the grid to show the updated data.
- Limitations of column virtualization with infinite scrolling in this documentation link here