Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript - Get HTML of current line in contentEditable div

I have got my contentEditable div:

div {
  width: 200px;
  height: 300px;
  border: 1px solid black;
}
<div contenteditable="true" spellcheck="false" style="font-family: Arial;">
    <b>Lorem ipsum</b> dolor sit amet, <u>consectetur adipiscing elit. 
    Morbi sagittis</u> <s>mauris porta arcu auctor, vel aliquam ligula ornare.</s> 
    Sed at <span id="someId">semper neque, et dapibus metus. 
    Maecenas dignissim est non nunc feugiat</span> 
    sollicitudin. Morbi consequat euismod consectetur. Mauris orci 
    risus, <b>porta quis erat ac, malesuada</b> fringilla odio.
</div>
    
<button>Get current line HTML</button>

And I want to create a button which gives me HTML code from the current line. For example:
When my caret is on the second line I want to get:

amet, <u>consectetur</u>

or on seventh line:

<span id="someId">dapibus metus. Maecenas</span>

I tried to do that using Rangy, but that didn't work. How can I do that using JavaScript and/or JQuery?
Thanks for help.

like image 635
Kacper G. Avatar asked Sep 16 '17 12:09

Kacper G.


2 Answers

I will not code you the full finished code but here are good help that will get you the result.

First you need to get a method for figuring out lines. I suggest looking at the answer in this stackoverflow: How to select nth line of text (CSS/JS) From that you can get line number for a specific word.

What word your caret is on you can get from this information: How can I get the word that the caret is upon inside a contenteditable div?

Combining the line number functionality with current caret word you will be able to return a full row where your caret is.

like image 160
JohanSellberg Avatar answered Nov 07 '22 07:11

JohanSellberg


This solution is based on the example proposed by Mozilla in Selection.modify(), but using lineboundary granularity and playing with move and extend alter parameters.

To preserve caret position, the range of the selection is stored/restored.

Play with the width of the content, edit the snippet and check it out.

You got your HTML.

function getSelectionHtml() {
  var selection = window.document.selection,
    range, oldBrowser = true;

  if (!selection) {
    selection = window.getSelection();
    range = selection.getRangeAt(0);
    oldBrowser = false;
  } else
    range = document.selection.createRange();

  selection.modify("move", "backward", "lineboundary");
  selection.modify("extend", "forward", "lineboundary");

  if (oldBrowser) {
    var html = document.selection.createRange().htmlText;
    range.select();
    return html;
  }

  var html = document.createElement("div");

  for (var i = 0, len = selection.rangeCount; i < len; ++i) {
    html.appendChild(selection.getRangeAt(i).cloneContents());
  }

  selection.removeAllRanges();
  selection.addRange(range);
  return html.innerHTML;
}

document.getElementById("content").onmouseup = function(e) {
  var html = getSelectionHtml();
  document.getElementById("text").innerHTML = html;
  document.getElementById("code").textContent = html;
};
h4,
p {
  margin: 0;
}

#code {
  width: 100%;
  min-height: 30px;
}

#content {
  margin: 15px;
  padding: 2px;
  width: 200px;
  height: 300px;
  border: 1px solid black;
}
<textarea id="code"></textarea>
<div id="text"></div>

<div contenteditable="true" id="content" spellcheck="false" style="font-family: Arial;">
  <b>Lorem ipsum</b> dolor sit amet, <u>consectetur adipiscing elit. 
    Morbi sagittis</u> <s>mauris porta arcu auctor, vel aliquam ligula ornare.</s> Sed at <span id="someId">semper neque, et dapibus metus. 
    Maecenas dignissim est non nunc feugiat</span> sollicitudin. Morbi consequat euismod consectetur. Mauris orci risus, <b>porta quis erat ac, malesuada</b> fringilla odio.
</div>
like image 44
I.G. Pascual Avatar answered Nov 07 '22 08:11

I.G. Pascual