javascript - ag-grid row sorting for custom cellRenderer data


Keywords:javascript 


Question: 

I'm, trying to implement column sorting on cell data that contains custom HTML, so I'm presuming that I need to implement a custom function to override the normal sorting routine and point it to the raw values rather than the HTML rendered output.

I'm not able to gather from the ag-grid documentation how I do this, I see which describes a solution to my problem, but the explanation and sample code aren't helping me figure this out. It looks like I need a comparator, but in their example about dateComparator, it's not clear how the parameters (date1, date2) are being fed into the custom function.

I've added some sample code below to show the issue, including a comparator function which is called when pressing the column header to sort the rows.

var columnDefs = [{ field: 'rank' }, { headerName: 'custom', cellRenderer: customCellRenderer, comparator: customNumberComparator }];

var rowData = [{ 'rank': 1, 'customData': '3.64' }, { 'rank': 2, 'customData': '-1.56' }, { 'rank': 3, 'customData': '11.21' }, { 'rank': 4, 'customData': '0.36' }, { 'rank': 5, 'customData': '45.1' }, { 'rank': 6, 'customData': '-34.2' }];

function customCellRenderer () {}

customCellRenderer.prototype.init = function ( params ) {
    this.eGui = document.createElement ( 'span' );
    this.eGui.textContent = params.data.customData + '%';

    if ( parseFloat( params.data.customData ) < 0 ) {
        this.eGui.setAttribute( 'style', 'color: red');
    } else {
        this.eGui.setAttribute( 'style', 'color: green');
    }
}

customCellRenderer.prototype.getGui = function () {
    return this.eGui;
}

// TEST FUNCTION TO OUTPUT params data
function customNumberComparator ( params ) {
  const log = document.getElementById('log');
  
  if (params === undefined ) {
      log.textContent = 'undefined';
    } else {
      log.textContent = params.data;
    }
}

var gridOptions = {
    columnDefs: columnDefs,
    rowData: rowData,
    enableSorting: true
}

document.addEventListener("DOMContentLoaded", function() {
    // lookup the container we want the Grid to use
    var eGridDiv = document.querySelector('#myGrid');

    // create the grid passing in the div to use together with the columns & data we want to use
    new agGrid.Grid(eGridDiv, gridOptions);
});
<script src=""></script>

<div id="myGrid" style="height: 150px;width:500px" class="ag-theme-fresh"></div>

<span id="log">customNumberComparator output here</span>

1 Answer: 

To answer my own question:

The solution is within valueGetter property of the column definition, which is a custom function call to provide the cells with a value which sort can use.

I've added code below to show that adding valueGetter: PercentValueGetter to the columnDefs, then a PercentValueGetter function, which is called when the

There's also valueSetter valueFormatter and valueParser to allow for further customisation.

var columnDefs = [{ field: 'rank' }, { headerName: 'custom', cellRenderer: customCellRenderer, valueGetter: PercentValueGetter }];

var rowData = [{ 'rank': 1, 'customData': '3.64' }, { 'rank': 2, 'customData': '-1.56' }, { 'rank': 3, 'customData': '11.21' }, { 'rank': 4, 'customData': '0.36' }, { 'rank': 5, 'customData': '45.1' }, { 'rank': 6, 'customData': '-34.2' }];

function customCellRenderer () {}

customCellRenderer.prototype.init = function ( params ) {
    this.eGui = document.createElement ( 'span' );
    this.eGui.textContent = params.data.customData + '%';

    if ( parseFloat( params.data.customData ) < 0 ) {
        this.eGui.setAttribute( 'style', 'color: red');
    } else {
        this.eGui.setAttribute( 'style', 'color: green');
    }
}

customCellRenderer.prototype.getGui = function () {
    return this.eGui;
}

function PercentValueGetter ( params ) {
  return params.data.customData;
}

var gridOptions = {
    columnDefs: columnDefs,
    rowData: rowData,
    enableSorting: true
}

document.addEventListener("DOMContentLoaded", function() {
    // lookup the container we want the Grid to use
    var eGridDiv = document.querySelector('#myGrid');

    // create the grid passing in the div to use together with the columns & data we want to use
    new agGrid.Grid(eGridDiv, gridOptions);
});
<script src=""></script>

<div id="myGrid" style="height: 150px;width:500px" class="ag-theme-fresh"></div>