Components: [Sort] Implement API to clear sort

Created on 22 Mar 2018  路  10Comments  路  Source: angular/components

Bug, feature request, or proposal:

I would like to know if there is a provision available to clear the sorting set by user on a mat-table column dynamically.

What is the expected behavior?

Provision to clear sort order set by user on mat-table

What is the current behavior?

Once user applies sort on a particular column, it is maintained permanently.

What are the steps to reproduce?

Click on one column header of a mat-table with sorting implemented. The table will be sorted based on the column data. Now if we need to reset the sorting, we need to click on the same column header 2 more times.

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

Our requirement is to reset the user selected sort order on every reload.

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

Angular CLI: 1.7.3
Node: 8.9.4
OS: win32 x64
Angular: 5.2.9

Is there anything else we should know?

P3 materiasort feature

Most helpful comment

Re-opening - looks like there isn't a good way to do this right now. Once the sort is set, it is not obvious how to reset the active sort.

Here's a workaround you can use while we design an affordance for this in the API:

  clearSort() {
    this.sort.sort({id: '', start: 'asc', disableClear: false});
  }

https://stackblitz.com/edit/angular-8ppzzq?file=app/table-sorting-example.ts

All 10 comments

Please keep GitHub issues for bug reports / feature requests. Better avenues for troubleshooting / questions are stack overflow, gitter, mailing list, etc.

Re-opening - looks like there isn't a good way to do this right now. Once the sort is set, it is not obvious how to reset the active sort.

Here's a workaround you can use while we design an affordance for this in the API:

  clearSort() {
    this.sort.sort({id: '', start: 'asc', disableClear: false});
  }

https://stackblitz.com/edit/angular-8ppzzq?file=app/table-sorting-example.ts

@andrewseguin Thank you for the workaround.

@andrewseguin Let me know if I should open a new ticket but this seems related.

The whole setting a sort is quite wonky.

  1. Set a sort on a column, click clear sort. Sorting clears, sort arrows disappear. Hooray! 馃帀
  2. Update Clear Sort to actually set a sort instead: https://stackblitz.com/edit/angular-8ppzzq-wbs8qz
  3. Click Set Sort
    3.1. Table sorts by Name as specified. Hooray! 馃帀
    3.2. Column header gets no arrow letting you know how the table is sorted. 馃槥
  4. Click Set Sort again. It now sorts the Name column descending even though you're forcing it to be "asc"in your Sort object. wat? 馃槙

The issue I'm having is I can't get the arrows to show up if I ever sort programatically. My use case is that I store the user's sort to localStorage and then when they come back later I want to automatically remember their sorting. This works great but then the arrows not showing up confuses users and they click again to sort.

IMHO you should move the whole sort.sort() method to just be a constructor since it has the whole "start" name which makes it seem like it's only meant to be at initial setup. Then you should add a sort.set() that takes in the "Sort" interface that comes out of sort.sortChange that will properly let you change sorting _after_ a table is all setup and ready to go.

@rfuhrer Thanks for the feedback, I think we'll need to revisit the sort API and address some of these concerns. I am also having trouble getting the arrow to even show up correctly when programatically setting the sort.

https://stackblitz.com/edit/angular-smqz4e?file=app/table-sorting-example.ts

