Start trial
PricingContact Us
Log InStart For Free

How to set and get cursor position in a text area

November 14th, 2023

9 min read

A cursor appears in a text editor along with other content behind it, set by end users represented by people icons

Written by

Joe Robinson

Category

How-to Use TinyMCE

Mastering the navigation of the Document Object Model (DOM) is a powerful skill. However, it’s not always clear exactly where elements reside within the DOM. That’s frustrating when you need to make changes to a page that’s already loaded, or when you need to set the cursor position.

Traversing the DOM is like following roadmap directions. And like a roadmap, each element of the web page has an address. You can target these addresses – also called nodes – and make changes to the page.

Usually, changes happen in response to customers pressing a button or some other interaction. But what about finding your way when the changes are inside a textarea? Like collaboration or commenting on text within the textarea?

The textarea is an element inside the page DOM, and the text content inside that textarea also contains elements. And since these elements are nodes, you can navigate through them and place the cursor position at a specific spot. 

But it’s not always a direct path through the DOM, through the textarea element, and to a specific cursor position.

For TinyMCE, a rich text editor that's shown its reliability time and again, this process is made possible (with some limits), using specific APIs. This article explains how it’s done, with some examples.

Table of Contents

What’s a cursor position? And what’s a caret?
What you need to set cursor position: JavaScript and more
Getting the cursor position
    Setting the cursor position
        1. Select content, and then bookmark the position of the content
        2. Set the caret position on newly added content
        3. Set the caret position at the end of the text area
How to set the caret position
Set up a TinyMCE demo editor
    1. Set the cursor position with the Bookmark Manager API
    2. Set the cursor position at new elements
    3. Set the cursor position at the end of the text editor
Setting the cursor position - one key point

What’s a cursor position? And what’s a caret?

A cursor is a pointer – the graphical icon that represents the mouse. It’s often a small arrow icon that moves around the web page on screen. Sometimes, the “cursor” position is brought up to describe the “caret” position.

A caret is the blinking line that indicates where the next word is going to appear when keydown events (the press of the keyboard) happens. Still unclear? What really matters is the intention – do you want to put the blinking line in a specific place in the text area? Then in that case, you want to set the caret at a specific position.

What you need to set cursor positions: JavaScript and more

With that goal in mind, what skills and knowledge do you need to  set the caret in the right spot? You need to know the following:

  1. Understand JavaScript
  2. Understand Web APIs
  3. Have some curiosity about TinyMCE APIs

It’s also important to know the limits of what you're doing. Finding a specific place in the textarea is difficult. It can also be difficult in TinyMCE's text area. 

What you can do though, is firstly place the caret at the location you want, and then you can bookmark that location. Then, you can load that location when you need it. That’s the main limit of setting the cursor location – you need to choose the location if you want a specific spot first, save it, and then apply that specific bookmark later on.

Getting the cursor position

While you can set the position using TinyMCE APIs, getting the cursor position coordinates, integers, or a string, represents a more difficult challenge. Using the TinyMCE Bookmark Manager API, you can set the cursor position that you want to get, and then bookmark that cursor position. The API saves the location so you can retrieve it later (more on the API in the following procedures).

Setting the cursor position

Using the TinyMCE Bookmark Manager API, you can configure the editor to hold on to the caret position in the form of a selection of content. A selection, also known as highlighting, happens when the browser recognizes that you have:

  1. Pushed the mouse button down
  2. Dragged the cursor across content
  3. Then let the mouse button move up again.

You can also hold down shift and move the cursor with the arrow keys on the keyboard to select content. It has the same effect. TinyMCE bookmarks the selected location with the Bookmark Manager API, and then loads the selected location later, if or when you request it.

If you are adding content into the TinyMCE text area, you can also set the caret position to be at a specific index location within a DOM element, like <p> or <strong> that you’re adding to the editor. The TinyMCE setCursorLocation API can target the content you’re adding, and TinyMCE then essentially picks up your cursor, and puts it down at the integer you want.

For instance, if you write “<strong>bold text</strong>” within the text area, you can use an API to set an integer of “<strong> [5]” to place the caret on the fifth character of the <strong> element, which is the letter “t” in text.

