How to add Row Header in Ag-grid? - ag-grid

Please refer to the image shown below. (The highlighted part is the ROW header that I need in AG-Grid)

I am not sure about the functional use case of this first column for you.
Nevertheless you can achieve this by adding it to column definition as shown below.
var gridOptions = {
// define grid columns
columnDefs: [
// using default ColDef
{
headerName: ' ',
field: '__',
width: 15,
sortable: false,
cellStyle: {
// you can use either came case or dashes, the grid converts to whats needed
backgroundColor: 'lightgrey', // whatever cell color you want
},
},
...
}
Created working sample plnkr here.

As far as I know ag-grid doesn't have any built-in support for row headers, but as a workaround you can make your first column appear as row headers. I recommend making the whole column look a little different compared to the other columns (including the column header if it's not blank) so it can clearly be seen they are column headers, not standard row data.
Example column definitions:
ColumnDefs: [
{ headerName: 'Column Title 1', field: 'Column1', minWidth: 100, headerClass: "upperLeftCell", cellStyle: {
backgroundColor: 'AliceBlue', //make light blue
fontWeight: 'bold' //and bold
}
},
{ headerName: 'Column Title 2', field: 'Column2', minWidth: 100 },
{ headerName: 'Column Title 3', field: 'Column3', minWidth: 100 }
]
You can also style in SCSS as shown here with the upper left cell:
::ng-deep .ag-header-cell.upperLeftCell {
background-color: aliceblue;
font-weight: bold;
}
In your data rows: you have to enter in the first column the title you want for each row.

Add this as your first colDef. It will render a index column that is unmovable. I have a separate IndexColumnCellRender so won't look exact the same, fill in cellStyle to fit your needs, or make a dedicated cell render like me.
const rowIndexColumn: ColDef = {
valueGetter: ({ node }) => {
const rowIndex = node?.rowIndex;
return rowIndex == null ? "" : rowIndex + 1;
},
width: columnWidth,
headerName: "",
colId: "some-id",
field: "some-id",
suppressNavigable: true,
suppressPaste: true,
suppressMovable: true,
suppressAutoSize: true,
suppressMenu: true,
lockPosition: true,
cellStyle: { padding: 0 },
};

Related

AG-Grid - Any way to have a pinned column fill the remaining space of the grid?

I know that I can use the flex attribute on a column def if I want that column to take up the remaining space of a grid, like this:
public columnDefs: ColDef[] = [
{ field: 'name', flex: 1 },
{ field: 'medals.gold', headerName: 'Gold' },
{ field: 'person.age' },
];
And I know that I can pin a column to the left (or right) so that it doesn't scroll with the rest of the columns:
public columnDefs: ColDef[] = [
{ field: 'name', pinned: 'left' },
{ field: 'medals.gold', headerName: 'Gold' },
{ field: 'person.age' },
];
But I have a case where I want the first column to both be pinned AND fill the remaining space:
public columnDefs: ColDef[] = [
{ field: 'name', flex: 1, pinned: 'left' },
{ field: 'medals.gold', headerName: 'Gold' },
{ field: 'person.age' },
];
And when I do this (pinned + flex) the grid seems to ignore the flex attribute and always renders the column with the default width. I've been through the AG-Grid docs and don't see anything that explicitly says pinning and flex columns are incompatible, but maybe I'm missing it.
Here's a plunker to play with. Try removing the pinned attribute to see the flex column work.
Has anyone been able to combine these attributes on one column?
OK, I've found a solution. I'm not sure if this is a workaround, or if this is the way you're supposed to do it, so...
It was a combination of handling the gridReady event and calling Grid API api.sizeColumnsToFit().
In my case, I also set the width and suppressSizeToFit=true for the non-pinned columns.
Updated plunker.

Configure AG Grid autoGroupColumnDef to only show chevron with no excess whitespace

Does anybody have experience with configuring the autoGroupColumnDef property for AG Grid? I am simply trying to make the default Group Column for my treeData grid to only show the expand/collapse chevron (with no group text). Below is my autoGroupColumnDef config and the current visual state:
const gridOptions: GridOptions = {
treeData: true,
getDataPath: (data) => data.hierarchy as string[],
autoGroupColumnDef: {
headerName: "",
width: 30, // <-- gets completely ignored??
valueFormatter: () => "",
cellRenderer: "agGroupCellRenderer",
cellRendererParams: {
suppressCount: true,
},
},
}
As you can see, I am left with a large amount of whitespace between the chevron in the group column and the data columns despite my setting an explicit width: 30 in the config. How can I get rid of this whitespace?
Use maxWidth instead of width.

Ag-grid: how to size columns to fit contents?

