John Traxer
John Traxer

Reputation: 21

Kendo Grid Angular custom sort by one field

I need to add sorting by one field by absolute value of the value. This is my component:

<kendo-grid [kendoGridBinding]="gridData | async"
            [filterable]="true"
            [pageSize]="10"
            [pageable]="true"
            [sortable]="true"
            [height]="410">
  <kendo-grid-column *ngFor="let col of columns"
                     [field]="col.field"
                     [title]="col.title"
                     [filterable]="col.filter"
                     [filter]="col.type"
                     [format]="col.format"
                     [sortable]="col.sortable"


  ></kendo-grid-column>
</kendo-grid>

This is my component class:

export class GridComponent implements OnInit {

  gridData: any;

  columns = [
    { filter: true,  title: 'Name', field: 'name', type: 'text' },
    { filter: true,  title: 'Date', field: 'date', type: 'date', format: '{0:MM/dd/yyyy}' },
    { filter: true,  title: 'Amount', field: 'amount', type: 'numeric' , sortable: true},
    { filter: true,  title: 'Currency', field: 'currency'}
  ];

    constructor(private dataService: DataService) { }

  ngOnInit() {
    this.preloadData();
  }

  private preloadData() {
    this.gridData = this.dataService.getData();
  }
}

I tried to add instead sortable:true this:

sortable: {compare: function(a,b) { return Math.abs(a) > Math.abs(b)} }

However it tells me that this function expects boolean to be returned. So, is there a way how to implement my own comparator?

Upvotes: 2

Views: 2136

Answers (1)

yazantahhan
yazantahhan

Reputation: 3110

You will need to add a sortChange event handler and sort model:

[sort]="sort"
(sortChange)="sortChange($event)"

And handle it on the TS:

public sortChange(sort: SortDescriptor[]): void {
  this.sort = sort;
  // Custom sort if it the field is amount and there is a direction
  if (sort[0].field === "amount" && sort[0].dir) {
    this.gridData.data = this.data.sort((a, b) =>
      this.amountSortFunction(a, b, sort[0].dir)
    );
  // If it is amount field but with no direction, then do the default sorting on name
  } else if (sort[0].field === "amount") {
    this.gridData.data = orderBy(this.data, [{ field: "name", dir: "asc" }]);
  // Other fields sorting
  } else {
    this.gridData.data = orderBy(this.data, sort);
  }
}

private amountSortFunction(a, b, direction) {
  if (direction === "asc") {
    return Math.abs(a.amount) - Math.abs(b.amount);
  }
  return Math.abs(b.amount) - Math.abs(a.amount);
}

You can check a demo here

Please note that if there is a pagination from the server side, then the sorting / filtering won't work as expected, as it will be only for the same page you have and not for all data. The solution for this to implement the filtration and sorting on the server side. So if you want to sort / filter, you will send a request to the server asking him to do it, then the response will be sorted / filtered, and you will need to replace the data you have with the sorted / filtered one.

Upvotes: 1

Related Questions