we want to add a function “Copy to clipboard” to the contextmenu of a grid that
copies the text-content of the cell over which the contextmenu was opened to the clipboard.
The standard way (click,select, Ctrl+C) ist not enough in our case, because clicking also
changes the selection, and the users don’t want to click, select whole string, switch to keyboard,…
Is there an easy way to get (on the client-side) the text-content of the cell and copy it to clip board?
We already use clipboard.js for this, but not from the context-menu…
I think it would be possible with some hidden textfield in which the text-content would be copied
and than it could be put into clipboard without roundtrip to the server. This way we stay in the user event
and chrome and firefox will hopefully be fine.
But how to get the full text-content of the cell over which the context menu was opened? Is there an easy way,
e.g. by getting the content value and calling the renderer on it?
Updating this for future reference.
It’s possible to achieve this by sending the cell data to the client beforehand on context click, then accessing and copying it to the clipboard from within javascript.
Java part:
grid.addContextClickListener(e -> {
ContextMenu menu = new ContextMenu(grid, false);
MenuItem copyItem = menu.addItem("Copy", VaadinIcons.COPY, null);
copyItem.setStyleName("contextCopyItem"); // setStyleName because there is no setId for MenuItem
String cellData = ...; // fetch the cell data from the grid
cellData = java.util.Base64.getEncoder().encodeToString(cellData.getBytes("UTF-8")); // base64 to be passed to javascript
Page.getCurrent().getJavaScript().execute("sessionStorage.setItem('curCellData', '" + cellData + "')"); // make data accessible from javascript
Page.getCurrent().getJavaScript().execute("addClickListenerOnItemWithClass('contextCopyItem')"); // add a mouse click listener for the menu item
});
Then we need to define the javascript functions to handle this:
function clickHandler() {
var valBase64 = sessionStorage.getItem("curCellData");
var val = atob(valBase64);
copyTextToClipboard(val); // see http://stackoverflow.com/questions/400212/how-do-i-copy-to-the-clipboard-in-javascript
}
function addClickListenerOnItemWithClass(itemClassName) {
var v = document.getElementsByClassName(itemClassName);
if (0 < v.length) {
v[0]
.removeEventListener('click', clickHandler);
v[0]
.addEventListener('click', clickHandler);
} else {
console.error("addClickListenerOnItemWithClass: Unable to find " + itemClassName);
}
}