appsmith icon indicating copy to clipboard operation
appsmith copied to clipboard

[Feature] User needs ability to get selected text

Open vnodecg opened this issue 3 years ago • 20 comments

Summary

We should make window.getSelection() api available to the appsmith developer. There are several use cases where user might need the selected text.

User request: image

Front logo Front conversations

vnodecg avatar Sep 03 '21 01:09 vnodecg

@vnodecg actually I think the request is to access the selected text inside an Input in this case right? Doesn't seem related to a JS Editor

Nikhil-Nandagopal avatar Sep 03 '21 07:09 Nikhil-Nandagopal

Web APIs https://developer.mozilla.org/en-US/docs/Web/API/Window/getSelection give selection for window. Its not bound to any input. Isn't it easier to provide support for this?

When I say JS editor I mean any CodeMirror instance. We need a method similar to showAlert

vnodecg avatar Sep 03 '21 08:09 vnodecg

@vnodecg the user doesn't seem like they need access to text selected in code mirror which is used in the property pane. They need access to the text selected by their users on the canvas which is the input widget

Nikhil-Nandagopal avatar Sep 03 '21 09:09 Nikhil-Nandagopal

@Nikhil-Nandagopal Yes. I was saying the we should make it an autocomplete item similar to showAlert() function. This would ensure the developer has a way get the text selected by end user.

vnodecg avatar Sep 03 '21 12:09 vnodecg

@vnodecg but showAlert is an action while onTextSelected is an event like onClick. It can be also exposed as a property in the Input like {{Input1.selectedText}}

Nikhil-Nandagopal avatar Sep 03 '21 12:09 Nikhil-Nandagopal

That works too. I was trying to stick to web standards. similar to window.getSelection

vnodecg avatar Sep 06 '21 07:09 vnodecg

Dev Note:

  • We will expose an api in the input widget > {{input.selectedText}}
  • We will introduce an action onTextSelection to trigger an event

somangshu avatar Sep 20 '21 15:09 somangshu

Thanks @somangshu , this will be a huge help on my current project. I was the one that requested the feature in Discord.

Would it be possible to add this as property to the appsmith.or user. object instead of inside each widget? I know that's different than the original request but I think this would be easier to utilize.

Otherwise, I would have to check multiple input widgets to see which one has an active selection. It would be more convenient to check a single place to find the name of the selected widget and the selectedText.

Something like this would be perfect for my use case:

appsmith.user.selectedText =

{
  "widgetName": "Input1",
  "activeSelection": "appsmith",
  "cursorStart": 0,
  "cursorEnd": 8
}

I don't necessarily need the activeSelection in text if I have the cursorStart and cursorEnd. But I definitely need the start to differentiate between multiple occurrences of the same substring in the Input.

Thank you for working on this, @somangshu !

GreenFlux avatar Sep 20 '21 15:09 GreenFlux

@GreenFlux that wouldn't be a great solve because it doesn't mimic how this would work in react.

Here my suggestion is to store the value in a common location that you find convenient onTextSelect: {{ storeValue('changedText', Input1.selectedText) }} and read it from this location as {{appsmith.store.changedText}}

Nikhil-Nandagopal avatar Sep 20 '21 16:09 Nikhil-Nandagopal

@Nikhil-Nandagopal , that would work fine as well. Thanks for your help on this.

GreenFlux avatar Sep 20 '21 16:09 GreenFlux

@Nikhil-Nandagopal

Here my suggestion is to store the value in a common location that you find convenient onTextSelect: {{ storeValue('changedText', Input1.selectedText) }} and read it from this location as {{appsmith.store.changedText}}

User would have to add this on every input right? Since there can be only one single text, wouldn't exposing a method or storing it in the global store( we have to remember to clear it) be more convenient? Also, can a user implement this on their own with JSObjects?

SatishGandham avatar Oct 05 '21 05:10 SatishGandham

@SatishGandham yes they would have to add it to every input only in the case that they want to store all of this in a commonplace. Otherwise, it will be accessible as Input1.selectedText which is also a global store of sorts. The actual store i.e appsmith.store should only be used for values users explicitly store in it. All internal properties are by default saved in the widgets. It's hard to justify why this property alone should be in the appsmith.store and not all the properties that we have in every widget.

Nikhil-Nandagopal avatar Oct 05 '21 06:10 Nikhil-Nandagopal

This property is different because there is only one selected text across the page. Since we don't expose window, we should expose a method to get the selected text.

The linked PR does the change only on the input widget, if it's going to be a widget property, it should be done for rich text editor as well.

SatishGandham avatar Oct 05 '21 07:10 SatishGandham

@SatishGandham that doesn't seem to be true. Looks like there can be multiple selected text per input (refer image). In web development does the window expose the selected text directly?

agreed that it should be for rich text editor as well. @techbhavin

Screenshot 2021-10-05 at 12 57 56 PM

Nikhil-Nandagopal avatar Oct 05 '21 07:10 Nikhil-Nandagopal

The selection in rich text editor may be its own implementation by the component as it uses that info formatting. I'm unable to get multiple selections.

We can use window.getSelection().toString() to get the actual selection.

SatishGandham avatar Oct 05 '21 09:10 SatishGandham

Looks like there can be multiple selected text per input (refer image).

I noticed this as well. I'm using window.getSelection() in a sample file to test. It seems that there can only be one selection at a time for the entire page, but RTEs are the exception.

RTEs maintain their own, single selection per widget. So every RTE on the page can have a single selection without deactivating other selections. But aside from RTEs there can only be a single selection per page and every new selection deactivates the old one.

When you use window.getSelection().toString(), the selection object returns the selected text only, and the rest of the object properties are lost.

Would it be possible to expose the entire selection object so we can also access the cursor position? These values are needed to distinguish between multiple occurrences of the same substring in the main text that has been selected.

GreenFlux avatar Oct 05 '21 10:10 GreenFlux

@SatishGandham @GreenFlux Got it! I missed that this was already part of the web API and that was why I was confused by this request. So to sum it up:

  • we should expose appsmith.getSelection() which will return the selection object
  • the RTE should have a selectedText attribute that may not populate the appsmith.getSelection() object
  • the input can optionally have a selectedText attribute as well

Nikhil-Nandagopal avatar Oct 05 '21 11:10 Nikhil-Nandagopal

@Nikhil-Nandagopal , We should not have input.selectedText if appsmith.getSelection() does this job. Otherwise this will be expected in all similar widgets.

SatishGandham avatar Oct 06 '21 05:10 SatishGandham

@SatishGandham in light of neither ant design nor blueprint exposing this in the widget, I agree with you here!

Nikhil-Nandagopal avatar Oct 06 '21 16:10 Nikhil-Nandagopal

Hi, don't know if a side effect of this FR could solve my issue. I wish to get all the text before the cursor, and all the text after the cursor, when no selection is done, but the cursor is simply in the middle of already inputted text. Having these properties already exposed would be great; but having just cursor position could be enough, to calculate them via javascript. As I see here cursor position is mentioned, I wonder if cursor position could be exposed whenever it changes; both when a selection is done, and when it is not. regards michele

micrem73 avatar Nov 28 '22 19:11 micrem73