
I tried reading the DOM spec but I didn’t find it as helpful.

It started making sense after I read it a few times and then checked the MDN links above again and played around etc. So I decided to dig directly into the W3C standards myself. I eventually got tired of the try, fail, google, curse, try, fail, curse some more routine. If you are working on a similar project and need the cursor to go to the end like this, then you know what a pain it was to get this figured out. Notice the user can enter a hashtag at the beginning and when they choose enter the cursor moves to the end.

This pretty much works exactly how I wanted it to work. In the video below you can see what I want and what I have gotten working so far. Yeah you need that so that when a user types into input or contenteditable divs it doesn’t drop it’s own suggestion list over your suggestion list, it really makes things a mess.
#CONTENTEDITABLE GET PLAIN TEXT CODE#
If you are wondering how I make these cool code images, you need to checkout this carbon app.īelow is the actual div and some sample hashtags I pulled from the developers console. I don’t like that I have to add the invisible space tag to make the contenteditable act right, but what can we do? Ok so now I have these hashtags displaying correctly. So I adjusted it to be just the span with a following nbsp tag like this. I also discovered that you must add contenteditable=false to each element within the parent element so that when the user clicks, the cursor doesn’t appear inside some randomish point instead of at the end of the content. But then I was like, most people will just backspace and if they are on their phone no way they can accurately touch it. My first idea was to have a hashtag with an x to remove it. I moved to just a simple span element with added to the end. I was using divs, with spans inside them. This repeats until there are no hashtags. So now when the user backspaces, the first backspace does nothing, but the next removes the hashtag. I decided to use nbsp because it is seen as a #text node not a text element like p for example. Some people add an empty paragraph from what I read. Explained in depth in this great article. I fixed this by adding which is html for non breaking space. One stupid, nonsensical issue I ran into right away was when the user hit backspace instead of one letter or hashtag being removed, ALL CONTENT WAS REMOVED. If you are reading this you probably have done all this too and may be having issues as well. I tried reading the MDN docs for range and well I didn’t quite grasp how the system works. My cursor would appear in random places or not appear, or not be where I wanted it to be. I got most of it working by using Google, reading some articles, reading stack questions… but it wasn’t working properly. At first I was all confident like This should be easy right?

Then when the user selects one, add it to the list by removing the typing first, then add the new hashtag and move the cursor to the end. What I needed was to allow a user to enter hashtags and then send an ajax request to the backend to fetch a list of matching hashtags to display in a drop list below the input(auto suggestions). My use case makes it even harder and maybe yours does too.
#CONTENTEDITABLE GET PLAIN TEXT UPDATE#
For one, you need to have event listeners to listen for input then perform the proper actions to update the content and move the cursor to the end.

The idea seems super simple, but in reality the problem becomes complex for several reasons. Or they worked partially, or only in one browser. So this is something I needed to do and all the examples I found didn’t work properly. (2) bonus question: I had to put the "perform" under try catch otherwise I had this error "Unhandled exception: appears to work in all browsers. Method = .AuthController#registerUser(SignupRequest)
