Know what you bring to the table…


Website :

We will cover briefly about

  1. PaginatedDataTable..
  2. CustomPaginatedTable (Wrapper over PaginatedDataTable)

Note: For changes to data, we have used Provider….This article won’t be explaining how the changes gets notified….

Introducing PaginatedDataTable….

Flutter Web and PaginatedDataTable
Flutter Web and PaginatedDataTable

As per the documentation :

A material design data table that shows data using multiple pages.

A paginated data table shows rowsPerPage rows of data per page and provides controls for showing other pages.

Data is read lazily from from a DataTableSource.

Note : Data is read lazily, which means the widget is already respective performance optimization….

For this article, we have created a custom widget called CustomPaginatedTable..(Basically a wrapper over PaginatedDataTable)..

Flutter Web and PaginatedDataTable…

This is the structure of our CustomPaginatedTable. We have kept some defaults inside the latter lines of our constructor…

In case, you want to just see a sample table, you can

Widget build(BuildContext context) {
return CustomPaginatedTable();

This will initialize the paginatedDataTable with default data and source…

Fetching data to show..

We have used sample rest api service…

This gives us a list of 10 users…Then we have moulded the response into a UserModel..

Now, to show the usermodel in the CustomPaginatedTable, we need to

  • Specify dataColumns (this takes in a list)

For instance,

label: Text(DataTableConstants.colPhone),
tooltip: DataTableConstants.colPhone,
label: Text(DataTableConstants.colWebsite),
tooltip: DataTableConstants.colWebsite,
label: Text(DataTableConstants.otherDetails),
tooltip: DataTableConstants.otherDetails,

Output :

Flutter Web and PaginatedDataTable..
Flutter Web and PaginatedDataTable..

Note : This is responsible for showing the rows inside the datatable…and by default implements notifyListeners.

We create a class called UserDataTableSource,

Flutter Web and PaginatedDataTable..
Flutter Web and PaginatedDataTable..
@required List<UserModel> userData,
}) : _userData = userData,
assert(userData != null);
final List<UserModel> _userData;

We will pass the list of UserModel to our UserDataTableSource

  • Showing the rows of data,
DataRow getRow(int index){
int get rowCount => _userData.length;

For each index, we will parse the desired values as

Flutter Web and PaginatedDataTable..
Flutter Web and PaginatedDataTable..

NOTE : Number of DataCell (here) and DataColumn (see above step), should be same..

Flutter Web and PaginatedDataTable..
Flutter Web and PaginatedDataTable..

Implement Sorting …

Most of the time, we might want to sort the data, for instance, in this example.

We want to sort by email, name and id..

Lets implement our sorting logic..

Flutter Web and PaginatedDataTable..
Flutter Web and PaginatedDataTable..

Create a method called sort, inside the UserDataTableSource…

getField : What type of field (present in the UserModel), you want to sort

ascending : sort by asc or desc

Lets go back to the dataColumns , where we have a list…

label: Text(DataTableConstants.colID),
numeric: true,
tooltip: DataTableConstants.colID,
onSort: (colIndex, asc) {
_sort<num>((user) =>, colIndex, asc, _src, _provider);

there is a property in DataColumn called onSort..

In our main class, we need to have our own function, where we specify

void _sort<T>(
Comparable<T> Function(UserModel user) getField,
int colIndex,
bool asc,
UserDataTableSource _src,
UserDataNotifier _provider,
) {
_src.sort<T>(getField, asc);
_provider.sortAscending = asc;
_provider.sortColumnIndex = colIndex;

Note : The above fxn (_sort) is a private one, (only accessible from our class), and in turn calls the UserDataTableSource’s sort

Time to implement this inside our DataColumns (Name, id and email)…

Flutter Web and PaginatedDataTable..
Flutter Web and PaginatedDataTable..

For id, we specify type as num… For name/email, we specify as String…

And now we can sort…..


Inside our CustomPaginatedTable, we have a property called onRowChanged. This basically binds to the onRowsPerPageChanged property of PaginatedDataTable..

First we set the value of rowsPerPage (property) to a default value


and when we want to change the value, we call the fxn onRowChanged and pass in the selected value..

onRowChanged: (index) => _provider.rowsPerPage = index,
rowsPerPage: _provider.rowsPerPage,
Rows per page….
Rows per page….

Actions on DataTable…

In order to show actions (refresh in our case), we specify (in our CustomPaginatedTable)

showActions: true,

and for the type of action, we set

actions: <IconButton>[
splashColor: Colors.transparent,
icon: const Icon(Icons.refresh),
onPressed: () {
_showSBar(context, DataTableConstants.refresh);

This shows the following refresh icon (top right) :

Refresh Icon (Top right)….
Refresh Icon (Top right)….

View Other Details

Sometimes, we want to hide extra details, and show only if user requests. For that we have the OtherDetails field..

There is an icon(reverse triangle) associated with each row,..

hoverColor: Colors.transparent,
splashColor: Colors.transparent,
icon: const Icon(Icons.details),
onPressed: () => onRowSelect(index),

and on the click of the icon, we open a dialog and show that row’s details..

onRowSelect: (index) => _showDetails(context, _model[index]),
userData: _model,
void _showDetails(BuildContext c, UserModel data) async =>
await showDialog<bool>(
context: c,
builder: (_) => CustomDialog(
showPadding: false,
child: OtherDetails(data: data),

Hosted URL :

Source code for Flutter Web App..

Valuable comments