Export custom column in Ag Grid to excel - ag-grid

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;
},
}),
},
],
},
];
};

Related

Bind CSS class of a UI5 control programatically to a model value

Is there a way to bind the class attribute of a ui5-input-template inside a sap.ui.table.Table to a model value?
What I tried so far is:
[
{
label: 'arow',
disabled: true,
class: 'myClass1',
data: [
{
value: 'rowVal1'
}
]
},
// ...
]
and
myTable.bindColumns("/columns", function (index: string, context: any) {
let indParts: string[] = index.split("-");
let ind = +indParts[indParts.length - 1];
var colLabel = context.getProperty().label;
let template = new sap.m.Input({
value: `{data/${ind}/value}`,
class: '{= ${class} }',
enabled: '{= !${disabled} && !${data/' + ind + '/disabled} }',
});
// template.addStyleClass('{class}');
// template.setClass('{class}');
let column = new sap.ui.table.Column({
label: colLabel,
width: `{width}`,
template: template,
});
return column;
});
myTable.bindRows("/rows");
It seems as if I cannot use the model binding here, only add static class values when I create the template. Is this right?
As suggested in the comment, one of the solutions is to enhance the control's set of properties with your own property to allow binding the style class.
Here is a working sample: https://embed.plnkr.co/ik9PIdHKvK8udpQt
And here a snippet from the control extension:
sap.ui.define([
"sap/m/Input",
"sap/m/InputRenderer",
], function(Input, InputRenderer) {
"use strict";
return Input.extend("demo.control.Input", {
metadata: {
properties: {
"styleClass": {
type: "string",
defaultValue: null,
bindable: true,
}
}
},
renderer: { // will be merged with the parent renderer (InputRenderer)
apiVersion: 2, // enabling semantic rendering (aka. DOM-patching)
// Implement the hook method from the parent renderer
addOuterClasses: function (oRenderManager, oInput) {
InputRenderer.addOuterClasses.apply(this, arguments);
oRenderManager
.class("demoControlInput") // Standard CSS class of demo.control.Input
.class(oInput.getStyleClass()); // Custom CSS class defined by application
},
},
});
});
As documented in the topic Extending Input Rendering, some base controls allow overwriting existing methods from the renderer. If you look at the sap.m.InputRenderer, for example, you can see that the renderer provides multiple hooks to be overwritten by subclasses such as the addOuterClasses.
And since styleClass in our customer control is a valid ManagedObject property, binding in JavaScript ("programmatically") also works:
new Input({ // required from "demo/control/Input"
// ...,
styleClass: "{= ${class}}"
});

How add menu button to ag-Grid row?

I'm using ag-Grid Enterprise Vue.
I see in the docs how to enable a "context menu" that is available by right-clicking any individual cell.
I instead would love to have a special column (pinned to the right) that has a button (maybe looking like ⚙ or ...) that opens a menu upon left-click.
How could I go about enabling this? I have found no examples in the docs.
Ag-grid Cell containing menu button is a similar question but has no answer.
From this comment on this ag-grid-enterprise issue, I was able to fork the example, and I think it will work for my situation.
The relevant code is:
var gridOptions = {
columnDefs: columnDefs,
enableRangeSelection: true,
getContextMenuItems: getContextMenuItems,
allowContextMenuWithControlKey: true,
onCellClicked: params => {
console.log(params);
if(params.column.colDef.field === '...'){
params.api.contextMenuFactory.showMenu(params.node, params.column, params.value, params.event)
}
},
onCellContextMenu: params => {
params.api.contextMenuFactory.hideActiveMenu()
}
};
function getContextMenuItems(params) {
console.log('getContextMenuItems', params);
const node = params.node;
console.log('node.id, node.rowIndex, node.data', node.id, node.rowIndex, node.data);
var result = [
{
name: `Alert 'Row ${node.rowIndex + 1}'`,
action: function() {
window.alert(`Row ${node.rowIndex + 1}`);
},
cssClasses: ['redFont', 'bold']
},
'separator',
{
name: 'Checked',
checked: true,
action: function() {
console.log('Checked Selected');
},
icon: '<img src="../images/skills/mac.png"/>'
},
'copy' // built in copy item
];
return result;
}

