Karthik Chintala Karthik Chintala -4 years ago 222
jQuery Question

How to get the original value of a copied cell in kendo grid

How to get the underlying value when a cell is copied in kendo grid ?

I've the following code

$(document).ready(function () {

$("#cellSelection").kendoGrid({
dataSource: {
data: orders,
pageSize: 6
},
selectable: "multiple cell",
allowCopy: true,
pageable: {
buttonCount: 5
},
scrollable: false,
navigatable: true,
columns: [
{
field: "ShipCountry",
title: "Ship Country",
width: 300
},
{
field: "Freight",
width: 300
},
{
field: "OrderDate",
title: "Order Date",
format: "{0:dd/MM/yyyy}"
}
]
});

//events to capture when Ctrl + C is pressed
$("#cellSelection").bind('copy', function (e) {
var grid = $("#cellSelection").data("kendoGrid");
if (grid != null && grid.areaClipBoard != undefined) {
console.log("copied content is:");
console.log(grid.areaClipBoard.val());
}
});
});


So, when you copy a cell, the value which is visible in the cell is being copied.

Say, if the value you are copying from grid is
40.65
then only that value is copied with
allowCopy
set to true in kendo grid. But the original value as per the data source is
40.6789
. I need the original value to be copied to clipboard when ctrl + c is pressed.

I wrote the copy event as you can see, it just outputs what is copied from the grid. Is there a way I can get the underlying value when ctrl + c is pressed ?

Here is the fiddle link. Run the fiddle and open developer tools and select few cells and copy it. You should be able to see what is copied.

Answer Source

Thanks to @Cobus Kruger for your solution. Here is my complete solution.

  1. We've to loop over the selected items in the grid and get the underlying data source values and return the result.
function getTSVFormat(grid) {
    var selected = grid.select();
    var delimeter = '\t';
    var allowCopy = grid.options.allowCopy;
    var onlyVisible = true;
    if ($.isPlainObject(allowCopy) && allowCopy.delimeter) {
        delimeter = allowCopy.delimeter;
    }
    var text = '';
    if (selected.length) {
        if (selected.eq(0).is('tr')) {
            selected = selected.find('td:not(.k-group-cell)');
        }
        if (onlyVisible) {
            selected.filter(':visible');
        }
        var result = [];
        var cellsOffset = grid.columns.length;
        var lockedCols = grid._isLocked() && lockedColumns(grid.columns).length;
        var inLockedArea = true;
        $.each(selected, function (idx, cell) {
            cell = $(cell);
            var tr = cell.closest('tr');
            var rowIndex = tr.index();
            var cellIndex = cell.index();
            if (onlyVisible) {
                cellIndex -= cell.prevAll(':hidden').length;
            }
            if (lockedCols && inLockedArea) {
                inLockedArea = $.contains(grid.lockedTable[0], cell[0]);
            }
            if (grid._groups() && inLockedArea) {
                cellIndex -= grid._groups();
            }
            cellIndex = inLockedArea ? cellIndex : cellIndex + lockedCols;
            if (cellsOffset > cellIndex) {
                cellsOffset = cellIndex;
            }
            var cellText = cell.text();

            var column = grid.columns[cellIndex];
            var data = grid.dataItem(tr);
            var cellData = data[column.field];

            if (!result[rowIndex]) {
                result[rowIndex] = [];
            }
            result[rowIndex][cellIndex] = cellData;

        });
        var rowsOffset = result.length;
        result = $.each(result, function (idx, val) {
            if (val) {
                result[idx] = val.slice(cellsOffset);
                if (rowsOffset > idx) {
                    rowsOffset = idx;
                }
            }
        });
        $.each(result.slice(rowsOffset), function (idx, val) {
            if (val) {
                text += val.join(delimeter) + '\r\n';
            } else {
                text += '\r\n';
            }
        });
    }
    return text;
}

Note that I didn't write the above function on my own. I've looked into kendo.all.js file and debugged it and customized for my own purpose.

  1. After you get the copied text we've to call this in the copy event
$("#cellSelection").bind('copy', function (e) {
                    var grid = $("#cellSelection").data("kendoGrid");
                    var text = getTSVFormat(grid);

                    //add textarea if its not in yet
                    if (!grid.areaClipBoard) {
                        grid.areaClipBoard = $('<textarea />').css({
                            position: 'fixed',
                            top: '50%',
                            left: '50%',
                            opacity: 0,
                            width: 0,
                            height: 0
                        }).appendTo(grid.wrapper);
                    }

                    //overwrite the default clipboard content of kendo with our custom data source
                    grid.areaClipBoard.val(text);
                    //call copy to clipboard to copy the contents
                    copyToClipboard(text);
                });
  1. As you can see in the copy event we'll have to overwrite the contents of areaClipBoard property to have our customized text.
  2. After you copy the contents over to areaClipBoard, call copyToClipBoard with the html that you want to copy to clipboard.
function copyToClipboard(html) {
                var textarea = document.createElement('textarea');
                $(textarea).addClass('k-spreadsheet-clipboard').val(html).appendTo(document.body).focus().select();
                document.execCommand('copy');
                $(textarea).remove();
            }

That's all ! You can now paste to any excel sheet as you wish to. It will have the exact same spaces for what you've selected in the grid.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download