Shai UI
Shai UI

Reputation: 51898

How to select text range within a contenteditable div that has no child nodes?

I'd like to select text within a content editable div. I'd like to provide a start index and an end index.

For example if I have a div:

<div id="main" contenteditable="true">
    Hello World
</div>

I'd like a function to do something like "selectText('#main',6,10)" and it would select set the focus to main and select "World".

But all the examples that I see online assume that the container div has children. But mine don't have any children. Just the text within the div.

This is what I've tried so far to no avail:

$('#main').focus();
var mainDiv = document.getElementById("main");
var startNode = mainDiv;
var endNode = mainDiv;

var range = document.createRange();
range.setStart(startNode, 6);
range.setEnd(endNode, 10);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);

But I get: Uncaught IndexSizeError: Failed to execute 'setStart' on 'Range': There is no child at offset 6.

My jsfiddle: http://jsfiddle.net/foreyez/h4bL5u4g/

Upvotes: 5

Views: 4032

Answers (1)

Rick Hitchcock
Rick Hitchcock

Reputation: 35670

But mine don't have any children. Just the text within the div.

The text within the div is a child – it's a text node. That's what you want to target.

You will also need to trim its nodeValue to get the proper offset. Otherwise, the leading spaces will be included.

This seems to do what you want:

function SelectText(obj, start, stop) {
  var mainDiv = $(obj)[0],
      startNode = mainDiv.childNodes[0],
      endNode = mainDiv.childNodes[0];

  startNode.nodeValue = startNode.nodeValue.trim();
  var range = document.createRange();
  range.setStart(startNode, start);
  range.setEnd(endNode, stop + 1);
  var sel = window.getSelection();
  sel.removeAllRanges();
  sel.addRange(range);
} //SelectText

$('#main').focus();

SelectText('#main', 6, 10);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main" contenteditable="true">
  Hello World
</div>

Upvotes: 7

Related Questions