Henrik Petterson
Henrik Petterson

Reputation: 7094

Select part of text after it's been added

I have this code:

$sel = 'lorem ipsum';
jQuery(this).html('<p>Hello world ' + $sel +' great day!');

So the .html() is added via ajax.

I want the $sel text to be selected when it's output on the page (as if the user highlighted it with their cursor).

I have the following code to select elements:

function SelectText(element) {
    var doc = document
        , text = doc.getElementById(element)
        , range, selection
    ;    
    if (doc.body.createTextRange) {
        range = document.body.createTextRange();
        range.moveToElementText(text);
        range.select();
    } else if (window.getSelection) {
        selection = window.getSelection();        
        range = document.createRange();
        range.selectNodeContents(text);
        selection.removeAllRanges();
        selection.addRange(range);
    }
}

How can I use that code and select just the text within $sel? So, output the html and select the $sel part.

Upvotes: 9

Views: 659

Answers (7)

Arjun
Arjun

Reputation: 1355

The function below (createSelectedSpan) accepts a single argument, value. Every time this function is called, a new local variable sel, with the value of span element, is created. The sel's innerHTML is set to the value of argument value. Then, sel is adopted as a child by body. And at last sel is selected.

Besides this, I've modified your SelectText function to set the variable text defined inside it to the DOM Node passed to it as an argument.

This function can be called multiple times without any error with the newly added element being selected and other elements being deselected.

  function SelectText(element) {
  var doc = document,
    text = element,  // A modification is made here
    range, selection;
  if (doc.body.createTextRange) {
    range = document.body.createTextRange();
    range.moveToElementText(text);
    range.select();
  } else if (window.getSelection) {
    selection = window.getSelection();
    range = document.createRange();
    range.selectNodeContents(text);
    selection.removeAllRanges();
    selection.addRange(range);
  }
}

function createSelectedSpan(value){
  var sel = document.createElement("span");
  sel.innerHTML = value;

  $("body").append(sel);

  
  SelectText(sel);
}

createSelectedSpan("hello world");
setTimeout(function(){createSelectedSpan("hello world2")},5000); //called second time
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Upvotes: 5

Georgggg
Georgggg

Reputation: 564

You can insert the new element within a span tag:

with Jquery:

$sel = 'lorem ipsum';
jQuery(this).html( '<p>Hello world <span id=\"selectedSpan\">' + $sel +'</span> great day!</p>')

jQuery("#selectedSpan").css('color','red')
jQuery("#selectedSpan").css('background','yellow')

This way you can choose whatever style you want it to look like.

Upvotes: 0

user3241019
user3241019

Reputation: 811

Your function is fine, so the easiest way to select it is to call it once your Ajax is finished. Just listen for the event to fire and call the function.

This should be done this way :

var xhr = new XMLHttpRequest();
// do stuff

// listen to the loading to be finished
xhr.onreadystatechange = function()
    {
        try
        {
            if (xhr.readyState == 4 && xhr.status == 200) 
            {           
             /* here your loading is finished, call the function
                on the id of the element which received the text */
             SelectText('yourElement');
            }
        }
        catch(e)
        {
        alert(e.message);
        }
    };

So just after the loading is finished i.e. when the text is outputted on your page, the text will be highlighted. Voila !

Upvotes: 0

Azamantes
Azamantes

Reputation: 1451

You can wrap the $sel in any custom tag, doesn't matter which one, for example x.

this.innerHTML = '<p>Hello world <x>' + $sel +'</x> great day!');

And then simply highlight it. Since this contains only the p tag, you can reference it descending directly from this through the p tag onto the x tag, which contains the $sel value. You don't have to worry about other x tags on the webpage since you start looking from this downwards. You will always find exactly 1 p tag and inside it only x tag.

var selection = window.getSelection();        
var range = document.createRange();
var p = this.children[0]; // 'children' ignores Text nodes unlike 'childNodes'
var x = p.children[0];
range.selectNodeContents(x);
selection.removeAllRanges();
selection.addRange(range);

Tadaa.

Upvotes: 0

user372495
user372495

Reputation: 710

You could insert the element through jQuery and then select the element you just inserted. That way you always target whatever it is that you're inserting at the moment.

var sel = $('<span>').html('lorem ipsum');
$('body').html('<p>Hello world <span class="insertion-point"></span> great day!</p>');
$('body').find('.insertion-point').after(sel);
var toSelect = sel.get(0);

if (document.body.createTextRange) {
	range = document.body.createTextRange();
    range.moveToElementText(toSelect);
    range.select();
} else if (window.getSelection) {
	selection = window.getSelection();
    range = document.createRange();
    range.selectNodeContents(toSelect);
    selection.removeAllRanges();
    selection.addRange(range);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Upvotes: 0

arvie
arvie

Reputation: 761

The function "SelectText" which you are using is fine. I think the solution can be like this:

$(document).ready(function(){
    $sel = 'lorem ipsum';
    $('#feedback').html('<p>Hello world <span id="selection">'+ $sel +'</span> great day!</p>');
    SelectText('selection');  
});

Upvotes: 0

The best approach is to use CSS for this purpose.

var text = "Bla Bla";
$('body').append("<p>Text Before, <span class='highlight'>" + text + "</span>, Text After</p>");
.highlight {
  background-color: yellow;
  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Upvotes: -3

Related Questions