CJT3
CJT3

Reputation: 2908

Working with contenteditable

Okay, so I am able to edit the content of my DIV just fine. However, there are a couple things I'm trying to work around.

In my editable div, I have a div containing a site address (such as twitter.com), I don't want that to be deletable from the editable DIV; the reason it's in there is so a user could copy all of the text including the domain.

If you remove all of the text except the domain, then the caret doesn't show up - or it does for a second all the way at the right side of the DIV.

And if a user deletes the domain name, it reappears but the caret is now to the left of it which I also don't want.

Any solutions on making the caret always visible and keeping it to the right of the domain?

Oh, and for some reason I can't use onKeyDown on the editable DIV to activate the anylyeText function (at least not in JSfiddle) so I had to do a setTimeout loop.

Here is my fiddle: jsfiddle


CSS:

.url {
    display: block;
    border: 1px solid rgb(140,140,140);
    padding: 5px;
    box-sizing: border-box;
    color: rgb(35,155,215);
    cursor: text;
    outline: none;
}
.url:focus {
    border-color: rgb(35,155,215);
}

.noedit {
    display: inline;
    color: rgb(140,140,140);
}

HTML:

<div class="url" contenteditable="true" id="textbox"><div class="noedit" contenteditable="false">http://twitter.com/</div>username</div>

JS:

var analyzeText = function() {
    var textbox = document.getElementById('textbox');
    var textVal = textbox.innerHTML;
    var urlString = '<div class="noedit" contenteditable="false">http://twitter.com/</div>';

    if (textVal.length < urlString.length) {
        textbox.innerHTML = urlString;
        textbox.focus();
    }
    setTimeout(function() { analyzeText(); }, 100);
};

(function(){analyzeText();})();

Upvotes: 0

Views: 1272

Answers (1)

Jack
Jack

Reputation: 9388

Here's a method using Selection and Range.

MDN Selection
MDN Range

(If you check out MDN, you'll notice that IE9 support isn't there - prior to IE9, you had to use proprietary IE script. Google can help you out there!)

First thing I do is add these two variables:

var range = document.createRange();
var sel = window.getSelection();

Then, I modified your script like so:

if (textVal.length < urlString.length) {
    textbox.innerHTML = urlString;

    // We create a text node and append to the textbox to select it
    textbox.appendChild(document.createTextNode(''));

    // Text node is selected
    range.setStart(textbox.childNodes[1], 0);

    // Collapse our range to single point (we're not selecting a word, after all!)
    range.collapse(true);

    // Let's clear any selections
    sel.removeAllRanges();

    // Alright, time to position our cursor caret!
    sel.addRange(range);

    textbox.focus();
}

And that's it! Here's an updated Fiddle to demonstrate:

Edit - Updated to include logic to prevent user from inserting text to the left of the domain

http://jsfiddle.net/Qycw2/6/

Upvotes: 2

Related Questions