Copied RSS Feed

Flutter

How to Sort Data in Syncfusion Flutter Data Tables Based on Multiple Columns

The Syncfusion Flutter DataGrid (data table) is used to display and manipulate data in a tabular view. Its rich feature set includes different types of columns, selections, column sizing, and autofit row height. The data table is optimized to handle high-frequency, real-time updates.

The data tables also provide various options to sort one or more columns. In this article, we are going to discuss the following sorting types in our data tables:

Let’s get started!

Single-column sorting

You can enable the sorting feature for these Flutter data tables by setting the allowSorting property to true. To perform sorting based on a single column, just tap on the column header to sort the data in ascending or descending order.

Refer to the following code example.

@override
Widget build(BuildContext context) {
  return Scaffold(
   body: SfDataGrid(
    source: _employeeDataSource,
    allowSorting: true,
    columns: [
      GridNumericColumn(mappingName: 'id', headerText: 'ID'),
      GridTextColumn(mappingName: 'name', headerText: 'Name'),
      GridTextColumn(mappingName: 'city', headerText: 'City'),
      GridNumericColumn(mappingName: 'freight', headerText: 'Freight')
    ],
  ));
}

In the following screenshot, the direction of the arrow in the Name column denotes that the data is sorted in ascending order.

Single-column sorting

You can also customize the trigger for sorting to a double-tap on the header by setting the sortingGestureType property to doubleTap.

Multiple-column sorting

Sort data in more than one column by setting the allowMultiColumnSorting property to true. To perform sorting on multiple columns, just tap the desired column headers in sequence.

In the web platform, sort data in multiple columns by holding on the Ctrl key when clicking on the column headers.

Refer to the following code example.

@override
Widget build(BuildContext context) {
  return Scaffold(
   body: SfDataGrid(
    source: _employeeDataSource,
    allowSorting: true,
    allowMultiColumnSorting: true,
    columns: [
      GridNumericColumn(mappingName: 'id', headerText: 'ID'),
      GridTextColumn(mappingName: 'name', headerText: 'Name'),
      GridTextColumn(mappingName: 'city', headerText: 'City'),
      GridNumericColumn(mappingName: 'freight', headerText: 'Freight')
    ],
  ));
}

In the following screenshot, first, the City column data is sorted in ascending order, and then, based on that, the Name column data is sorted in descending order.

Multiple column sorting

To show the sorted order sequence numbers while performing sorting for multiple columns, set the showSortNumbers property to true.

Refer to the following code example.

@override
Widget build(BuildContext context) {
  return Scaffold(
   body: SfDataGrid(
    source: _employeeDataSource,
    allowSorting: true,
    allowMultiColumnSorting: true,
    showSortNumbers: true,
    columns: [
      GridNumericColumn(mappingName: 'id', headerText: 'Order ID'),
      GridTextColumn(mappingName: 'name', headerText: 'Name'),
      GridTextColumn(mappingName: 'city', headerText: 'City'),
    ],
  ));
}

In the following screenshot, the numbers shown in the columns denote the sequential order in which the columns have been sorted.

Columns showing the sorted orders in sequence numbers

Tri-state sorting

You can unsort the data to its original order by tapping the column header after sorting to descending order. This feature will bring your data to the original order in which you gave it to the Flutter data table. This can be done by enabling the SfDataGrid.allowTriStateSorting property.

Refer to the following code example.

@override
Widget build(BuildContext context) {
  return Scaffold(
   body: SfDataGrid(
    source: _employeeDataSource,
    allowSorting: true,
    allowMultiColumnSorting: true,
    allowTriStateSorting: true,
    columns: [
      GridNumericColumn(mappingName: 'id', headerText: 'ID'),
      GridTextColumn(mappingName: 'name', headerText: 'Name'),
      GridTextColumn(mappingName: 'city', headerText: 'City'),
      GridNumericColumn(mappingName: 'freight', headerText: 'Freight')
    ],
  ));
}

Refer to the following .gif image.

Tri-state sorting

Programmatic sorting

