'Add a "Copy this row" context menu to agGrid

I would like to add a "Copy this row to the clipboard" context menu item to my agGrid (running in Angular 9).

agGrid gives us a "params" value, containing the currently selected value, and, params.node.data, which contains the "raw" entire record for this row.

getContextMenuItems(params) {
    return [
      {
        name: 'Copy this row',
        action: function() {
          let dataForThisRecord = params.node.data;

          //  ...what now...?
      },
      'export'    //  This adds the generic agGrid "export\export to Excel" menu items
    ];
}

The problem is, my params.node.data is huge, and my agGrid is actually just displaying 5 fields of this record, so I just want these 5 fields (in the same order as in the grid).

Also, some of those 5 agGrids columns might have valueGetter functions or cellRenderers, so I want to get the values after these have been called.

So, rather than exporting the raw data, which I can see in the params.node.data object:

{
   forename: 'Mike',
   surname: 'Jones',
   DOB: '2020-04-30T00:00:00',
   countryID: 1001,
   phone: '055 123 4567'
}

I want to copy the values as they are shown in the grid, after passing through any cellRenderers or valueGetters:

[ 'Mike', 'Jones', '30/4/2020', 'France', '055 123 4567' ]

Is is possible to do this ?

I assume so, as when I add a default 'export' option to my context menu, agGrid itself will happily export my data into an Excel file, containing the nicely-formatted values which are shown in the grid.



Solution 1:[1]

There is no correct way, and it cannot be, because the render returns html. Workarounds below.

Clipboard Api in deph

export interface IClipboardService {
    registerGridCore(gridCore: GridCore): void;
    pasteFromClipboard(): void;
    copyToClipboard(includeHeader?: boolean): void;
    copySelectedRowsToClipboard(includeHeader?: boolean, columnKeys?: (string | Column)[]): void;
    copySelectedRangeToClipboard(includeHeader?: boolean): void;
    copyRangeDown(): void;
}

Look at ClipboardService from enterprise. In private ClipboardService.copyFocusedCellToClipboard get value from gridOptions.processCellForClipboard.

Set gridOptions.processCellForClipboard = (params) => myLogic(params.node.data, params.column.colDef.field). Then select row as params.node.setSelected(true). Then params.api.copySelectedRowsToClipboard(false, columnKeys)

All render pipline methods in colDef, not in api but!

Formatter valueFormatterService not exists in GridApi. But valueGetter exists as params.api.getValue.

TLDR

action: function() {
   const colDef = params.column.getColDef();
   // do
   const value = colDef.valueGetter(...);
   // or do 
   const value = params.api.getValue(colDef.colId, params.node); // valueGetter
   // then
   params.api.clipboardService.copyDataToClipboard(value);
},

Warn

The first method works through selection, it’s bad, because the user will suffer.

The second method requires playing the pipeline.

In total, I came to the fact that I wrote my own handler for working with the console, so that the format in Excel and in the clipboard often do not match.

Solution 2:[2]

All you need to write is:

{
    name: 'Details for... ',
    disabled: true,
},
'separator',
'copy',
'copyWithHeaders',
'copyWithGroupHeaders',
'separator'

https://www.ag-grid.com/javascript-data-grid/context-menu/

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Nikita Fedorov
Solution 2 Harold Noble Bright