1

Given the following HTML...

<p>Today is <span data-token="DateTime.DayOfWeek">$$DayOfWeek$$</span>,
</p>
<p>Tomorrow is the next day, etc, etc....</p>

Clicking on $$DayOfWeek$$ returns a DOM Range object (via a component, which is a WYSIWIG editor bundled with KendoUI).

I can then access the entire Element like so...

var element = range.startContainer.parentElement;
console.log(element);

which outputs...

<span data-token="DateTime.DayOfWeek">$$DayOfWeek$$</span>

What i am trying to figure out is how to construct a Range object that consists of the entire Element, as a Range.

The desired 'high level' behaviour is to single click a piece of text, and have the browser select all the text within that element, returning a Range object.

Happy to accept a jQuery solution.

Baldy
  • 3,621
  • 4
  • 38
  • 60

2 Answers2

1

here is a way i came up with that seems to work if i understand you correctly, that you want the element surrounding a click to produce a range containing everything in that element.

without the onclick code, which i assume you can handle, here is the DOM range code you describe:

var sel=document.getSelection(); //find the node that was clicked
var rng=sel.getRangeAt();  //get a range on that node

//now, extend the start and end range to the whole element:
rng.setStart(rng.startContainer.parentNode.firstChild);
rng.setEndAfter(rng.endContainer.parentNode.lastChild);

//DEMO: verify the correct range using a temp div/alert:
var t=document.createElement("div");
t.appendChild(rng.cloneContents());
alert(t.innerHTML);
dandavis
  • 16,370
  • 5
  • 40
  • 36
  • +1 for the idea of wrapping the range into a new div - this was useful for getting at the html – Baldy May 22 '13 at 11:28
1

HTML

<p>Today is <span data-token="DateTime.DayOfWeek">$$DayOfWeek$$</span>,</p>
<p>Tomorrow is the next day, etc, etc....</p>

JS

var span = document.querySelector('[data-token]');

span.addEventListener('click', function() {
    var sel = window.getSelection();
    var range = document.createRange();
    sel.removeAllRanges();
    range.setStart(span.childNodes[0], 0);                      
    range.setEnd(span.childNodes[0], span.innerText.length);
    sel.addRange(range);                      
});

Here's a fiddle for you: http://jsfiddle.net/V66zH/2/

It' might not be super cross browser, but works in chrome. See JavaScript Set Window selection for some additional optimizations elsewhere.

Also assumes only one childNode as in your example html

Some additional reference for Ranges (https://developer.mozilla.org/en-US/docs/Web/API/range) and Selections (https://developer.mozilla.org/en-US/docs/Web/API/Selection)

Community
  • 1
  • 1
Matt Berkowitz
  • 975
  • 6
  • 13
  • Thanks Matt. Was really easy to adapt your fiddle into the editor component and simply pass it the created range to enable the selection of the whole element. – Baldy May 22 '13 at 08:59
  • in FireFox i get an error at span.innerText ... so i changed the jsFiddle a bit .. `var TX = span.textContent || span.innerText; range.setEnd(span.childNodes[0], TX.length);` .. and this way i think it works in all browsers. – Roelof Berkepeis Jul 29 '14 at 11:54