Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to highlight the matching sub-string from search result in JavaScript

I am a newbie in JavaScript. Trying to build a small user interface that searches a list of words when we fire a query into the search box. With that, I want to highlight the matching sub-string of each word in the list box so that the user can see at a glance how the word matches the query. To achieve this target I include highlight function in my code by referring some basic JS tutorials. But due to some mistake, it is not working. Can you please help me. Thanks..!!!

    function getFullName(item,index) { 
        return "<li>"+item.firstname + "<span class='tool-tip'>" +item.lastname+"</span> "+ item.id+"</li>";
    }
    function myFunction1() {
        document.getElementById("demo").innerHTML = persons.map(getFullName);
    }

    function myFunction() {
        var input, filter, ul, li, a, i,count=0;
        input = document.getElementById("myInput");
        filter = input.value.toUpperCase();

      var longWords = persons.filter(function(person){

         return  person.firstname.toUpperCase().indexOf(filter) > -1 
    });
        var message = "Result:" + longWords.length + " words containing '" + input.value;
        document.getElementById("demo").innerHTML=message;

        ul = document.getElementById("myUL");
        ul.innerHTML= longWords.map(getFullName);
        highlight();
    }
    function highlight(){
        var inputText, filter1,innerHTML,index;
        inputText = document.getElementById("myInput");
        console.log(inputText);
        filter1 = inputText.value.toUpperCase();
        console.log(filter1);
        innerHTML1 = inputText.innerHTML;
        console.log(innerHTML1);
        index1 = innerHTML1.indexOf(filter1);
    if ( index1 >= 0 )
    { 
        innerHTML1 = innerHTML1.substring(0,index1) + "<span class='highlight'>" + innerHTML1.substring(index1,index1+filter1.length) + "</span>" + innerHTML1.substring(index1 + filter1.length);
        filter1.innerHTML = innerHTML1; 
    }

}

here is the CSS file:

.highlight{
             font-weight:bold;
             color:black;
 }
like image 385
Rupali Avatar asked Oct 17 '22 03:10

Rupali


1 Answers

Following is from my bookmarked code for highlighting. Type a text in textfield and you can see the highligted text in yellow

function highlight_text_nodes($nodes, word) {
  if (!$nodes.length) {
    return;
  }

  var text = '';

  // Concatenate the consecutive nodes to get the actual text
  for (var i = 0; i < $nodes.length; i++) {
    text += $nodes[i].textContent;
  }

  var $fragment = document.createDocumentFragment();

  while (true) {
    // Tweak this if you want to change the highlighting behavior
    var index = text.toLowerCase().indexOf(word.toLowerCase());

    if (index === -1) {
      break;
    }

    // Split the text into [before, match, after]
    var before = text.slice(0, index);
    var match = text.slice(index, index + word.length);
    text = text.slice(index + word.length);

    // Create the <mark>
    var $mark = document.createElement('mark');
    $mark.className = 'found';
    $mark.appendChild(document.createTextNode(match));

    // Append it to the fragment
    $fragment.appendChild(document.createTextNode(before));
    $fragment.appendChild($mark);
  }

  // If we have leftover text, just append it to the end
  if (text.length) {
    $fragment.appendChild(document.createTextNode(text));
  }

  // Replace the nodes with the fragment
  $nodes[0].parentNode.insertBefore($fragment, $nodes[0]);

  for (var i = 0; i < $nodes.length; i++) {
    var $node = $nodes[$nodes.length - i - 1];
    $node.parentNode.removeChild($node);
  }
}


/*
 * Highlights all instances of `word` in `$node` and its children
 */
function highlight($node, word) {
  var $children = $node.childNodes;
  var $current_run = [];

  for (var i = 0; i < $children.length; i++) {
    var $child = $children[i];

    if ($child.nodeType === Node.TEXT_NODE) {
      // Keep track of consecutive text nodes
      $current_run.push($child);
    } else {
      // If we hit a regular element, highlight what we have and start over
      highlight_text_nodes($current_run, word);
      $current_run = [];

      // Ignore text inside of our <mark>s
      if ($child.nodeType === Node.ELEMENT_NODE && $child.className !== 'found') {
        highlight($child, word);
      }
    }
  }

  // Just in case we have only text nodes as children
  if ($current_run.length) {
    highlight_text_nodes($current_run, word);
  }
}

/*
 * Removes all highlighted <mark>s from the given node
 */
function unhighlight($node) {
  var $marks = [].slice.call($node.querySelectorAll('mark.found'));

  for (var i = 0; i < $marks.length; i++) {
    var $mark = $marks[i];

    // Replace each <mark> with just a text node of its contents
    $mark.parentNode.replaceChild(document.createTextNode($mark.childNodes[0].textContent), $mark);
  }
}



var $p = document.querySelector('p');

document.querySelector('input').onkeyup = function() {
  unhighlight($p);

  if (this.value.length) {
    highlight($p, this.value);
  }
};
<input type="text" />

<p>
<b>JavaScript</b> is a high-level, dynamic, multi-paradigm, object-oriented, prototype-based, weakly-typed language traditionally used for client-side scripting in web browsers. JavaScript can also be run outside of the browser with the use of a framework like Node.js, Nashorn, Wakanda, or Google Apps Script. Despite the name, it is unrelated to the Java programming language and shares only superficial similarities.

Unless a tag for a framework or library is also included, a pure JavaScript answer is expected for questions with the javascript tag.
</p>

Edit, based on comment. Here is the jsfiddle version for OP.

The jsfiddle version just tweek OP's code to give her an insight of how it works

like image 64
Optional Avatar answered Nov 01 '22 10:11

Optional