If you are an Enterprise user you should consider using
the Server-Side Row Model
instead of the Infinite Row Model . It offers the same functionality with many more features. The differences between
row models can be found in the Row Models page.
Infinite scrolling allows the grid to lazy-load rows from the server depending on what the scroll position is of the
grid. In its simplest form, the more the user scrolls down, the more rows get loaded.
The grid will have an ‘auto extending’ vertical scroll. That means as the scroll reaches the bottom position, the grid
will extend the height to allow scrolling even further down, almost making it impossible for the user to reach the
bottom. This will stop happening once the grid has extended the scroll to reach the last record in the table.
The grid will ask your application, via a datasource, for the rows in blocks. Each block
contains a subset of rows of the entire dataset. The following diagram is a high-level overview.
When the grid scrolls to a position where there is no corresponding block of rows loaded, the model
uses the provided datasource to get the rows for the requested block. In the diagram, the datasource
is getting the rows from a database in a remote server.
To turn on infinite scrolling, you must set the grid property rowModelType="infinite"
:
dag.AgGrid(
rowModelType="infinite",
# other props
)
In a nutshell, every time the grid wants more rows, it will call getRows()
on the datasource. Use the getRowsRequest
property as the Input
of the Dash callback. The callback responds with the rows requested. Use getRowsResponse
as
the Output
of the callback to provide data to the grid.
getRowsRequest
(dict; optional): Infinite Scroll, Datasource interface. getRowsRequest
is a dict with keys:
startRow
(number; optional): The first row index to get.endRow
(number; optional): The first row index to NOT get.filterModel
(dict; optional): If filtering, what the filter model is.sortModel
(list of dicts; optional): If sorting, what the sort model is.successCallback
(function; optional): Function to call when the request is successful.failCallback
(function; optional): Function to call when the request fails.context
(boolean | number | string | dict | list; optional): The grid context object.getRowsResponse
(dict; optional): Serverside model data response object. getRowsResponse
is a dict with keys:
rowCount
(number; optional): Current row count, if known.rowData
(list of dicts; optional): Data retrieved from the server.storeInfo
(boolean | number | string | dict | list; optional): Any extra info for the grid to associate withThe grid keeps the blocks in a cache. You have the choice to never expire the blocks, or to set a limit to the number of
blocks kept. If you set a limit, then as you scroll down, previous blocks will be discarded and will be loaded again if
the user scrolls back up. The maximum blocks to keep in the cache is set using the Grid Option maxBlocksInCache
:
dashGridOptions = {"maxBlocksInCache": 10}
The block size is set using the Grid Option cacheBlockSize
. This is how many rows each block in the cache should
contain. Each call to your datasource will be for one block.
dashGridOptions = {"cacheBlockSize": 100}
It is also possible to debounce the loading to prevent blocks loading until scrolling has stopped. This can be
configured using the Grid Option blockLoadDebounceMillis
:
dashGridOptions = {"blockLoadDebounceMillis": 1000}
Aggregation and grouping are not available in infinite scrolling. This is because to do so would require the grid
knowing the entire dataset, which is not possible when using the Infinite Row Model. If you need aggregation and / or
grouping for large datasets, check
the Server-Side Row Model for
doing aggregations on the server-side.
The grid cannot do sorting or filtering for you, as it does not have all the data. Sorting or filtering must be done on
the server-side. For this reason, if the sort or filter changes, the grid will use the datasource to get the data again
and provide the sort and filter state to you.
The example below makes use of infinite scrolling and caching. Note that the grid will load more data when you bring the
scroll all the way to the bottom.
Selection works on the rows in infinite scrolling by using
the Row IDs of the Row Nodes. If you do not provide Keys for the Row
Nodes, the index of the Row Node will be used. Using the index of the row breaks down when (server-side) filtering or
sorting, as these change the index of the Rows. For this reason, if you do not provide your
own Row IDs, then selection is cleared if sort or filter is changed.
To provide your own Row IDs, use the getRowId
prop which will
return the Key for the data.
dag.AgGrid(
# the ID can be any string, as long as it's unique within your dataset
getRowId="params.data.ID"
)
Once you have a Row ID, the selection will persist across sorts and filters.
The following example extends the example above by adding server-side sorting, filtering and persistent selection.
Any column can be sorted by clicking the header. When this happens, the datasource is called again with the new sort
options.
The columns Age
, Country
and Year
can be filtered. When this happens, the datasource is called again with the new
filtering options.
When a row is selected, the selection will remain inside the grid, even if the grid gets sorted or filtered. Notice that
when the grid loads a selected row (e.g. select first row, scroll down so the first block is removed from cache, then
scroll back up again) the row is not highlighted until the row is loaded from the server. This is because the grid is
waiting to see what the ID is of the row to be loaded.
When performing multiple row selections using shift-click, it is possible that not all rows are available in memory if
the configured value ofmaxBlocksInCache
doesn’t cover the range. In this case multiple selections will not be
allowed.
It is also possible to specify which rows can be selected via the isRowSelectable
function.
For instance in the example below, we only allow rows where the data.country
property is the ‘United States’ like
this:
dashGridOptions = {
"isRowSelectable": {
"function": "params.data ? params.data.country === 'United States' : false"
}
}
Note that we have also included an optional checkbox to help highlight which rows are selectable.
The examples on this page use a loading spinner to show if the row is waiting for its data to be loaded. The grid does
not provide this, rather it is a simple rendering technique used in the examples. If the data is loading, then
the rowNode
will have no ID, so if you use the ID as the value, the cell will get refreshed when the ID is set.
To see the spinners, scroll down quickly. This example has a 2-second delay to simulate a longer running callback to
fetch data.
View Custom Loading Cell Renderer Component used for this example
This JavaScript function must be added to the dashAgGridComponentFunctions.js
file in the assets folder.
See Custom Components for more
information.
Note that in this example, the loading spinner is a component from the dash-bootstrap-components
library. In the app, it’s necessary to import the dash_components_components
library and include a Bootstrap stylesheet, even if there
are no other Bootstrap components used in the app. For example:
app.py
import dash_bootstrap_components as dbc
app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
assets/dashAgGridComponentFunctions.js
var dagcomponentfuncs = (window.dashAgGridComponentFunctions = window.dashAgGridComponentFunctions || {});
dagcomponentfuncs.SpinnerCellRenderer = function (props) {
if (props.value !== undefined) {
return props.value;
} else {
return React.createElement(window.dash_bootstrap_components.Spinner, {color: "primary", size: "sm"})
}
}
As with all row models, it is possible to enable pagination with infinite scrolling. With infinite scrolling, it is
possible to mix and match with the configuration to achieve different effects. The following examples are presented:
Example | Page Size | Block Size | Comment |
---|---|---|---|
Example 1 | Auto | Large | Most Recommended |
Example 2 | Equal | Equal | Recommended Sometimes |
Having smaller infinite blocks size than your pagination page size is not supported
You must have infinite block size greater than or equal to the pagination page size. If you have a smaller block size,
the grid will not fetch enough rows to display one page. This breaks how infinite scrolling works and is not
supported.
This example is the recommended approach. The infinite block size is larger than the pages size, so the grid loads data
for a few pages, allowing the user to hit ‘next’ a few times before a server sided call is needed.
View Custom Loading Cell Renderer Component used for this example
This JavaScript function must be added to the dashAgGridComponentFunctions.js
file in the assets folder.
See Custom Components for more
information.
var dagcomponentfuncs = (window.dashAgGridComponentFunctions = window.dashAgGridComponentFunctions || {});
dagcomponentfuncs.SpinnerCellRenderer = function (props) {
if (props.value !== undefined) {
return props.value;
} else {
return React.createElement(window.dash_bootstrap_components.Spinner, {color: "primary", size: "sm"})
}
}
This example demonstrates having the page and block sizes equal. Here the server is hit every time a new page is
navigated to.
View Custom Loading Cell Renderer Component used for this example
This JavaScript function must be added to the dashAgGridComponentFunctions.js
file in the assets folder.
See Custom Components for more
information.
var dagcomponentfuncs = (window.dashAgGridComponentFunctions = window.dashAgGridComponentFunctions || {});
dagcomponentfuncs.SpinnerCellRenderer = function (props) {
if (props.value !== undefined) {
return props.value;
} else {
return React.createElement(window.dash_bootstrap_components.Spinner, {color: "primary", size: "sm"})
}
}