How to disable multi sort on specific column (single column sort should be enabled) [AG grid]

Viewed 182
5 Answers

What I understood is

  1. When the age column is selected, multisort should be disabled
  2. When other columns are sorted, the age column should be disabled for multisort
  3. Age column should always be available for single sort Is it right understanding?

You can achieve the above behavior by using a combination of events on grid onSortChanged and keyup/keydown event. And update the sortable property of columnDef using api.setColumnDef(columnDefs) method.

Rough Logic for updateColumnDef

Basically this logic changes sortable property of columnDefs

  1. Separately keep a track of Ctrl button is pressed logic
  2. when no Ctrl button is pressed then Keep all columns sortable: true
  3. when Ctrl + age column is not sorted then mark age column sortable: false
  4. when Ctrl + age column selected then Keep other columns sortable: false

trackCtrlKey

@HostListener('document:keyup', ['$event'])
@HostListener('document:keydown', ['$event'])
trackCtrlKey(event) {
  if (this.isCtrl === event.ctrlKey) {
    return;
  }
  this.isCtrl = event.ctrlKey;
  this.updateColDef();
}

Register onSortChanged event using gridOptions attribute

gridOptions = {
 onSortChanged: (e) => {
   this.updateColDef();
 },
};

updateColumnDef

updateColDef() {
  const columnDefs = this.grid.columnApi.columnModel.getColumnDefs();
  const displayedColumns = this.grid.columnApi.columnModel.displayedColumns;
  const sortedColumns = displayedColumns.filter((col) => !!col.sort);
  const isAgeSorted = sortedColumns.find((col) => col.colId === 'age');
  // Keep all column sortable
  // 1. no Ctrl
  if (!this.isCtrl) {
    columnDefs.forEach((colDef) => (colDef.sortable = true));
  } else 
  if ((this.isCtrl && !isAgeSorted)) {
    // 2. Ctrl + age is not sorted
    const ageColumn = columnDefs.find((col) => col.colId === 'age');
    ageColumn.sortable = false;
  } else 
  // Keep other column sortable = false when
  // 1. Ctrl + age column selected
  if (this.isCtrl && isAgeSorted){
    columnDefs.forEach((colDef) => (colDef.sortable = colDef.colId === 'age'));
  }
  this.grid.columnApi.columnModel.setColumnDefs(columnDefs);
}

Whoa!! if everything is wired together, it works as expected. It was nice learning to solve this issue.

Working Plunker

It is enough to disable the sortable option for that column by setting sortable=false:

[
{
"field":"Athlete",
"sortable":true
},
**{
"field":"Age",
"sortable":false
},**
{
"field":"Country",
"sortable":true
}
...
...
]

In the file app.component.ts you can do it like this:


  public columnDefs: ColDef[] = [
    ...
    { field: 'age', width: 100, sortable:false},
    ....
  ];

I tested it with your app and it's working like you asked in your question.

Since sortable parameter is accepting only a boolean and not a callback function, you have to implement your own custom header. Have a look at this documentation, your onSortRequest method should implement your own logic such:

onSortRequested(order: string, event: any) {
    const sortModel = this.columnsApi.getColumnState();
    const allSorted = sortModel.filter(el=>el.sort!=null);
    const suppressAgeSorting = allSorted.length>0;
    if(suppressAgeSorting) //override default sort parameters before applying set sort
        this.params.setSort(order, event.shiftKey);
}

You can use the below code for ag-grid

// enable sorting on 'name' and 'age' columns only
this.columnDefs = [
    { field: 'name', sortable: true },
    { field: 'age', sortable: true },
    { field: 'address' },
];

// disable sorting on 'name' and 'age' columns only
this.columnDefs = [
    { field: 'name', sortable: false},
    { field: 'age', sortable: false },
    { field: 'address' },
];

ag-grid official website documents with below link

https://www.ag-grid.com/angular-data-grid/row-sorting/

I think its:

[
{
"field":"Athlete",
"sortable":false
},
**{
"field":"Age",
"sortable":false
},**
{
"field":"Country",
"sortable":false
}
...
...
]
Related