Cursor Position for New Rich Text Element

I was able to successfully use the following code snippet to get the cursor index from the regular text input:

return document.getElementById(‘input’).selectionStart

This isn’t working for the new rich text element. Anyone have any ideas?

1 Like

You can try using this Window.getSelection() - Web APIs | MDN

That doesn’t seem to work for me. Did you get it to work for you?

What did you try?

it does return an object that should have the info you need. See the docs and follow the links to see the properties of the object.

Also check that you are getting the right window, see Upload a file to Xano with custom JavaScript - WeWeb error - #10 by dorilama

I tried using an OnChange workflow trigger on the rich text element, and setting an object variable to window.getSelection()

Clearly, that’s not the way to go! Should I be selecting the rich text element specifically?

It looks like the onChange event is not triggered by the rich text input.

Have you tried triggering the workflow onKeyup?

Yes, I tried using the Keyboard Listener wrapper around the rich text and using key up to do the same thing, but this didn’t work either.

are you testing in preview mode?

the window object is different in preview and edit mode because the script is executed in different contexts.

I tried it in both and it didn’t work in either

It does not work if you try to assign the Selection object to a variable. Try assigning just the values you need (eg. the offset) to a number variable.

Of course this gives you just the offset in the current element. It is enough if you just have a line without text formatting.
Because text formatting adds html tags to the element the offset will be referring to the offset in the current child.
If you want the total position from the beginning you need to implement your own code to include the other created tags and calculate it.
If you need to position something you may just be good with the offset and the current element (they are both in the Selection object)

Thanks @dorilama that definitely helped. The final hurdle, as you implied in your post, is the total position from the beginning, given other tags.

Here is a loom showing where I am now in the process:
Slash Command Testing

That is the hurdle indeed.

If you see the apps that are using the “slash command” ui pattern (notion, dashibase) they do not insert content with it but they add a new block to the document instead. A more simple use case for this ui pattern.

If you google around you can find many topics about modifying the content of a rich text with contenteditable. At the end you will need to parse the elements, calculate the position, change the html of the elements and set back the caret position. You will need to check that you are not introducing vulnerabilities, that it is actually working in all the browsers and that in the end you are not messing up with the weweb rich editor.

A very basic way you can explore (I’m just thinking about it so you need to check if it can actually work) is:

  • get the selection window.getSelection()
  • get focusNode from the selection
  • if focusNode.innerText is undefined get focusNode.parentElement
  • replace the innerText of this element with what you want. Replacing the innerText is safe if not done on script tags
    Now check if the rich text input liked what you did.
    Also now your caret position is not correct anymore, you can follow one of the guide online to calculate the position before you change anything and set it back again.

Usually this is better done as a plugin or extension for the rich text editor library that is used. For example the tiptap editor has a way to create extensions so that you can work with the already existing features of the library.

@weweb-team - how does this work for the built-in mentions function?

Hi, we use the suggestion utility provided by the TipTap library, combined with the Mention extension.

I looked at the library issues and find out a thread of someone having the same struggle as you here.
Indeed, the library offer a way to retrieve the cursor position but I tested it and as mentioned before, the issue remain because the cursor position will not be relative to the html (including all tags) so its will not help you in the replacement step.

I think the easiest way to resolve your issue could be to use the mention as command. You can set the char as “/” and provide your list of command, then you will be able to found the command node added in the html and replace it.

You can also decide to provide only “/command” and keep your current flow (with the custom command list you have)

2 drawbacks :

  • You can’t use both mentions and your commands in the same rich text, but I think we can improve the rich text and allow users to implement multiple suggestions types instead of only one (mentions)
  • Not the same UX

BTW, well done for what you accomplished with your current solution!

Edit : Oh, and we are aware of the issue with the onChange, we have similar issue on the multiselect and select input, should be fixed for the next release (early next week hopefully)

1 Like

I played a bit with it and you can actually insert text in the rich text input and keep the cursor at the right point.
Here is the result:

It works also inside styled text:

Because it is not an extension to the text editor it has some limitation:

  • only insert text in the tag where the cursor is.
  • needs to change focus in another element to have keyboard events not interfering with the text editor

Of course an extension to the text editor is still the best way to go.

Wait… how did you do this?!?

1 Like

more and less as I described in my previous post.
I used textContent to insert the text instead of changing the innerHTML of the parent.
I added a dynamic positioning for the command ui. For this example it’s only a naive positioning, but you can add smarter calculations to avoid edge cases (eg. overflow of the dialog).
Then the cursor is positioned back to the right place using the info of getSelection

Could you show what the workflow looks like? Are you using the mentions feature of the weweb rich text element, or something else?

Using the @-mention feature of the text editor is the safest method but, as Alexis said, the ux is different.

In this example I’m not using the @-mention feature because I wanted to test the original ux you aimed to.
I’m using a logic similar to what I described in the previous post.

I’m going to make a tutorial as soon as I have some time.