appsmithorg / appsmith

Platform to build admin panels, internal tools, and dashboards. Integrates with 25+ databases and any API.
https://www.appsmith.com
Apache License 2.0
34.11k stars 3.69k forks source link

[Feature] User needs ability to get selected text #7076

Open vnodecg opened 3 years ago

vnodecg commented 3 years ago

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

Nikhil-Nandagopal commented 3 years ago

@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

vnodecg commented 3 years ago

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

Nikhil-Nandagopal commented 3 years ago

@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

vnodecg commented 3 years ago

@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.

Nikhil-Nandagopal commented 3 years ago

@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}}

vnodecg commented 3 years ago

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

somangshu commented 3 years ago

Dev Note:

GreenFlux commented 3 years ago

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 !

Nikhil-Nandagopal commented 3 years ago

@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}}

GreenFlux commented 3 years ago

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

SatishGandham commented 3 years ago

@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?

Nikhil-Nandagopal commented 3 years ago

@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.

SatishGandham commented 3 years ago

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.

Nikhil-Nandagopal commented 3 years ago

@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
SatishGandham commented 3 years ago

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.

GreenFlux commented 3 years ago

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.

Nikhil-Nandagopal commented 3 years ago

@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:

SatishGandham commented 3 years ago

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

Nikhil-Nandagopal commented 3 years ago

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

micrem73 commented 1 year ago

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