Ryan King Ryan King - 5 months ago 21
Javascript Question

Contenteditable / jQuery / Javascript - Select text from cursor / caret to end of paragraph

I'm trying make a new paragraph when the enter key is pressed. I can do that and it works well. But now say the cursor is the middle of a paragraph - when enter is pressed I'm trying to select a range from the cursor position to the end of the paragraph. Remove that from the existing paragraph and add it to new paragraph below.

I'm trying to modify the code found in the answer here: Contenteditable - extract text from caret to end of element

$(document).on('keydown', 'p[contenteditable="true"]', function(e) {
if(e.which == 13) { //new paragraph on enter/return
e.preventDefault();
var sel = window.getSelection();
if (sel.rangeCount) {
var selRange = sel.getRangeAt(0);
var blockEl = selRange.endContainer.parentNode;
var range = selRange.cloneRange();
range.selectNodeContents(blockEl);
range.setStart(selRange.endContainer, selRange.endOffset);
remainingText = range.extractContents();
$(this).after('<p contenteditable = "true">'+ remainingText +'</p>');
$(this).next('p').focus();

}


I haven't had much success - mostly due to my lack of understanding when it comes to range, node and selection objects. Would someone be able to explain how these objects work and how I can adapt the answer above to suit my situation.

http://jsfiddle.net/UU4Cg/17/

Answer

Here's some code adapted from another answer to remove the Rangy dependency:

var sel = window.getSelection();
if (sel.rangeCount > 0) {
    // Create a copy of the selection range to work with
    var range = sel.getRangeAt(0).cloneRange();

    // Get the containing paragraph
    var p = range.commonAncestorContainer;
    while (p && (p.nodeType != 1 || p.tagName != "P") ) {
        p = p.parentNode;
    }

    if (p) {
        // Place the end of the range after the paragraph
        range.setEndAfter(p);

        // Extract the contents of the paragraph after the caret into a fragment
        var contentAfterRangeStart = range.extractContents();

        // Collapse the range immediately after the paragraph
        range.setStartAfter(p);
        range.collapse(true);

        // Insert the content
        range.insertNode(contentAfterRangeStart);

        // Move the caret to the insertion point
        range.setStartAfter(p);
        range.collapse(true);
        sel.removeAllRanges();
        sel.addRange(range);
    }
}