Ag-grid has a sizeColumnsToFit function that sizes the columns to fit the screen, but what I want is to size the columns to fit the data. In other words I want each column's width to be the minimum required to fit its content (without truncating strings and adding ellipses) even if that means I have to scroll horizontally to see some of the columns.
The autoSizeColumns function seems to be making all the columns equal width, disregarding the width of the contents.
You can see both of these functions in the "Resizing Example" demo on this page.
For the "size to fit" option you can see truncated strings in some columns, but not the first column, presumably because it has "suppressSizeToFit: true". But adding that option to all column defs doesn't solve the problem; there's still some truncation in some columns, while others are wider than they need to be for the content.
Here's the code from that example:
const columnDefs = [
{ field: 'athlete', width: 150, suppressSizeToFit: true },
{
field: 'age',
headerName: 'Age of Athlete',
width: 90,
minWidth: 50,
maxWidth: 150,
},
{ field: 'country', width: 120 },
{ field: 'year', width: 90 },
{ field: 'date', width: 110 },
{ field: 'sport', width: 110 },
{ field: 'gold', width: 100 },
{ field: 'silver', width: 100 },
{ field: 'bronze', width: 100 },
{ field: 'total', width: 100 },
];
const gridOptions = {
defaultColDef: {
resizable: true,
},
columnDefs: columnDefs,
rowData: null,
onColumnResized: (params) => {
console.log(params);
},
};
function sizeToFit() {
gridOptions.api.sizeColumnsToFit();
}
function autoSizeAll(skipHeader) {
const allColumnIds = [];
gridOptions.columnApi.getAllColumns().forEach((column) => {
allColumnIds.push(column.getId());
});
gridOptions.columnApi.autoSizeColumns(allColumnIds, skipHeader);
}
// setup the grid after the page has finished loading
document.addEventListener('DOMContentLoaded', () => {
const gridDiv = document.querySelector('#myGrid');
new agGrid.Grid(gridDiv, gridOptions);
fetch('https://www.ag-grid.com/example-assets/olympic-winners.json')
.then((response) => response.json())
.then((data) => gridOptions.api.setRowData(data));
});
Any help?
I'm actually trying to get this working with JustPy using run_api, and I have that (sort of) working, except that the sizeColumnsToFit function doesn't do what I expected.
Most columns of my data consist of fixed-width strings (different widths, but the same width for all strings in a column), so I guess my "plan B" is to commit to a monospace font and font size and try to use trial and error to come up with a width calculation formula based on string lengths.
But sizing columns to fit data is a pretty common thing to want (isn't that what autofit does in Excel?), so I'm hoping there's a more robust solution.
I think you'll find autoSizeColumns does what you need it to.
Take a look at this demo.

agGrid with Angular, using agRichSelectCellEditor

I have an agGrid populated with Employee records in JSON format from my web service.
[
{
id: 123,
firstName: 'Mike',
lastName: 'Jones',
countryId: 1001,
DOB: '1980-01-01T00:00:00',
. . .
}
I have a second web service returning a list of country codes:
[
{ id: 1000, name: 'France' },
{ id: 1001, name: 'Spain' },
{ id: 1002, name: 'Belguim' }
]
What I'm trying to do is get my agGrid to have a column showing the user's details, including the name of their country, and when they edit this cell, a list of country codes will appear, where they can select one, and it'll update the record with the id of that country.
Basic stuff, no ?
But has anyone managed to get agGrid to successfully use the "agRichSelectCellEditor" to do this successfully ?
{ headerName: 'Country', width: 120, field: 'countryId', editable: true,
cellEditor:'agRichSelectCellEditor',
cellEditorParams: {
// This tells agGrid that when we edit the country cell, we want a popup to be displayed
// showing (just) the names of the countries in our reference data
values: listOfCountries.map(s => s.name)
},
// The "cellRenderer" tells agGrid to display the country name in each row, rather than the
// numeric countryId value
cellRenderer: (params) => listOfCountries.find(refData => refData.id == params.data.countryId)?.name,
valueSetter: function(params) {
// When we select a value from our drop down list, this function will make sure
// that our row's record receives the "id" (not the text value) of the chosen selection.
params.data.countryId = listOfCountries.find(refData => refData.name == params.newValue)?.id;
return true;
}
},
My code seems to be almost correct.. it manages to:
display the country name in each row of the agGrid
display a popup, listing the country names, from our "list of countries" array
when I select an item in the popup, it successfully updates the countryId field with the (numeric) id value of my chosen country
The only problem is that at the top of the popup, it shows the countryId value, rather than the user's current country name.
Has anyone managed to get this to work ?
The only workaround I could come up with was to override the CSS on this popup and hide that top element:
.ag-rich-select-value
{
display: none !important;
}
It works... but you no longer get to see what your previously selected value was.
(I really wish the agGrid website had some decent, real-life, working Angular examples... or at least let developers post comments on there, to help each other out.)
The solution was to use a valueGetter, rather than a cellRenderer:
{
headerName: 'Country', width: 120, field: 'countryId', editable: true,
cellEditor:'agRichSelectCellEditor',
cellEditorParams: {
// This tells agGrid that when we edit the country cell, we want a popup to be displayed
// showing (just) the names of the countries in our reference data
values: listOfCountries.map(s => s.name)
},
valueSetter: function(params) {
// When we select a value from our drop down list, this function will make sure
// that our row's record receives the "id" (not the text value) of the chosen selection.
params.data.countryId = listOfCountries.find(refData => refData.name == params.newValue)?.id;
return true;
},
valueGetter: function(params) {
// We don't want to display the raw "countryId" value.. we actually want
// the "Country Name" string for that id.
return listOfCountries.find(refData => refData.id == params.data.countryId)?.name;
}
},
I hope this is useful...
I was able to get my similar situation (id:name pairs in a list, but not using Angular though) working without the problem you mentioned above, and without a valueGetter/valueSetter and only a renderer. The benefit is that you don't need to double click the cell to see the list, the cell appears as a selection box always, and you avoid a bug should the user double click the cell when the list is displayed.
The renderer is a lot clunkier than I was wanting (one line like yours) and it didn't seem that aggrid had built in support for this pretty basic function (and I already have spent enough time on this).
Anyway, this is what I had, which at least works, but keen to see further improvements on it. (You will need to at least change 2 lines for the option related code since my defaultValue object is specific to me).
The column definition:
{field: 'defaultValueID', headerName: "Default Value", cellEditor:'agRichSelectCellEditor', cellRenderer: defaultValueRenderer}
And the renderer code:
function defaultValueRenderer(params) {
var input = document.createElement("select");
// allow it to be cleared
var option = document.createElement("option");
option.innerHTML = '[None]';
option.value = null;
input.appendChild(option);
for (var i=0; i < defaultValueList.length; i++) {
var option = document.createElement("option");
option.innerHTML = defaultValueList[i].name;
option.value = defaultValueList[i].gltID;
input.appendChild(option);
}
input.value = params.value;
input.onchange = function() {
params.setValue(this.value);
params.data.defaultValueID = this.value;
}
input.style="width: 100%; height: 100%"; // default looks too small
return input;
}
Here Is Example Of agRichSelectCellEditor...
{
headerName: 'Dropdown', field: 'dropdown',
cellEditor: 'agRichSelectCellEditor',
width: 140,
editable: true,
cellEditorParams: (params) => {
values: Get All Dropdown List Like ["Hello","Hiii","How Are You?"]
},
valueSetter: (params) => {
if (params.newValue) {
params.data.dropdown= params.newValue;
return true;
}
return false;
}
}
Much simpler solution: use cellEditorParams formatValue, along with valueFormatter
{
field: 'foo',
cellEditor: 'agRichSelectCellEditor',
cellEditorParams: {
values: [1,2,3, 4, other ids... ],
formatValue: (id: number): string => this.getLabelFromId(value)
},
valueFormatter: (params: ValueFormatterParams): string => this.getLabelFromId(params.value as number)
}

ag-grid's agSelectCellEditor doesn't render the cell correctly

I am using agSelectCellEditor to imlement a dropdown menu in a particular column cells.
This is the column definition:
{
headerName: "Rattachement",
field: "rattachement",
editable: true,
headerTooltip:
"Choisissez l'entité de rattachement parmi les choix présents dans la liste déroulante",
cellEditor: "agSelectCellEditor",
cellEditorParams: {
values: [
"",
"Audit",
"RA",
"Consulting",
"FA",
"Tax&Legal",
"ICS",
"Taj"
]
}
}
This is how ag-grid renders it:
I have to doubl-click on it in order for the dropdown list to show-up this way:
And then I can select any of the available options.
As you notice, this is really poor rendering and may cause the user to be confused and unable to use the tool that I am building.
So my question is:
Is there any way to make ag-grid show the dropdown menu from the beginnig without having to double-click on the cell so that the user actually knows what to do?
Thanks!
PS: I don't want to use a custom cell renderer, because the options in the cell depend on other variables and the whole thing may get messy if I choose to implement the dropdown list using a customcellRenderer (which I did with other columns where it doesn't cause me any of the mentioned trouble)
This is the same issue which i encountered :).
By default AgGrid doesnt show dropdown columns. If you wish to show it as a dropdown you will have to use cellRenderer just to show the image to notify user that this is dropdown column.
Double click edit can be changed to singleclick or no click edit that option is avaiable.
Set columndef option singleClickEdit : true,
var columnDefs = [
{field: 'name', width: 100},
{
field: 'gender',
width: 90,
cellRenderer: 'genderCellRenderer',
cellEditor: 'agRichSelectCellEditor',
singleClickEdit : true,
cellEditorParams: {
values: ['Male', 'Female'],
}
},]
var gridOptions = {
components: {
'genderCellRenderer': GenderCellRenderer
},
columnDefs: columnDefs,
}
function GenderCellRenderer() {
}
GenderCellRenderer.prototype.init = function (params) {
this.eGui = document.createElement('span');
this.eGui.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 18 18"><path d="M5 8l4 4 4-4z"/></svg>' + params.value;
};
GenderCellRenderer.prototype.getGui = function () {
return this.eGui;
};
DEMO
Hope this helps.