sort multiple columns on Column header click in ag-grid - 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>
)
}

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.

ag-grid sort by column A using hidden column B

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;
}

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 enterprise server side how to set agSetColumnFilter filter checkboxes

I am using ag-grid enterprise 20.2 using server side and have a column where I would like to use the agSetColumnFilter filter type. The column and filter display fine, but when I go to check a filter checkbox it returns from filterModel empty and no checkboxes are changed.
{
headerName: 'header,
field: 'field',
width: 150,
filter: 'agSetColumnFilter',
filterParams: {
values: (valuesParams) => {
const values = Object.entries(field_values).map(e => e[1].id);
valuesParams.success(values);
},
},
},
I am guessing that there is a callback or something to update the filter (setModel?), but I have not been able to sort out what the API is. Could someone let me know how to do this?
This looks to be a bug in the software. I changed to rowModelType="infinite" leaving almost everything else the same and it now works.

JQGrid Dynamic Select Data

I have utilised the example code at Example Code at this link
and I have got my grid to show a dynamically constructed select dropdown on add and edit. However when it is just showing the data in the grid it shows the dropdown index instead of its associated data. Is there a way to get the grid to show the data associated with the index instead of the index itself.
e.g. the data on my select could be "0:Hello;1:World"; The drop down on the edit/add window is showing Hello and World and has the correct indexes for them. If the cell has a value of 1 I would expect it to show World in the grid itself but it is showing 1 instead.
Here is the row itself from my grid:
{ name: 'picklist', index: 'picklist', width: 80, sortable: true, editable: true,
edittype: "select", formatter: "select", editrules: { required: true} },
I am filling the dynamic data content in the loadComplete event as follows:
$('#mygrid').setColProp('picklist', { editoptions: { value: picklistdata} });
picklist data is a string of "0:Hello;1:World" type value pairs.
Please can anyone offer any help. I am fairly new to JQGrids so please could you also include examples.
I know you have already solved the problem but I faced the same problem in my project and would like to offer my solution.
First, I declare a custom formatter for my select column (in this case, the 'username' column).
$.extend($.fn.fmatter, {
selectuser: function(cellvalue, options, rowdata) {
var userdata;
$.ajax({
url:'dropdowns/json/user',
async:false,
dataType:'json',
cache:true,
success: function(data) {
userdata = data;
}
});
return typeof cellvalue != 'undefined' ? userdata[cellvalue] : cellvalue ;
}
});
This formatter loads up the mapping of id and user in this case, and returns the username for the particular cellvalue. Then, I set the formatter:'selectuser' option to the column's colModel, and it works.
Of course, this does one json request per row displayed in the grid. I solved this problem by setting 10 seconds of caching to the headers of my json responses, like so:
private function set_caching($seconds_to_cache = 10) {
$ts = gmdate("D, d M Y H:i:s", time() + $seconds_to_cache) . " GMT";
header("Expires: $ts");
header("Pragma: cache");
header("Cache-Control: max-age=$seconds_to_cache");
}
I know this solution is not perfect, but it was adequate for my application. Cache hits are served by the browser instantly and the grid flows smoothly. Ultimately, I hope the built-in select formatter will be fixed to work with json data.
If you save in jqGrid ids of the select elements and want to show the corresponding textes then you should use formatter:'select' in the colModel (see http://www.trirand.com/jqgridwiki/doku.php?id=wiki:predefined_formatter#formatter_type_select) together with the edittype: "select".
The Usage of stype: 'select' could be also interesting for you if you plan to support data searching.