In some specific cases, you may need to apply the sorting programmatically during load or run time. To apply the sorting feature programmatically, define the SortColumnDetails objects and add them to the SfDataGrid.source.sortedColumns collection. Then, call the SfDataGrid.source.sort() method to perform sorting.

Refer to the following code example.

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        SfDataGrid(
          source: _employeeDataSource,
          columns: [
            GridNumericColumn(mappingName: 'id', headerText: 'ID'),
            GridTextColumn(mappingName: 'name', headerText: 'Name'),
            GridTextColumn(mappingName: 'city', headerText: 'City'),
            GridNumericColumn(mappingName: 'freight', headerText: 'Freight')
          ],
        ),
        Padding(
          padding: const EdgeInsets.all(8.0),
          child: FlatButton(
              onPressed: () {
                _employeeDataSource.sortedColumns.add(SortColumnDetails(
                    name: 'name',
                    sortDirection: DataGridSortDirection.ascending));
                _employeeDataSource.sort();
              },
              child: Text('Apply sort')),
        )
      ],
    ),
  );
}

Custom sorting

To sort the data with custom logic, override the compare method in the DataGridSource class and then return the sort order.

The following example shows how to perform case-insensitive sorting.

class EmployeeDataSource extends DataGridSource<Employee> {
  @override
  List<Employee> get dataSource => _employeeData;

  @override
  Object getValue(Employee employee, String columnName) {
    switch (columnName) {
      case 'id':
        return employee.id;
        break;
      case 'name':
        return employee.name;
        break;
      case 'city':
        return employee.city;
        break;
      case 'freight':
        return employee.freight;
        break;
      default:
        return ' ';
        break;
    }
  }

  @override
  int compare(Employee a, Employee b, SortColumnDetails sortColumn) {
    if (sortColumn.name == 'name') {
      if (sortColumn.sortDirection == DataGridSortDirection.ascending) {
        if (a.name == null || b.name == null)
          return a.name == null ? -1 : 1;
        else 
          return a.name.toLowerCase().compareTo(b.name.toLowerCase());
      } else {
        if (a.name == null || b.name == null)
          return a.name == null ? 1 : -1;
        else
          return b.name.toLowerCase().compareTo(a.name.toLowerCase());
      }
    }
    return super.compare(a, b, sortColumn);
  }
}

Refer to the following screenshot.

Custom case-insensitive sorting

Appearance customization

The sort icon color can be customized for all columns using the SfDataGridThemeData.headerStyle.sortIconColor property and for a specific column with the GridColumn.headerStyle.sortIconColor property.

Refer to the following code example in which the sort icon color is set to redAccent.

import 'package:syncfusion_flutter_datagrid/datagrid.dart';
import 'package:syncfusion_flutter_core/theme.dart';

@override
Widget build(BuildContext context) {
  return Scaffold(
   body: SfDataGridTheme(
    data: SfDataGridThemeData(
        headerStyle: DataGridHeaderCellStyle(
            sortIconColor: Colors.redAccent,
            background)),
    child: SfDataGrid(
      source: _employeeDataSource,
      allowSorting: true,
      columns: [
        GridNumericColumn(mappingName: 'id', headerText: 'ID'),
        GridTextColumn(mappingName: 'name', headerText: 'Name'),
        GridTextColumn(mappingName: 'city', headerText: 'City'),
        GridNumericColumn(mappingName: 'freight', headerText: 'Freight')
      ],
    ),
  ));
}

Refer to the following screenshot.

Sort icon color customization

GitHub reference

Access the samples for Flutter DataGrid sorting features from this GitHub link.

Conclusion

In this blog, we learned about the various sorting features available in the Flutter Data Table. You can refer to this UG documentation for a complete guide to all the available features in the Syncfusion Flutter DataGrid widget.

If you aren’t a customer yet, you can try our 30-day free trial to check out these features.

If you wish to send us feedback or would like to submit any questions, please feel free to post them in the comments section of this blog post. You can also contact us through our support forumfeedback portal, or Direct-Trac support system. We are always happy to assist you!

Meet the Author

Neelakandan Kannan

Neelakandan Kannan is a product manager at Syncfusion. He has been a .NET developer since 2014 with expertise in Flutter, WinForms and WPF.