Zaren Wienclaw
Zaren Wienclaw

Reputation: 191

How to focus on text box while text is highlighted

I want to set up a notes UI where the user can type notes while seeing what they highlighted to take notes on.

I have an element with id note which just fades in a textarea where notes can be typed.

My code

//on mouse up this function is called            
function note(){
  var sel = window.getSelection();
  var range = sel.getRangeAt(0);
  editor = { "startContainer": range.startContainer, "startOffset": range.startOffset, "endContainer": range.endContainer, "endOffset": range.endOffset };     //saves position of highlighted text
  range.setStart(editor.startContainer, editor.startOffset);
  range.setEnd(editor.endContainer, editor.endOffset);
  if (sel != '') {
    //notes element pops up
    $('#note').focus();
    sel.removeAllRanges();
    sel.addRange(range);
  }
}

Without the removeAllRanges() and addRange(range), the textarea gets the focus but the text becomes unhighlighted and with it the textarea loses focus but the text stays highlighted.

Solution

In my note menu pop up function I create a span and added a class to it:

var $span = $('<span>').addClass('blueHighlight').append(range.extractContents());
range.insertNode($span[0]);

I call a function that deletes the span class when the note menu goes away:

$('#pages').find('.blueHighlight').each(function(){
     $(this)[0].outerHTML = $(this).text();
});

Upvotes: 0

Views: 120

Answers (1)

Jeto
Jeto

Reputation: 14927

You could use a custom highlighted class and surround selected text with a span with that class when selected.

Demo:

// Get the selected text's range

function getSelectedTextRange() {
  var selection = window.getSelection();
  if (selection.rangeCount > 0) {
    var range = selection.getRangeAt(0);
    var rangeContents = range.cloneContents();
    if (rangeContents.childNodes.length > 0 && rangeContents.childNodes[0].nodeType === Node.TEXT_NODE) {
      return range;
    }
  }
  return null;
}

$('#text')
   // On click release, surround highlighted text with a span with highlighted class
  .on('mouseup', function() {
    if (range = getSelectedTextRange()) {
      var $span = $('<span>').addClass('highlighted').append(range.extractContents());
      range.insertNode($span[0]);
      $('#note').focus();
    }
  })
  // On click down, remove all previously highlighted text
  .on('mousedown', function() {
    $(this).find('span').each(function() {
      $(this)[0].outerHTML = $(this).text();
    });
  });
#text::selection,
.highlighted {
  color: red;
  background: yellow;
}

#text::-moz-selection,
.highlighted {
  color: red;
  background: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="text">Highlight me!</div>
<textarea id="note" placeholder="Notes"></textarea>

Upvotes: 1

Related Questions