How to use Gantt Chart with OData model instead of JSON

I am trying to use the Gantt Chart with Tree Table with an OData model. Unfortunately, I can only find examples with JSON model. I have built the hierarchy in my OData model like in the example https://blogs.sap.com/2015/10/23/treetable-odata-binding/ - I used the annotation option.
The Tree Table seems to be correct but the shapes in the Gantt do not fit to the start end end date in the related row. In the JSON examples always stands "children" at the property "shapeDataName" but I don't know what I have to write there using OData. Can somebody help?
Here you can see the structure of my OData model if I call it in the browser:
In my onInit method I did the following:
To build the shapes I wrote the following method:
My result Looks like this:
my onInit method looks like this:
onInit: function () {
var oGantt = new sap.gantt.GanttChartContainer({ ganttCharts: [
new sap.gantt.GanttChartWithTable({
id: "gantt",
columns: [ new sap.ui.table.Column({ label: "Id", template: "Aufgabenid" }),
new sap.ui.table.Column({ label: "Bezeichnung", template: "Aufgabenbez" }),
new sap.ui.table.Column({ label: "Start", template: new sap.m.DatePicker({ value: {path: "Berstartstring"}, valueFormat: "yyyyMMdd" }) }),
new sap.ui.table.Column({ label: "Ende", template: new sap.m.DatePicker({ value: {path: "Berendestring"}, valueFormat: "yyyyMMdd" }) })
],
rowSettingsTemplate: new sap.gantt.simple.GanttRowSettings( {rowId: "{Aufgabenid}" })
})
]});
var oGanttTable = oGantt.getGanttCharts()[0],
sServiceUrl = "/sap/opu/odata/sap/Z_PPM_Projekt_SRV/",
oModel = new sap.ui.model.odata.v2.ODataModel(sServiceUrl);
oGantt.setModel(oModel);
oGanttTable.bindRows({
path : "/TimingAnnoSet",
parameters: {
operationMode: "Server",
numberOfExpandedLevels: 0
}
});
oGanttTable.setShapeDataNames(["top"]);
oGanttTable.setShapes(this.configShape());
oGantt.placeAt("content");}
And here my configShape method as code:
configShape: function () {
var aShapes = [];
Rectangle.extend("sap.gantt.ppm.Rectangle", {
getFill: function(oRawData) {
switch (oRawData.Hierarchie) {
case "0":
return "black";
case "1":
return "#FF9999";
default:
return "#FAC364";
}
}
});
var oTopShape = new sap.gantt.config.Shape({
key: "top",
shapeDataName: "metadata",
shapeClassName: "sap.gantt.ppm.Rectangle",
level: 1,
shapeProperties: {
time: "{Berstartstring}",
endTime: "{Berendestring}",
height: 20,
isDuration: true,
enableDnD: true
}
});
aShapes = [oTopShape];
return aShapes;
}

actioncolumn xtype column header is showing Actions in column hide/show list

In EXT JS grid, for column with xtype: actioncolumn, the column header is not showing up in show/hide column list. It comes up as 'Actions' by default for actioncolumn column.
Can we override actual column header in the list of columns to show/hide for actioncolumn columns? Image shows a screenshow of examples from sencha examples.
If you want change the Label in Columns, You need to use a config called menuText for actioncolumn
Example: (https://fiddle.sencha.com/#fiddle/1944)
{
xtype:'actioncolumn',
width:50,
menuText: 'My Actions',
items: [{
icon: 'extjs-build/examples/shared/icons/fam/cog_edit.png', // Use a URL in the icon config
tooltip: 'Edit',
handler: function(grid, rowIndex, colIndex) {
var rec = grid.getStore().getAt(rowIndex);
alert("Edit " + rec.get('firstname'));
}
},{
icon: 'extjs-build/examples/restful/images/delete.png',
tooltip: 'Delete',
handler: function(grid, rowIndex, colIndex) {
var rec = grid.getStore().getAt(rowIndex);
alert("Terminate " + rec.get('firstname'));
}
}]
}

Ag-Grid: Number Formatting eg:123456.78 to 123,457

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