bosskmk / pluto_grid

PlutoGrid is a dataGrid for flutter that can be controlled by the keyboard on desktop and web. Of course, it works well on Android and IOS.
https://pluto.weblaze.dev
MIT License
635 stars 288 forks source link

[Feature] Custom sorting on column based on value #1038

Closed Kaexzr closed 1 month ago

Kaexzr commented 3 months ago

I have some values that are members of an enum on the server side, I send them to the client as the string representation, so flutter can simply display it on a PlutoGrid, but sorting is broken, since I don't want them to be sorted alphabetically,

I could use a PlutoColumnValueFormatter and change my underlying data type to int and convert to text on the client side, but I would love to have a way to simply override how sorting is applied to a column. I can think of many reasons this would be useful.

One way this could be done is: take a delegate the will be called with the cell value, and must return an int, then the sorting will be applied on the int value behind the scenes.

i.e. image

Kaexzr commented 2 months ago

This might be far from a proper patch, but it works. Is there anything I should look into before attempting a pull request?

For starters, Im passing the value to the delegate, not valueForSorting, as callers would expect data in the same format they set in the grid, is this desired? The value passed to the delegate can be null, but the returned int must not be null, so we dont have to deal with null values in library code. We might want to pass the current PlutoRow to the delegate, instead of the value, so callers can break ties on the value of the current cell (i.e. sort by this then that then....)

Any comments, suggestions?

pluto_column.dart

typedef PlutoSortDelegate = int Function(dynamic? value);

/// A callback that returns a value for sorting.
PlutoSortDelegate? sortDelegate;

  PlutoColumn({
    ...
    this.sortDelegate,

column_state.dart

 @override
  void sortAscending(PlutoColumn column, {bool notify = true}) {
    ....
    compare(a, b) {
      if (column.sortDelegate != null) {       
          var v1 = column.sortDelegate!(a.cells[column.field]!.value);
          var v2 = column.sortDelegate!(b.cells[column.field]!.value);
          return v1.compareTo(v2);  
      } else {
        return column.type.compare(
          a.cells[column.field]!.valueForSorting,
          b.cells[column.field]!.valueForSorting,
        );
      }
    }

    // compare(a, b) => column.type.compare(
    //       a.cells[column.field]!.valueForSorting,
    //       b.cells[column.field]!.valueForSorting,
    //     );
    ...

  @override
  void sortDescending(PlutoColumn column, {bool notify = true}) {
    ...
    compare(b, a) {
      if (column.sortDelegate != null) {
        var v1 = column.sortDelegate!(a.cells[column.field]!.value);
        var v2 = column.sortDelegate!(b.cells[column.field]!.value);
        return v1.compareTo(v2);
      } else {
        return column.type.compare(
          a.cells[column.field]!.valueForSorting,
          b.cells[column.field]!.valueForSorting,
        );
      }
    }

    // compare(b, a) => column.type.compare(
    //       a.cells[column.field]!.valueForSorting,
    //       b.cells[column.field]!.valueForSorting,
    //     );
    ...

Now, I can do :

image

github-actions[bot] commented 1 month ago

This issue is stale because it has been open for 30 days with no activity.

github-actions[bot] commented 1 month ago

This issue was closed because it has been inactive for 14 days since being marked as stale.