@andrewseguin your fix broke. nowadays you get with both (this.sort.sort(... and this.dataSource.sort.sort(... ) :

core.js:1598 ERROR
defaultErrorLogger @ core.js:1598
push../node_modules/@angular/core/fesm5/core.js.ErrorHandler.handleError @ core.js:1647
dispatchEvent @ core.js:8565
(anonymous) @ core.js:10044
schedulerFn @ core.js:3724
push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.__tryOrUnsub @ Subscriber.js:253
push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.next @ Subscriber.js:191
push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._next @ Subscriber.js:129
push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next @ Subscriber.js:93
push../node_modules/rxjs/_esm5/internal/Subject.js.Subject.next @ Subject.js:53
push../node_modules/@angular/core/fesm5/core.js.EventEmitter.emit @ core.js:3704
push../node_modules/@angular/material/esm5/sort.es5.js.MatSort.sort @ sort.es5.js:193
push../src/app/logged.in/content/routing/purchase.orders/review.table/review.table.component.ts.ReviewTable.sortData @ review.table.component.ts:175
(anonymous) @ review.table.component.html:15
handleEvent @ core.js:11107
handleEvent @ core.js:11652
dispatchEvent @ core.js:8561
(anonymous) @ core.js:10044
schedulerFn @ core.js:3724

Hi guys,

Here is my implementation for this issue.

You can control the exact sorting behavior(ASC / DESC / CLEAR) with this code.
I wrapped the logic with 'if statement' to prevent the change of 'matSort' after certain sorting behavior executed.

@ViewChild(MatSort, { static: false }) matSort: MatSort;

  sortData(id: string, start?: 'asc' | 'desc') {
    const disableClear = false;
    const currentDirection = this.matSort.direction;

    if (start === 'asc' && currentDirection !== 'asc') {
      this.matSort.sort({ id: null, start, disableClear });
      this.matSort.sort({ id, start, disableClear });
    } else if (start === 'desc' && currentDirection !== 'desc') {
      this.matSort.sort({ id: null, start, disableClear });
      this.matSort.sort({ id, start, disableClear });
    }
  }

  clearSort(id: string) {
    if (this.matSort.direction === 'asc') {
      this.matSort.sort({ id, start: 'desc', disableClear: false });
    } else if (this.matSort.direction === 'desc') {
      this.matSort.sort({ id, start: 'asc', disableClear: false });
    }
  }
md5-0bc8278cdb7f48dad04e95215b883a8c


For your info, check this out in StackBlitz

Thanks.

Hi guys,

Here is my implementation for this issue.

You can control the exact sorting behavior(ASC / DESC / CLEAR) with this code.
I wrapped the logic with 'if statement' to prevent the change of 'matSort' after certain sorting behavior executed.

@ViewChild(MatSort, { static: false }) matSort: MatSort;

  sortData(id: string, start?: 'asc' | 'desc') {
    const disableClear = false;
    const currentDirection = this.matSort.direction;

    if (start === 'asc' && currentDirection !== 'asc') {
      this.matSort.sort({ id: null, start, disableClear });
      this.matSort.sort({ id, start, disableClear });
    } else if (start === 'desc' && currentDirection !== 'desc') {
      this.matSort.sort({ id: null, start, disableClear });
      this.matSort.sort({ id, start, disableClear });
    }
  }

  clearSort(id: string) {
    if (this.matSort.direction === 'asc') {
      this.matSort.sort({ id, start: 'desc', disableClear: false });
    } else if (this.matSort.direction === 'desc') {
      this.matSort.sort({ id, start: 'asc', disableClear: false });
    }
  }
<div mat-menu-item mat-filter-item [disableRipple]="true">
      <button mat-raised-button (click)="sortData('name', 'asc')">ASC</button>
      <button mat-raised-button (click)="sortData('name', 'desc')">DESC</button>
      <button mat-raised-button (click)="clearSort('name')">Clear</button>
</div>

For your info, check this out in StackBlitz

Thanks.

Hi guys,

  1. I want to programmatically set/clear active and direction of table, but the arrow do not change.
  2. If sort the same column twice, code will run this.direction = this.getNextSortDirection(sortable);, then we may get diffrent sort result.
  3. thirst for API to get/set/clear active and direction of table(same the title of this issue).

Thanks.

Disabling sort on 3rd click is bonkers. It should be disabled by default and enabled through property disableClear=false

Hi,

I would like to know if there is any progress on this issue? It is still not possible to reset the sort to the initial state when the table is rendered for the first time, since there is strange behavior in the sort function:

  • If there is currently a column named for example name and it's sorted in desc order, if I invoke
this.matSort.sort({id: 'name', start: 'desc', disableClear: true});

What it does is change the order to the next one (in the cycle, I think), in this case it would be asc and it shouldn't behave like that, it should keep the order that I'm currently indicating in the start parameter.

The documentation for that function is not clear on that behavior:

Sets the active sort id and determines the new sort direction.

Thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jelbourn picture jelbourn  路  3Comments

3mp3ri0r picture 3mp3ri0r  路  3Comments

kara picture kara  路  3Comments

constantinlucian picture constantinlucian  路  3Comments

julianobrasil picture julianobrasil  路  3Comments