Highlight DIV text as custom character type in input field

I have seen many posts related to highlighting text in a DIV using javascript, but no one is doing what I'm looking for.

What I need to do is select the text within a specific DIV, character by character, when the user enters a search query. Conversely, since the user reverses or deletes characters, I need to “de-highlight” the text of the same DIV.

I assume that this has already been done by someone, but I have not yet found a message here or from Google, which behaves exactly as I need.

Any feedback is welcome.

this code executes as custom character types in the input field. The problem is that in some cases it inserts the string "" into the table when I type, and I don't know why, so I'm looking for another solution.

Thanks for the feedback!

function filterTable(Stxt, table) {
     dehighlight(document.getElementById(table));
     if (Stxt.value.length > 0)
       highlight(Stxt.value.toLowerCase(), document.getElementById(table));
  }

  function dehighlight(container) {
     for (var i = 0; i < container.childNodes.length; i++) {
       var node = container.childNodes[i];
       if (node.attributes && node.attributes['class'] && node.attributes['class'].value == 'highlighted') {
           node.parentNode.parentNode.replaceChild(
           document.createTextNode(node.parentNode.innerHTML.replace(/<[^>]+>/g, "")),node.parentNode);
           return;
       } else if (node.nodeType != 3) {
           dehighlight(node);
       }
     }
  }

  function highlight(Stxt, container) {
    for (var i = 0; i < container.childNodes.length; i++) {
        var node = container.childNodes[i];
        if (node.nodeType == 3) {
            var data = node.data;
            var data_low = data.toLowerCase();
            if (data_low.indexOf(Stxt) >= 0) {
                var new_node = document.createElement('span');
                node.parentNode.replaceChild(new_node, node);
                var result;
                while ((result = data_low.indexOf(Stxt)) != -1) {
                    new_node.appendChild(document.createTextNode(data.substr(0, result)));
                    new_node.appendChild(create_node(
                    document.createTextNode(data.substr(result, Stxt.length))));
                    data = data.substr(result + Stxt.length);
                    data_low = data_low.substr(result + Stxt.length);
                }
                new_node.appendChild(document.createTextNode(data));
            }
        } else {
            highlight(Stxt, node);
        }
    }
  }

  function create_node(child) {
    var node = document.createElement('span');
    node.setAttribute('class', 'highlighted');
    node.attributes['class'].value = 'highlighted';
    node.appendChild(child);
    return node;
  }
+5
source share
4 answers

This can easily be done with a regular expression to modify the contents of a div. Here's a simple implementation:

var s = document.getElementById('s');    // your input
var div = document.getElementById('a');  // the div to change
var t = a.textContent || a.innerText;
s.onkeyup = function(){
   div.innerHTML = this.value
   ? t.replace(new RegExp('('+this.value+')','ig'), '<span class=highlight>$1</span>')
   : t;
};

Demo (click "Run with JS")


EDIT:

This more complex version works even if you have tables and stuff:

var s = document.getElementById('s');
var div = document.getElementById('a'); 

function changeNode(n, r, f) {
  f=n.childNodes; for(c in f) changeNode(f[c], r);
  if (n.data) {
    f = document.createElement('span');
    f.innerHTML = n.data.replace(r, '<span class=found>$1</span>');
    n.parentNode.insertBefore(f, n);
    n.parentNode.removeChild(n);
  }
}
s.onkeyup = function(){
  var spans = document.getElementsByClassName('found');
  while (spans.length) {
    var p = spans[0].parentNode;
    p.innerHTML = p.textContent || p.innerText;
  }
  if (this.value) changeNode(
    div, new RegExp('('+this.value+')','gi')
  );
};

Demo (click "Run with JS")

+4
source

My Rangy library supports this, although I recognize this as a pretty large script just for this use.

: http://rangy.googlecode.com/svn/trunk/demos/textrange.html

+1

I did a demo that uses regex.

// Input element
var input = document.getElementById("highlighter"), 
    // Text container element
    divText = document.getElementById("text"),
    // using textContent property if it exists
    textProp = ("textContent" in divText) ? "textContent" : "innerText",
    // Getting text to discard html tags (delete line 6 and use divText.innerHTML if you want to keep the HTML tags)
    originalText = divText[textProp];

function handler(){
    // if Input.value is empty clear the highlights
    if(!this.value){
        divText.innerHTML = originalText;
        return true;
    }
    // Regex to group the matches, with tags 'global' and 'case insensitive'
    var regex = new RegExp("("+this.value+")", "ig");
    // replace text with the new one ($1 refers to first group matched by regex)
    divText.innerHTML = originalText.replace(regex, "<span class='highlight'>$1</span>");

};
// adding listener to input.. IE uses attachEvent method
input.addEventListener("keyup", handler, false);

JSFiddle DEMO

0
source

sdsdsdsdsdsdsddsdsdsdsdsdsdsadsdsadsadsadasdsadasds

-1
source

All Articles