I want to send data to my cellRenderer component via the cellRendererParams object but I don't know how to access row data for this. Here's an example of what I want to do:
cellRendererParams: {
label: currentRowData.myField + currentRowData.myOtherField
}
I don't want my cellRenderer component to have knowledge of the data structure of the grid since I may use it in other grids with different row data.
there are many ways:
1)
valueGetter: (params) => ({ property1: params.data.myField1 + params.data.myField2, property2: params.data.someOtherField }),
valueFormatter: ({ property1: params.data.myField1 + params.data.myField2, property2: params.data.someOtherField }),
Try using a valueGetter, like this:
valueGetter: (params) => params.data.myField + params.data.myOtherField
Related
I have a custom column in Ag Grid which has an image and text in it.
When I export the whole table to excel I get [object] as value for the custom column.
Is there a way to export only the text from the custom column?
Project is in Angular typescript
Good day, please have a look at the docs of customising-cell-and-row-group-values
Description:
You can create custom options and describe what exact field should be passed in export with concrete value:
First look for how can create custom options
Looking for exportDataAsExcel method and ExcelExportParams
Example:
const getContextMenuItems = ({ api, ...restProps }) => {
return [
// other options
{
name: 'Export',
tooltip: 'Export',
subMenu: [
{
name: 'Excel Export',
action: () => api.exportDataAsExcel({
// other params like columnKeys e.t.c
processCellCallback: ({ column, value }) => {
// Rules for your custom cellRenderer here:
if (column.colId === 'yourCustomFieldId') {
return value.customText;
}
return value;
},
}),
},
],
},
];
};
Setup Summary: We have two aggrids where we drag from one grid to the second grid. This works perfectly.
Issue: We have some lines we don't want to enable drag on. So we want a conditional drag based on a cell value.
Currently our table settings (we use reactjs) are as follows:
Table 1 and 2 have these properties:
rowData={rowData}
ref={fileGridRef}
columnDefs={columnDefs}
gridOptions={gridOptions}
rowDragManaged={true}
rowDragEntireRow={true}
animateRows={true}
onRowDragEnd={(params: any) => addToFilesGrid(params)}
suppressClickEdit={true}
gridOptions are (for both grids)
rowSelection: "single",
rowMultiSelectWithClick: true,
Column defs are (for both grids)
{
field: "name",
headerName: "File Name",
sortable: true,
filter: true,
editable: true,
cellStyle: { textAlign: "center", marginLeft: "-10px" },
cellRenderer: EditCellRenderer,
rowDrag: (params: any) => {
params.data.type !== ""; //HERE IS THE CONDITION WE HAVE
},
},
{
field: "type",
headerName: "Type",
sortable: true,
filter: true,
editable: false,
}
When the params.data.type is "" we want it not to move.
I tried playing around with rowDragManaged=false, but then nothing moved. I thought about making handlers for onDragEnter/Leave/Move/End, but I would rather avoid that if I can.
Anyone know what the issue is?
Do I have to do unmanaged dragging if I want this to work?
Finally found a solution!
I had seen that rowDrag could be set to a conditional statement but had issues getting it working, and there is one example on ag-grid docs that wasn't helpful in my use case.
So, I have a table, and if a cell is BLANK I don't want the row to drag.
So in the ColDef I had:
rowDrag: params => params.data.type === "",
Because that is what it was in the rowData. Also when I printed out params in other row changing functions (onRowSelected, onRowDragMove, etc...) this field was an empty string -> "".
It seems like for this conditional however it may be treated as an undefined or have a space. Not exactly sure, but I was able to do this:
params => params.data.type.length > 1,
And it worked! This leads me to believe the tags in the aggrid cell or something in their code inserts a space somewhere.
This was shown when I tried
rowDrag: params => params.data.type.length > 0,
and I could still drag the rows where my type field was "".
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)
}
I have huge sets of numeric data.
this needs to be rendered as comma separated value.
For Ex.
123456.78 to be rendered as 123,457 using Ag-Grid.
Kindly help me on achieving this.
As per the cell rendering flow documentation (here), you can use the colDef.valueFormatter, like this:
var columnDefs = [
{headerName: "Number", field: "number"},
{headerName: "Formatted", field: "number", valueFormatter: currencyFormatter}
];
function currencyFormatter(params) {
return '£' + formatNumber(params.value);
}
function formatNumber(number) {
// this puts commas into the number eg 1000 goes to 1,000,
// i pulled this from stack overflow, i have no idea how it works
return Math.floor(number).toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,");
}
You could also use a cellRenderer as other posts describe, but that's typically for more complex rendering, whereas the valueFormatter is specifically for this case. From the ag-grid documentation:
valueFormatter's are for text formatting.
cellRenderer's are for when you want to include HTML markup and
potentially functionality to the cell. So for example, if you want to
put punctuation into a value, use a valueFormatter, if you want to put
buttons or HTML links use a cellRenderer. It is possible to use a
combination of both, in which case the result of the valueFormatter
will be passed to the cellRenderer.
{
headerName: 'Salary', field: 'sal'
cellRenderer: this.CurrencyCellRenderer
}
private CurrencyCellRenderer(params:any) {
var usdFormate = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 4
});
return usdFormate.format(params.value);
}
Like these we can mention in Angular2 Typescript code.
You can do this by writing a "customcellRenderer", when you create a column definition provide a function to "cellRenderer " attribute and in renderer use number filter, something like this
var colDef = {
name: 'Col Name',
field' 'Col Field',
cellRenderer: function(params) {
var eCell = document.createElement('span');
var number;
if (!param.value || !isFinite(param.value)) {
number = '';
} else {
number = $filter('number')(param.value, 0);
}
eCell.innerHTML = number;
return eCell;
}
}
I'm trying to create grid data view from ExtJS with pagination.
Actually there's no issue when I create a simple data grid.
Then I want to create a "filter/search" function using Ext Form.
It's only work for page one. Here is my Ext Form Code below :
var winFilter = Ext.create('widget.window',{
title : 'Filter',
width : 400,
height : 200,
modal : true,
closeAction : 'hide',
items : frmFilter,
layout : 'fit',
bodyPadding: 5,
buttons:[
{
text : 'Filter',
handler: function(btn){
var win = btn.up('window');
var form = win.down('form');
tempProductID = form.getForm().findField('Product_ID').getSubmitValue();
tempDescription = form.getForm().findField('Description').getSubmitValue();
store.load({
params: {
start: 0,
limit: itemsPerPage,
productid: form.getForm().findField('Product_ID').getSubmitValue(),
description: form.getForm().findField('Description').getSubmitValue()
}
});
winFilter.hide();
}
},
{
text : 'Close',
handler: function(){
winFilter.hide();
}
}
]});
for the next page, my JSON return all data without using filtering value that I used before (Product ID and Description).
Please if any advice
Thanks bud.
params (when used as an argument of load method) are applied only once. If you want to apply these params to each request you have to modify proxy extraParams property:
Ext.apply(store.proxy.extraParams, {
productid: form.getForm().findField('Product_ID').getSubmitValue(),
description: form.getForm().findField('Description').getSubmitValue()
}, {});
store.load();
Else you can use store filter method (store.remoteFilter should be set to true):
store.filter([
{property: "productid", value: form.getForm().findField('Product_ID').getSubmitValue()},
{property: "description", value: form.getForm().findField('Description').getSubmitValue()
]);
But note that the filter part of request url has different form when filter approach is used. In this case filter part looks something like ?filter=[{'property':'productid','value':2}]&limit=10.... Whereas when params approach is used url looks something like ?productid=2&limit=10.... So when filter approach is used backend should parse filter property of request.