The expected behavior of the text area caret is to appear at the beginning, that is, the top left hand corner of the text area. The selection.collapse API method allows for this beavior. However, you can set the caret to appear in the lower right of the text area, which is the opposite position to where it ordinarily appears.

How to set the caret position

The first way of doing this involves the TinyMCE Bookmark Manager API. To test this out, the Tutorial below creates a function, and sets the function up to run when a button on the demo web page is clicked.

Set up a TinyMCE demo editor

To put TinyMCE’s APIs for cursor position to the test, the following demo first sets up TinyMCE in a demo document editor:

  1. Create a new index.html file in your development environment
  2. Include the following HTML to start up the TinyMCE demo editor:
<!DOCTYPE html>
<html lang="en">
 <head>
   <meta charset="utf-8">
   <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://cdn.tiny.cloud/1/no-api-key/tinymce/6/tinymce.min.js" referrerpolicy="origin"></script>
   <script>
    tinymce.init({
       selector: "#editor",
    });
   </script>
   </head>
 <body>
 <h1>TinyMCE Example</h1>
   <form method="post">
     <textarea id="editor"></textarea>
   </form>
 </body>
</html>
  1. For this cursor position test, the rich text editor resides inside a Document Management System. Setting this up requires using the content_style option to target the body element and change the appearance:

<script>
    tinymce.init({
       selector: "#editor",
       content_style:`
                body {
                    background: #fff;
                }

                @media (min-width: 840px) {
                    html {
                        background: #eceef4;
                        min-height: 100%;
                        padding: 0 .5rem
                    }

                    body {
                        background-color: #fff;
                        box-shadow: 0 0 4px rgba(0, 0, 0, .15);
                        box-sizing: border-box;
                        margin: 1rem auto 0;
                        max-width: 820px;
                        min-height: calc(100vh - 1rem);
                        padding:4rem 6rem 6rem 6rem
                    }
                }
             ` 
     });
   </script>

💡NOTE: You can change the “no-api-key” string to your TinyMCE API key. When you sign up for a FREE TinyMCE API key, you get a 14 day free trial of TinyMCE’s Premium plugins. Using the key also prevents domain identification errors showing up in the text area.

  1. Save the changes, and test the index file in the browser. You can also test it by running the index file on your workstation’s local host using a python command or a PHP command:

TinyMCE working as a DMS for cursor position

1. Set the cursor position with the Bookmark Manager API

To test out this API, and see how it works quickly, this tutorial makes use of the Developer Tools console.

  1. With the developer console open (ctrl + option + j on chrome for instance) highlight the content in the editor that you want to bookmark, and return the cursor position to later.
  2. Run the following command to bookmark the cursor position:
let bookmark = tinymce.activeEditor.selection.getBookmark();
  1. Move the cursor away from the bookmarked content. You can remove the highlighted selection, and include some more content in the editor at this stage.

  2. To load the bookmark, run the following command in the developer console:

tinymce.activeEditor.selection.moveToBookmark(bookmark);

With the moveToBookmark method, the editor will return the content set up and selected with the getBookmark command. This is one way to capture the cursor position inside the TinyMCE editor, and then return to it later when it’s needed.

2. Set the cursor position at new elements

For this method, the tutorial sets up an interactive element (a button) and runs the TinyMCE setCursorLocation API command.

  1. Set a button element just after the text area in the demo HTML file:

 <body>
 <h1>TinyMCE Example</h1>
   <form method="post">
     <textarea id="editor"></textarea>
   </form>
  <button></button>
  1. Give the button the id of buttonSelect

<button id=”buttonSelect”></button>
  1. Set up a pair of script tags after the body element of the demo HTML file:

