grid-js / gridjs

Advanced table plugin
https://gridjs.io
MIT License
4.39k stars 240 forks source link

Sorting with Undefined Values #1424

Open ldrummond opened 7 months ago

ldrummond commented 7 months ago

Column sorting doesn't work as expected when column contains undefined values.

To Reproduce Steps to reproduce the behavior:

  1. Create a table
  2. Add data as array of arrays, with sample values
    [
    [undefined],
    [100],
    [300],
    [undefined],
    [50]
    }
  3. Test sorting of column; sorting does not occur. No errors are thrown.

** Device

Additional context May be able to fix by 1. Adding check for undefined in native sort function 2. Passing order (asc, desc) to comparator function for custom handling of undefined values. Unfortunately don't currently have time to check all possible causes and write PR, but may be able to in the next few weeks.

JonasKellerer commented 3 months ago

We seem to have a similar issue. When there are null values, then the sorting goes wrong. Some entries are sorted, but when the null value is reached, then the following values are no longer sorted. Writing an own sort function solves the issue.

anguslee-wse commented 2 months ago

This is my attempt of fixing the code in src/pipeline/sort/native.ts by using https://github.com/snovakovic/fast-sort.

import { inPlaceSort, ISortByObjectSorter } from 'fast-sort';

...

protected _process(data: Tabular): Tabular {
    const sortedRows = [...data.rows];
    /* sortedRows.sort(this.compareWrapper.bind(this)); */
    let sortBys: ISortByObjectSorter<Row>[] = [];
    for (const column of this.props.columns) {
      let sortBy: ISortByObjectSorter = {};
      if (column.direction === -1) {
        sortBy.desc = (r: Row): TCell => {
          return r.cells[column.index].data;
        };
      }
      else {
        sortBy.asc = (r: Row): TCell => {
          return r.cells[column.index].data;
        };
      }
      if (typeof column.compare === 'function') {
        sortBy.comparer = column.compare;
      }
      sortBys.push(sortBy);
    }
    inPlaceSort(sortedRows).by(sortBys);

    const sorted = new Tabular(sortedRows);
    // we have to set the tabular length manually
    // because of the server-side storage
    sorted.length = data.length;

    return sorted;
}