This is a function to call rows from the server side added in PlutoGrid 5.3 version.
There are two ways to load and process data on the server side.
The pagination method used in the DB structure where the total number of pages is known and the infinite scroll method used in the DB structure where the total number of pages is unknown.
Demo links
PlutoLazyPagination
https://weblaze.dev/pluto_grid/build/web/#feature/row-lazy-pagination
PlutoInfinityScrollRows
https://weblaze.dev/pluto_grid/build/web/#feature/row-infinity-scroll
This is a pagination widget.
Return a PlutoLazyPagination widget to the createFooter callback of PlutoGrid as shown below.
Pagination widget is created at the bottom of PlutoGrid.
final columns = [
PlutoColumn(
title: 'Column',
field: 'column',
type: PlutoColumnType.text()
),
];
final rows = [];
PlutoGrid(
columns: columns,
rows: rows,
createFooter: (stateManager) {
return PlutoLazyPagination(
initialPage: 1,
initialFetch: true,
fetchWithSorting: true,
fetchWithFiltering: true,
pageSizeToMove: null,
fetch: fetch,
stateManager: stateManager,
);
},
)
Implementation description of fetch function of PlutoLazyPagination
Future<PlutoLazyPaginationResponse> fetch(
PlutoLazyPaginationRequest request,
) async {
String queryString = '?page=${request.page}';
if (request.filterRows.isNotEmpty) {
final filterMap = FilterHelper.convertRowsToMap(request.filterRows);
for (final filter in filterMap.entries) {
for (final type in filter.value) {
queryString += '&filter[${filter.key}]';
final filterType = type.entries.first;
queryString += '[${filterType.key}][]=${filterType.value}';
}
}
}
if (request.sortColumn != null && !request.sortColumn!.sort.isNone) {
queryString += '&sort=${request.sortColumn!.field},${request.sortColumn!.sort.name}';
}
print(queryString);
final dataFromServer = await Future.value("""
{
"totalPage": 10,
"data": [
{
"column": "value 1"
},
{
"column": "value 2"
}
]
}
""");
final parsedData = jsonDecode(dataFromServer);
final rows = parsedData.data.map<PlutoRow>((rowData) {
return PlutoRow.fromJson(rowData);
});
return PlutoLazyPaginationResponse(
totalPage: parsedData['totalPage'],
rows: rows.toList(),
);
}
It is an infinite scrolling widget.
Return the PlutoInfinityScrollRows widget to the createFooter callback of PlutoGrid as shown below.
No widgets are created at the bottom of the PlutoGrid. (Created by SizedBox.shrink.)
No widgets need to be added, but if you need it for a special case, please ask.
I will update the function to add widgets.
final columns = [
PlutoColumn(
title: 'Id',
field: 'id',
type: PlutoColumnType.text()
),
PlutoColumn(
title: 'Name',
field: 'name',
type: PlutoColumnType.text()
),
];
final rows = [];
PlutoGrid(
columns: columns,
rows: rows,
createFooter: (stateManager) => PlutoInfinityScrollRows(
initialFetch: true,
fetchWithSorting: true,
fetchWithFiltering: true,
fetch: fetch,
stateManager: stateManager,
),
)
Implementation description of fetch function of PlutoInfinityScrollRows
Future<PlutoInfinityScrollRowsResponse> fetch(
PlutoInfinityScrollRowsRequest request,
) async {
String queryString = '?';
if (request.lastRow == null) {
queryString += 'lastId=';
} else {
queryString += 'lastId=${request.lastRow!.cells['id']}';
}
if (request.filterRows.isNotEmpty) {
final filterMap = FilterHelper.convertRowsToMap(request.filterRows);
for (final filter in filterMap.entries) {
for (final type in filter.value) {
queryString += '&filter[${filter.key}]';
final filterType = type.entries.first;
queryString += '[${filterType.key}][]=${filterType.value}';
}
}
}
if (request.sortColumn != null && !request.sortColumn!.sort.isNone) {
queryString += '&sort=${request.sortColumn!.field},${request.sortColumn!.sort.name}';
}
print(queryString);
final dataFromServer = await Future.value("""
{
"isLast": false,
"data": [
{
"id": 1,
"name": "mike"
},
{
"id": 2,
"name": "jessi"
}
]
}
""");
final parsedData = jsonDecode(dataFromServer);
final bool isLast = parsedData['isLast'];
final rows = parsedData.data.map<PlutoRow>((rowData) {
return PlutoRow.fromJson(rowData);
});
if (isLast && mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Last Page!')),
);
}
return PlutoInfinityScrollRowsResponse(
isLast: isLast,
rows: rows.toList(),
);
}
- When sorting and filtering events occur, the fetch callback requests the first page.
PlutoLazyPagination is page = 1
PlutoInfinityScrollRows is lastRow = null
This is because a sorting or filtering event must show the user new data with sorting and filtering applied.
In some cases, sorting or filtering can be handled client-side rather than being handled by the server.
fetchWithSorting = false, fetchWithFiltering = false
In this case, it is sorted or filtered based on the currently existing rows.
- The existing
stateManager.setPage operation is not valid.
The way it is handled by the server does not have a separate page state internally in PlutoGrid.
You do the paging inside the PlutoLazyPagination or PlutoInfinityScrollRows widget.
Therefore, page changes or additions are handled by deleting and inserting all existing rows of PlutoGrid.
A separate implementation is required if client-side caching handling is required. This is not yet to be considered, please comment on the GitHub issue and I will consider handling caching.
- When data is fetched from the server, it is common that filtering and sorting are not applied to all columns.
There are properties that can prevent filtering and sorting of certain columns.
enableSorting, enableFilterMenuItem in PlutoColumn.
You may also need a single filtering input rather than a filtering input for each column.
In this case, a separate UI is not provided. If necessary, please suggest it to a GitHub issue and I will consider adding it.
- The loading screen uses an internal loading widget.
A custom loading UI is not yet available. If necessary, please comment on a github issue and I will consider adding it.
- When creating a return value by fetching data from the server and creating a
PlutoRow, you need to pay attention to the PlutoColumn.field value.
The field passed to columns in PlutoGrid must match.
PlutoRow.cells is of type Map<String, PlutoCell>, and the part corresponding to String should be PlutoColumn.field.
If you have more questions, please contact us through the GitHub issue.
https://github.com/bosskmk/pluto_grid