angular / components

Component infrastructure and Material Design components for Angular
https://material.angular.io
MIT License
24.32k stars 6.72k forks source link

[Table] Add sort function to MatTableDataSource #8121

Closed quanterion closed 6 years ago

quanterion commented 6 years ago

Proposal:

Currently inside MatTableDataSource (that is inside master branch, but not released yet) there is sortingDataAccessor function that allows customization of sorting behavior. I propose to enhanсe or replace it with sortFunction

What is the use-case or motivation for changing an existing behavior?

For example, I have array of files, some of them are folders. I want to display all folders first and files last. I can try to solve it by using data accessor that return string ${data.isFolder}${data[sortHeaderId]}. However it doesn't work when sort direction changed from ascending do descending and the folders will be beneath the files.

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

Current master branch of Anular Material

Is there anything else we should know?

I think using sortFunction = (a: T, b: T, ascending: boolean) over sortingDataAccessor is better because sortFunction gives greater flexibility, while sortingDataAccessor just saves a single line of actual comparison.

andrewseguin commented 6 years ago

Sounds reasonable, its possible we can add another hook for overriding the sort function altogether. I suspect we would keep the sortDataAccessor as a more granular hook for those who just want to customize how the data source gets data for sorting. By default, the overall sortPredicate would sort by using the sortDataAccessor.

In the meantime, I imagine you may just want to avoid sending the MatSort to the data source and handle the sorting yourself. When sort changes, send the sorted data to the data source.

ghost commented 6 years ago

I have another issue with the sorting system. Can the sort function be on a column in particular ? Y a have a table with 10 columns: 9 string with a default alpha sort, and the tenth column with a custom sort. I only want to customize this one, not the others.

andrewseguin commented 6 years ago

You can now override sortData to have full control over the data sorting.

https://github.com/angular/material2/pull/8698

rohitkrishna12 commented 6 years ago

@andrewseguin is there any place where we can find an example on how to override sortData to implement custom data sorting?

VladislavLobakh commented 5 years ago

@rohitkrishna12 it's a simple example:

this.dataSource.sortingDataAccessor = (data: any, sortHeaderId: string) => {
  const value: any = data[sortHeaderId]; 
  return typeof value === "string" ? value.toLowerCase() : value; 
};
jaroslaw-bagnicki commented 5 years ago

@rohitkrishna12 I do it like this:

export class MatTableDataSourceWithCustomSort<T> extends MatTableDataSource<T> {

  _compareFn = new Intl.Collator('pl', {sensitivity: 'base', numeric: true}).compare;

  sortData: ((data: T[], sort: MatSort) => T[]) = (data: T[], sort: MatSort): T[] => {
    const active = sort.active;
    const direction = sort.direction;
    if (!active || direction == '') { return data; }

    return data.sort((a, b) => {
      const valueA = this.sortingDataAccessor(a, active);
      const valueB = this.sortingDataAccessor(b, active);

      const comparatorResult = this._compareFn(<string>valueA, <string>valueB);

      return comparatorResult * (direction == 'asc' ? 1 : -1);
    });
  }
}
angular-automatic-lock-bot[bot] commented 5 years ago

This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.