ag-grid sort by column A using hidden column B - ag-grid

Is there a way to sort by column A (user clicks on A column header) but under the hood use column B?
For example, I have a column "name" that displays a user's name. But then I have a column "name frequency in general population" that is hidden. I want to display the regular "name" but sort by the other column under the hood.

Create your own customer comparator and set it to your name field by using Custom Sorting.
With custom sorting, you have access to all the data in each row where you can choose what should go where.
var columnDefs = [
{ field: 'name', comparator: customComparator },
{ field: 'name frequency in general population' },
];
function customComparator(valueA, valueB, nodeA, nodeB, isInverted) {
const nodeAValue = nodeA.data['name frequency in general population'];
const nodeBValue = nodeB.data['name frequency in general population'];
return (nodeAValue > nodeBValue) ? 1 : -1;
}

Related

Using complex object for grouping in Ag Grid

I am trying to use a complex object to group my ag grid rows. Object of my rowdata looks like this -
const rowData= {
id : '123',
name: 'dummy',
category: 'A',
group : {
name : 'dummyGroup',
id : '456',
category: 'A'
}
}
Now, I am using group object to group the rows. And according to this documentation https://www.ag-grid.com/javascript-data-grid/grouping-complex-objects/ I am using keyCreator as keyCreator: params => params.value.name . My group object is uniquely identified by combination of id and catogory.
The problem that I am facing is, as I am using group.name in the keyCreator, if I have two row data object whose group.names are same but id and category are different, ag grid is grouping those rows together. I understand that this is the behavior from ag grid. So can I get any workaround for it? I need to show name on group row. But to identify the groups differently I need to use id+catogory in keyCreator. How can I achieve this ?
You need to utilise the groupRowInnerRenderer property so you can group by a combination of the id and category fields, while displaying the name as the group.
const gridOptions = {
groupDisplayType: 'groupRows',
groupRowInnerRenderer: function (params) {
return params.node.childrenAfterFilter[0].data.name;
},
columnDefs: [
{ field: 'id' },
{ field: 'name' },
{ field: 'category' },
{
field: 'group',
valueFormatter: groupValueFormatter,
rowGroup: true,
keyCreator: function (params) {
return params.value.id + params.value.category;
},
},
],
};
Demo.

sort multiple columns on Column header click in ag-grid

In documentation, sorting api i.e columns API method "applyColumnState" used for sorting multiple columns on external button click
But Can we sort multiple columns on a Column header click?
For eg, On Column A header cell click I want Column A to be sorted desencding and Column B to be sort ascending. Is this possible?
from the docs : https://www.ag-grid.com/documentation/javascript/row-sorting/#sorting-api
you can manually sort through multiple columns, one after one using the ColumnState API:
gridOptions.columnApi.applyColumnState({
state: [
{ colId: 'country', sort: 'asc', sortIndex: 0 },
{ colId: 'sport', sort: 'asc', sortIndex: 1 },
],
defaultState: { sort: null },
});
if you want to click on a header and sort an other one, you can disable sorting on the header in question, listen for the click on it an execute the above applyColumnState to manually sort.
you can listen to the click on the header by adding a listener on the .ag-header-cell class (https://stackoverflow.com/a/57812319/6641693) or simply by creating your own header component that would trigger any function you want using headerComponentFramework on the column Definition :
headerComponentFramework: (params) =>{
return (
<div>
.....
</div>
)
}

Ag-Grid Server Side Row Group Key Creator

When using Ag-Grid's server side row model, I am unable to send a custom group key to the server in order to do proper group by queries.
My row data is a simple JSON structure but with one composite object.
row = {
athlete: '',
age: '',
country: {
name: 'Ireland',
code: 'IRE'
},
...
}
I am using the server side row model. To get the grid to display the country name is simple enough as I use the following column definition.
{
headerName: "Country",
colId: "country",
valueGetter: "data.country.name",
enableRowGroup: true
}
However, when I group by the Country column ag-grid sends the groupKey as 'Ireland' from my example above. But I need the group key to be the country code, 'IRE'. I cannot figure out how to generate a groupKey when using the server-side row model.
I have seen the keyCreator method, but this only works for client-side row model. In addition, I have seen the Tree Data Mode which has a callback for getServerSideGroupKey(dataItem) but then callback only gets used when gridOptions.treeData = true and when the treeData option is set to true, a "Group" column is always displayed regardless if a grouping is happening or not. I tested this out by setting isServerSideGroup: function(dataItem) {return false;}
Any help would be appreciated.
I was able to solve this issue by using the dot notation for the column definition's field attribute and a custom cellRenderer.
{
headerName: "Country",
colId: "country",
field: "country.code",
enableRowGroup: true,
cellRenderer: function (params) {
return params.data.country.name;
}
}
This allowed me to display the correct data point from the custom object and when doing server side actions, ag-grid will send the datapoint contained within the field attribute.

ag-grid: Need to aggregate multiple fields into a table within a cell

I'm wondering what the best practice is for displaying a table (with data from multiple fields) within a cell in ag-grid?
I think I can get it to work with formatting the entire table as an html string and passing that to the grid as the field and using a cellRenderer, however I'd rather not have that kind of view logic on the server-side.
I'd really like for the column definition to be able to take in more than one field, but it doesn't seem like that's possible.
Any ideas? Thanks.
You can define a valueGetter for the desired column in column def.
Here is a sample -
valueGetter:
function sumField(params) {
return params.data.a + params.data.b
}
Value getters example
In your ColDef for the column, you can pass data and then destructure the values you're looking for off of that object, which comes through props in ag-grid.
For example...
In your ColDef array:
{
field: 'data',
headerName: 'Name',
cellRendererFramework: NameDescriptionRenderer
}
Then, in your NameDescriptionRenderer:
export default class NameDescriptionRenderer extends React.Component {
public render() {
const { description, name } = this.props.data;
return <React.Fragment>{`${name}: ${description}`}</React.Fragment>;
}
}
function fullNameGetter(params) {
return params.data.Title + ' ' + params.data.FirstName + ' ' + params.data.MiddleName + ' ' + params.data.LastName;
}
.....
{
headerName: 'Full Name',
field: 'Title&FirstName&MiddleName&LastName',
filter: true,
width: 225,
valueGetter: fullNameGetter,
},

AG-GRID Default Sort Model with Dynamic Column Defs

So I have a Grid setup that works with the Enterprise Row Model.
The columns are very dynamic and so the column defs are not known until the first query for rows is made to the server. This all works fine, but how can I set a default sort state when the column defs are not set until after the request has succeeded?
Once the grid has been set-up with the column defs you can just set the sort on any column
gridOptions.columnApi.getColumn(COLUMN_NAME).setSort("asc")
Adding a sort attribute to your colDef works too.
Example:
const columnDefs = [
{
headerName: 'Created Date',
field: 'CreateDate',
sort: 'desc',
sortingOrder: ['desc','asc'] //optional but for better sorting behaviour
}
]
Try this
const sort = [
{
colId: "firstName",
sort: "asc",
},
{
colId: "lastName"
},
];
this.gridApi.setSortModel(sort);