Ryan King
Ryan King

Reputation: 3696

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/

Upvotes: 0

Views: 2129

Answers (3)

Nikhil Ghuse
Nikhil Ghuse

Reputation: 1288

Try this.

      function placeCaretAtEnd(el) {
        el.focus();
        if (typeof window.getSelection != "undefined"
        && typeof document.createRange != "undefined") {
            var range = document.createRange();

            range.selectNodeContents(el);
            range.collapse(false);
            var sel = window.getSelection();
            sel.removeAllRanges();
            sel.addRange(range);
        } else if (typeof document.body.createTextRange != "undefined") {
            var textRange = document.body.createTextRange();
            textRange.moveToElementText(el);
            textRange.collapse(false);
            textRange.select();
        }
    }

Upvotes: 0

Ryan King
Ryan King

Reputation: 3696

Substring Version:

$(document).on('keydown', 'p[contenteditable="true"]', function(e) {
    if(e.which == 13) { //new paragraph on enter/return
        e.preventDefault();
        cursorIndex = window.getSelection().getRangeAt(0).startOffset;
        textBefore = $(this).text().substring(0, cursorIndex);
        textAfter = $(this).text().substring(cursorIndex);
        $(this).text(textBefore); 
        $(this).after('<p contenteditable = "true">'+ textAfter +'</p>');
        $(this).next('p').focus();

    }
}

Upvotes: 2

Tim Down
Tim Down

Reputation: 324567

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);
    }
}

Upvotes: 1

Related Questions