ContextMenu in Grid - How to copy text from cell to clipboard?

Hi,

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?

Every idea is welcome!

Regards
Benjamin

This is not so trivial at it may sound to get it work with most browsers.

Simplest case is IE11/Edge, where you can just do simple JavaScript call from menu event, and it will work.

For more generic solution, you need to get this linked to user event (otherwise e.g. Chrome does not allow this). This add-on does integrate
clipboard.js
with button
https://github.com/vaadin4qbanos/vaadin-jsclipboard-addon
.

In theory it should be possible to do the same with context menu as well.

Hi Tatu,

yes, clipboard access is not trivial at all :-/

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?

Regards
Benjamin

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