Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Split div content at cursor position

I need to split an element after user clicks on it and the attr 'contenteditable' becomes 'true'. This fiddle works for the first paragraph but not second because the latter is in a p tag. Similary in this fiddle you will see that when the element has html tags in it, the counter loses accuracy and hence the text before and after the cursor is not what you'd expect.

The assumption here is that the users will split the data in a way that the help tags will stay intact. As pointed out by dandavis here, e.g. the div has <i>Hello</i> <b>Wo*rld</b>, the user will only need to split the div into two divs, first will have <i>Hello</i> and the second div will have <b>Wo*rld</b> in it.

Html:

<div><mark>{DATE}</mark><i>via email: </i><mark><i>{EMAIL- BROKER OR TENANT}</i></mark></div>

JS:

var $splitbut = $('<p class="split-but">Split</p>');
$(this).attr('contenteditable', 'true').addClass('editing').append($splitbut);

var userSelection;
if (window.getSelection) {
    userSelection = window.getSelection();
}
var start = userSelection.anchorOffset;
var end = userSelection.focusOffset;

var before = $(this).html().substr(0, start);
var after = $(this).html().substr(start, $(this).html().length);

The "Split" button is not working as generating the html is not an issue once I get proper "after" and "before" text. Any ideas as to what I am doing wrong here?

like image 616
AspiringCanadian Avatar asked Jan 19 '16 22:01

AspiringCanadian


1 Answers

Something like this could work for the specific case you describe

$('div, textarea').on('click', function(e) {
 var userSelection;
    if (window.getSelection) {
        userSelection = window.getSelection();
    }
    var start = userSelection.anchorOffset,
        end = userSelection.focusOffset,
        node = userSelection.anchorNode,
        allText = $(this).text(),
        nodeText = $(node).text();

// before and after inside node
  var nodeBefore = nodeText.substr(0, start);
  var nodeAfter = nodeText.substr(start, nodeText.length);

// before and after for whole of text
    var allExceptNode = allText.split(nodeText),
        before = allExceptNode[0] + nodeBefore,
        after = nodeAfter + allExceptNode[1];

  console.log('Before: ', before);
  console.log('------');
  console.log('After: ', after);

});

Updated demo at https://jsfiddle.net/gaby/vaLz55fv/10/


It might exhibit issues if there are tags whose content is repeated in the whole text. (problem due to splitting)

like image 167
Gabriele Petrioli Avatar answered Nov 15 '22 11:11

Gabriele Petrioli