Can flutter PaginatedDataTable rowsPerPage be set to a number not divisible by 10?
UPDATE
Data used b
I'm leaving this for the next guy since I just battled this recently.
Right now, it seems like PaginatedDataTable has a couple of bugs in it... this is one of them. If the number of data elements doesn't exactly equal the selected number of rows per page, the PaginatedDataTable widget puts in 'filler rows'
Until this is fixed, I'd recommend taking the flutter PaginatedDataTable widget in the file paginated_data_table.dart and putting it in your project in order to customize it. (you'll have to replace all of the dependencies that aren't found with a simple import 'package:flutter/material.dart';
In order to limit the number of seen rows, add the lines with // <--- below in the _getRows method seen below:
List<DataRow> _getRows(int firstRowIndex, int rowsPerPage) {
final List<DataRow> result = <DataRow>[];
final int nextPageFirstRowIndex = firstRowIndex + rowsPerPage;
bool haveProgressIndicator = false;
for (int index = firstRowIndex; index < nextPageFirstRowIndex; index += 1) {
if (index < _rowCount) { // <---
// This stops "overflow" rows from appearing on the last page.
DataRow row;
if (index < _rowCount || _rowCountApproximate) {
row = _rows.putIfAbsent(index, () => widget.source.getRow(index));
if (row == null && !haveProgressIndicator) {
row ??= _getProgressIndicatorRowFor(index);
haveProgressIndicator = true;
}
}
row ??= _getBlankRowFor(index);
result.add(row);
} // <---
}
return result;
}
Additionally, the page count will now be off, so you'll have to change this section below in order to add the ternary operator to change the final count:
Text(
localizations.pageRowsInfoTitle(
_firstRowIndex + 1,
(_firstRowIndex + widget.rowsPerPage <= _rowCount)?_firstRowIndex + widget.rowsPerPage:_rowCount,
_rowCount,
_rowCountApproximate,
),
),
import 'package:flutter/material.dart';
class DemoTable extends StatelessWidget {
@override
Widget build(BuildContext context) {
return _DemoTableBody();
}
}
class _DemoTableBody extends StatefulWidget {
@override
__DemoTableBodyState createState() => __DemoTableBodyState();
}
class __DemoTableBodyState extends State<_DemoTableBody> {
int _rowsPerPage = PaginatedDataTable.defaultRowsPerPage;
// A Variable to hold the length of table based on the condition of comparing the actual data length with the PaginatedDataTable.defaultRowsPerPage
int _rowsPerPage1 = PaginatedDataTable.defaultRowsPerPage;
@override
Widget build(BuildContext context) {
//Obtain the data to be displayed from the Derived DataTableSource
var dts = DTS();
// dts.rowcount provides the actual data length, ForInstance, If we have 7 data stored in the DataTableSource Object, then we will get 12 as dts.rowCount
var tableItemsCount = dts.rowCount;
// PaginatedDataTable.defaultRowsPerPage provides value as 10
var defaultRowsPerPage = PaginatedDataTable.defaultRowsPerPage;
// We are checking whether tablesItemCount is less than the defaultRowsPerPage which means we are actually checking the length of the data in DataTableSource with default PaginatedDataTable.defaultRowsPerPage i.e, 10
var isRowCountLessDefaultRowsPerPage = tableItemsCount < defaultRowsPerPage;
// Assigning rowsPerPage as 10 or acutal length of our data in stored in the DataTableSource Object
_rowsPerPage =
isRowCountLessDefaultRowsPerPage ? tableItemsCount : defaultRowsPerPage;
return Scaffold(
appBar: AppBar(
title: Text("Demo Paginated Table"),
),
body: SingleChildScrollView(
child: PaginatedDataTable(
header: Text('data with 7 rows per page'),
// comparing the actual data length with the PaginatedDataTable.defaultRowsPerPage and then assigning it to _rowPerPage1 variable which then set using the setsState()
onRowsPerPageChanged: isRowCountLessDefaultRowsPerPage // The source of problem!
? null
: (rowCount) {
setState(() {
_rowsPerPage1 = rowCount;
});
},
columns: <DataColumn>[
DataColumn(label: Text('row')),
DataColumn(label: Text('name')),
],
source: dts,
//Set Value for rowsPerPage based on comparing the actual data length with the PaginatedDataTable.defaultRowsPerPage
rowsPerPage:
isRowCountLessDefaultRowsPerPage ? _rowsPerPage : _rowsPerPage1,
),
),
);
}
}
class DTS extends DataTableSource {
@override
DataRow getRow(int index) {
return DataRow.byIndex(
index: index,
cells: [
DataCell(Text('row #$index')),
DataCell(Text('name #$index')),
],
);
}
@override
int get rowCount => 9; // Manipulate this to which ever value you wish
@override
bool get isRowCountApproximate => false;
@override
int get selectedRowCount => 0;
}
This error is caused by the values provided by flutter. rowsPerPage can only be 10, 20, 50 and 100.
snapshot source PaginatedDataTable
This is specified in the source PaginatedDataTable.
Let's say you have some method that fetches data from a remote server or locally and return a list of objects like this :
List<Map<String, String>> fetchedDataObj = [
{
"name": "Rami",
"email": "dummyemail01@gmail.com"
},
{
"name": "Kara",
"email": "dummyemail02@gmail.com"
},
{
"name": "Lina",
"email": "dummyemail03@almakana.com"
}
];
in PaginatedDataTable
widget set :
rowsPerPage: fetchedDataObj.length,
and
onRowsPerPageChanged: (fetchedDataObj.length < PaginatedDataTable.defaultRowsPerPage) ? null : (r) {
// setState(() {
// _rowsPerPage = r;
// });
},
),
Hope this helps. Thanks
rowsPerPage
and availableRowsPerPage
need to be defined together.
For example:
_rowsPerPage = 5;
recalculate _rowsPerPage
in build method:
@override
Widget build(BuildContext context) {
_rowsPerPage = widget.items.length > 5 ? 5 : widget.items.length;
return _buildCollectivePanel();
}
then add rowsPerPage
, availableRowsPerPage
to the PaginatedDataTable
in _buildCollectivePanel()
PaginatedDataTable(
header: Text("dataTableHeader"),
rowsPerPage: _rowsPerPage,
availableRowsPerPage: <int>[_rowsPerPage, _rowsPerPage * 2, _rowsPerPage * 5, _rowsPerPage * 10],......