0

I am facing a problem with setting cursor position in a contentEditable div and seek some assistance.

I have already looked at several SO and other online solutions without success, including: jquery Setting cursor position in contenteditable div, and Set cursor position on contentEditable <div> and many other online resources.

Basically, we are using a Telerik Editor with the contentAreaMode set to DIV which forces it to use a contentEditable div instead of an iFrame. When a user clicks in the editor, we wish to be able to move the cursor to the click point so the user may enter/edit content wherever they wish in the editor. Using the example code below, I am able to set the cursor position in FF, Chrome, and IE9 to AFTER the inner div. However, in IE8 (which falls into the else if (document.selection) block), I am unable to get the cursor position to move after the div, so any typed text ends up either before or inside the div - never after. I would be GREATLY appreciative of any help.

ADDITIONAL INFO: Need this to work in IE8 standards document mode - NOT in Quirks mode (which does work).

UPDATE: Here is a jsfiddle of the issue to play with: http://jsfiddle.net/kidmeke/NcAjm/7/

<html>
    <head>
        <style type="text/css">
            #divContent
            {
                border: solid 2px green;
                height: 1000px;
                width: 1000px;
            }
        </style>

        <script type="text/javascript">
        $(document).ready(function()
        {
            $("#divContent").bind('click', function()
            {
                GetCursorPosition();
            });
            $("#divContent").bind('keydown', function()
            {
                GetCursorPosition();
            });
        });

        function GetCursorPosition()
        {
            if (window.getSelection)
            {
                var selObj = window.getSelection();
                var selRange = selObj.getRangeAt(0);
                cursorPos = findNode(selObj.anchorNode.parentNode.childNodes, selObj.anchorNode) + selObj.anchorOffset;
                $('#htmlRadEdit_contentDiv').focus();
                selObj.addRange(selRange);
            }
            else if (document.selection)
            {
                var range = document.selection.createRange();
                var bookmark = range.getBookmark();
                // FIXME the following works wrong when the document is longer than 65535 chars 
                cursorPos = bookmark.charCodeAt(2) - 11; // Undocumented function [3] 
                $('#htmlRadEdit_contentDiv').focus();
                range.moveStart('textedit');
            }
        }
        function findNode(list, node)
        {
            for (var i = 0; i < list.length; i++)
            {
                if (list[i] == node)
                {
                    return i;
                }
            }
            return -1;
        }
        </script>

    </head>
    <body>
        <div id="divContent" contentEditable="true">
            <br>
            <div style="background-color:orange; width: 50%;">
                testing!
            </div>
        </div>
    </body>
</html>
Community
  • 1
  • 1
user415127
  • 21
  • 2
  • 6

1 Answers1

0

Using Rangy (disclosure: I'm the author) works for me in IE 7 and 8 in the window load event. Trying to move the caret when the user clicks on an editable element is a bad idea: it conflicts with default browser behaviour hence may not work, and does not do what he user expects (which is to place the caret at or near where they clicked).

<html>
    <head>
        <style type="text/css">
            #divContent
            {
                width: 1000px;
                height: 1000px;
                border: solid 2px green;
                padding: 5px
            }
        </style>
        <script src="http://rangy.googlecode.com/svn/trunk/currentrelease/rangy-core.js"></script>

        <script type="text/javascript">
            window.onload = function() {
                rangy.init();
                var el = document.getElementById("divContent");
                el.focus();
                var range = rangy.createRange();
                range.setStartAfter(el.getElementsByTagName("div")[0]);
                range.collapse(true);
                rangy.getSelection().setSingleRange(range);
            };

        </script>

    </head>
    <body>
        <div id="divContent" contentEditable="true">
            <br>
            <div style="background-color:orange; width: 50%;">
                testing!
            </div>
        </div>
    </body>
</html>
Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • 1
    Hi, thanks for reply - gonna try code example now. You mention that it's a bad idea to try and move the caret - but it isn't placed where user clicks by default...have to do something. Am I missing something? How is such a task normally handled in a WYSIWYG editor? – user415127 Mar 28 '12 at 17:29
  • This doesn't work for me...I cannot set the cursor position PAST the inner div - it always ends up inside the div. I should have mentioned - I need it to work in IE8 document mode - it only works in QUIRKS mode... – user415127 Mar 28 '12 at 17:43
  • @user415127: OK. I suspect this may well be impossible then. Is it possible to place the cursor where you want using the mouse rather than programmatically? – Tim Down Mar 30 '12 at 23:49