</body>  
<script>  </script>
</html>
  1. Place the following function inside the script tags. This function selects the active editor Body element :

     <script>
         function selectionCommand() {
  let editorBody = tinymce.activeEditor.getBody();
  1. Extend the function by using the TinyMCE setContent API to change the editor content 

 <script>
  function selectionCommand() {
  let editorBody = tinymce.activeEditor.getBody();
  tinymce.activeEditor.setContent('<p>hello <strong>bold</strong> content</p>');
  1. To set the cursor position in the new content, add to the function a variable, and assign to it the bold, or strong, element set up in the previous step.

    ✏️NOTE: This is one method for selecting the TinyMCE text editor, setting content, and then selecting a specific node within the editor.
<script>
  function selectionCommand() {
  let editorBody = tinymce.activeEditor.getBody();
  tinymce.activeEditor.setContent('<p>hello <strong>bold</strong> content</p>');
  let nodeStrong = tinymce.activeEditor.dom.select('strong')
  1. Add the setCursorLocation API command targeting the variable set up in the previous step (containing the strong tag selection), and set the focus method:

<script>
  function selectionCommand() {
  let editorBody = tinymce.activeEditor.getBody();
  tinymce.activeEditor.setContent('<p>hello <strong>bold</strong> content</p>');
  let nodeStrong = tinymce.activeEditor.dom.select('strong');
        tinymce.activeEditor.selection.setCursorLocation(nodeStrong[0].firstChild, 2);
        tinymce.activeEditor.focus();

}

</script>
  1. Add an event listener that’ll be triggered by the button click event, referencing the button added at the beginning of this procedure:

 <script>
  function selectionCommand() {
    let editorBody = tinymce.activeEditor.getBody();
    tinymce.activeEditor.setContent('<p>hello <strong>bold</strong> content</p>');
    let nodeStrong = tinymce.activeEditor.dom.select('strong');
    tinymce.activeEditor.selection.setCursorLocation(nodeStrong[0].firstChild, 2);
    tinymce.activeEditor.focus();
}
var buttonSelection = document.getElementById('buttonSelect');
buttonSelection.addEventListener('click', selectionCommand, false);
</script>
  1. Save the changes, and then test run the button to set the cursor position:

New content with cursor position set in a specific location

3. Set the cursor position at the end of the text area

With the selection.collapse API method, you can move the cursor position to the end of the editor.

  1. Add a second button the the demo HTML file after the button produced in the previous procedure:

<button id="buttonEnd" class="button_style">
  Go to the end
</button>;
  1. Add a new function to script tags at the end of the demo HTML file:

function endCommand() {}
  1. Use the selection API and the getBody API methods to capture the text area content:

function endCommand() {
        tinymce.activeEditor.selection.select(tinyMCE.activeEditor.getBody(), true);
  1. Include the collapse API method to move the cursor to the end of the selection range, which is the end of the editor, and then include the focus API:

function endCommand() {
  tinymce.activeEditor.selection.select(tinyMCE.activeEditor.getBody(), true);
  tinymce.activeEditor.selection.collapse(false);
  tinymce.activeEditor.focus();
}
  1. Add an event listener to trigger the function when the button is clicked:

var buttonEnd = document.getElementById("buttonEnd");
buttonEnd.addEventListener("click", endCommand, false);
  1. Save the changes, and test run the button to move the cursor to the end of the rich text editor:

TinyMCE cursor position set to end of editor

Setting the cursor position - one key point

Depending on what you need in your web page or app, you can use one of the methods available with the TinyMCE API to set the cursor position in your rich text editor.

Next steps could include setting the Bookmark Manager API to run on events in the interface, such as a mouseup event, following a highlight.

Once you have the DOM node selected in the text area, you can be precise, and set the caret to appear at a specific index number within that DOM node. 

The key point to remember is: that setting the cursor position on a specific point in the text area needs a specific DOM node to work correctly.

If you’d like to find out more about TinyMCE, and try some of the Premium plugins, contact us and our customer success team can help you find the rich configuration for your web page or app, and set the cursor position where you need it.

APITextareaTinyMCEHTML
byJoe Robinson

Technical and creative writer, editor, and a TinyMCE advocate. An enthusiast for teamwork, open source software projects, and baking. Can often be found puzzling over obscure history, cryptic words, and lucid writing.

Related Articles

  • How-to Use TinyMCENov 21st, 2024

    How to Add Custom Import and Export from Markdown Buttons to TinyMCE

Join 100,000+ developers who get regular tips & updates from the Tiny team.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Tiny logo

Stay Connected

SOC2 compliance badge

Products

TinyMCEDriveMoxieManager
© Copyright 2024 Tiny Technologies Inc.

TinyMCE® and Tiny® are registered trademarks of Tiny Technologies, Inc.