Getting user selected text from client div or component (DOM onselect event

Hey all,

Anyone have an example of getting selected text from Div or Span (or any component) in Vaadin 14?

Use case:
I have some text in a component, in this case in a panel in a SplitLayout. In large text, users want to highlight (e.g. text select via mouse) and then click a button someone on the page that takes the selected text (in a component) and uses that selected text for something.

Implementation idea:

For a specific component, I’d like to add a “onselect” [@DomEvent]
(https://vaadin.com/docs/v14/flow/creating-components/tutorial-component-events.html#firing-events-from-the-client) listener and have the server store the selected text (assuming the event sends the selected text to the server) in a String or something. When the user clicks a button (for example) I could then take the stored String and do something with it.

Any other suggested ways or examples of doing this?

I’ll give this approach a go but wondering if anyone has done something similar that could offer any tips / advice or any alternative approaches.

Cheers.

I would try a executeJS callback, something like this https://stackoverflow.com/a/5379408/3608089 from a UI.getCurrent().getPage().executeJS("[JS snippet that returns a String here] ").then(String.class, string -> { /* event handling with the return value */} )

Thanks Olli,

I did get something working using a @ClientCallable method with some JS executed on attach that listened to a select event and then returned document.getSelection().toString() to the server’s @ClientCallable method.

In essence very similar to your suggestion.

Thanks again.

Good to hear you got it working!

For others’ benefit, this turned out to be relatively straightforward.

In your View (e.g. MyView extends Div) add a @ClientCallable method, e.g.:

@ClientCallable
public void receiveSelectedText(String text) {
	System.out.println(text);
}

then override the onAttach(...) method with something like:

@Override
protected void onAttach(AttachEvent attachEvent) {

	getElement().executeJs(
			"document.addEventListener('selectionchange', () => {\n" + 
			"    $0.$server.receiveSelectedText(document.getSelection().toString());\n" + 
			"});",	getElement());
}

The getElement() object is passed into the javascript snippet as $0. This allows the client to access the server-side @ClientCallable method.

That’s it. Now when a user selects some text it will pass that text to the server by calling the servers’ receiveSelectedText method.