2

This is the text formatting before the search term entered.

enter image description here

After entering the term it loses the initial format (returns plain text) and duplicates the p text by the number of consecutive characters found (actually I know why is that, but again no idea how to avoid it):

enter image description here

What I want is to keep my initial html format, with those higlighted words and of course to avoid text duplication.


Here is my code snippet:

function searchHighlight(searchText) {
  if (searchText) {
    var content = $("p").text();
    // i for case insensitive, g search all matches
    var searchExpression = new RegExp(searchText, "ig"); 
    var matches = content.match(searchExpression);
    if (matches) {
      $("p").html(content.replace(searchExpression, function(match) {
        return "<span class='highlight'>" + match + "</span>";
      }));
    } else {
      $(".highlight").removeClass("highlight");
    }
  } else {
    $(".highlight").removeClass("highlight");
  }
}

$("#search").keyup(function() {
  // Return the value inside the text box
  searchHighlight($(this).val()); 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>


<p>
  <span>jQuery selektori</span> omogućavaju selektovanje i upravljanje HTML elementima.
  Selektori traže HTML elemente na osnovu njihovih identi೰katora, klasa, atributa, 
  vrednosti atributa i dr. Bazirani su na CSS selektorima, ali postoje još neki. 
  Svi selektori u <span>jQuery-ju</span> počinju sa znakom dolara i zagradama: $() .
</p>
<p id="paragraph">
  <span>Selektor $("*
        ")</span> selektuje sve elemente.
  <span>– Selektor $(this)</span> selektuje element na koji se odnosi funkcija koja ga obuhvata.
  <span>– Selektor $("p.intro")</span> selektuje sve p elemente sa atributom class="intro" . 
  Uvod u Veb i Internet Tehnologije 133
  <span>– Selektor $("p:first")</span> selektuje prvi p element.
  <span>– Selektor $("ul li:first")</span> selektuje prvi li element prvog ul elementa.
  <span>– Selektor $("ul li:first child")</span> selektuje prvi li element svakog ul elementa.
  <span>– Selektor $("[href]")</span> selektuje sve elemente koje imaju postavljen atribut 
  href . – Selektor $("a[target='_blank']") selektuje sve elemente a sa atributom target="_blank" 
  . – Selektor $("a[target!='_blank']") selektuje sve elemente a koji
  nemaju atribut target="_blank" . – Selektor

</p>
unknown
  • 461
  • 9
  • 23
  • 1
    Is there a reason that you are using removeClass, but are not using addClass? https://api.jquery.com/addClass/ – dmoore1181 Dec 23 '19 at 14:33
  • I am already apending the class ' + match + ' here. removeClass is for deleting higlights when removing search terms characters. Maybe I don't get you? – unknown Dec 23 '19 at 14:37

2 Answers2

2

When you are calling searchHighlight function, you are getting content of p, which will give you all the p. Also, when you say .text() it will give you plain text. That's why it was removing the initial format.

If you run a loop on all p and use .html() instead of .text() and also if you unwrap the highlighted content in start before getting html content, you will be able to achieve it.

See the Snippet below:

function searchHighlight(searchText) {
          if (searchText) {
          
              $("p").each(function() { 
                 $(this).find(".highlight").contents().unwrap();
                var content = $(this).html();
                
                var searchExpression = new RegExp(searchText + '(?=[^<>]*(<|$))', "ig"); // i for case insensitive, g search all matches
                var matches = content.match(searchExpression);
                if (matches) {
                  $(this).html(content.replace(searchExpression, function (match) {
                      return "<span class='highlight'>" + match + "</span>";
                  }));
                }
              });
          }else{
            $(".highlight").contents().unwrap();
            $(".highlight").remove();
          }
      }
$("#search").keyup(function () {
  searchHighlight($(this).val()); // Return the value inside the text box
});
p > span {
  color: red;
}

p#paragraph > span{
  color: orange;
}

span.highlight {
  font-weight: bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="search">

<p>
    <span>jQuery selektori</span> omogućavaju selektovanje i upravljanje HTML elementima. Selektori
    traže
    HTML elemente na osnovu njihovih identi೰katora, klasa, atributa,
    vrednosti atributa i dr. Bazirani su na CSS selektorima, ali postoje još neki. Svi
    selektori u <span>jQuery-ju</span> počinju sa znakom dolara i zagradama: $() .
</p>
<p id="paragraph">
    <span>Selektor $("*
        ")</span> selektuje sve elemente.
    <span>– Selektor $(this)</span> selektuje element na koji se odnosi funkcija koja ga obuhvata.
    <span>– Selektor $("p.intro")</span> selektuje sve p elemente sa atributom class="intro" .
    Uvod u Veb i Internet Tehnologije 133
    <span>– Selektor $("p:first")</span> selektuje prvi p element.
    <span>– Selektor $("ul li:first")</span> selektuje prvi li element prvog ul elementa.
    <span>– Selektor $("ul li:first child")</span> selektuje prvi li element svakog ul
    elementa.
    <span>– Selektor $("[href]")</span> selektuje sve elemente koje imaju postavljen atribut href . –
    Selektor $("a[target='_blank']") selektuje sve elemente a sa atributom target="_blank" . – Selektor
    $("a[target!='_blank']") selektuje sve elemente a koji nemaju atribut target="_blank" . – Selektor

</p>

There will always be some loopholes.

I am keeping Older jsFiddle. Here is the new jsFiddle.

Nimitt Shah
  • 4,477
  • 2
  • 10
  • 21
  • 1
    Love it. I just spent an hour on this and couldn't get it going. Good work! – jpmc Dec 23 '19 at 16:22
  • Thanks, love the people who appreciate :) – Nimitt Shah Dec 23 '19 at 16:24
  • @JamesMcGlone Nice, thank you! What I noticed is when searching for 's', it will unveil elements as well, and loose formatting, you can check it in the jsfiddle you sent me. Is it avoidable, or this solution is as good as it gets. – unknown Dec 23 '19 at 16:50
  • 1
    @T_Dejan This wasn't my work, it was Nimitt Shah, who said there was some loopholes... ah yes you are correct it reveals the tag. I really don't know, you can ask Nimitt tho, I'd be keen see how it is solved! – jpmc Dec 23 '19 at 17:05
  • Oh yes, I tagged you by accident, so @NimittShah, we are looking forward to hear from you. – unknown Dec 23 '19 at 17:09
  • 2
    T_Dejan and @JamesMcGlone : I have fixed it. Please have a look. The only change I made is RegExp – Nimitt Shah Dec 23 '19 at 17:48
  • 1
    I see, beautiful, thank you! For curiosity matters, is there a way to do it without appending regex rule. – unknown Dec 23 '19 at 17:49
0

Highlighing easy with mark.js

Getting to Know mark.js

mark.js is a text highlighter written in JavaScript. It can be used to dynamically mark search terms or custom regular expressions and offers you built-in options like diacritics support, separate word search, custom synonyms, iframes support, custom filters, accuracy definition, custom element, custom class name and more.

Look how easy, you don't need more than ten lines, the framework is ready and does everything for you, with possibilities of customization of your code, just enter the official page and see the documentation and examples. The chance of failures is much lower and you already do it right the first time. Just put the dependencies and use it easily.

$(function() {
  var $input = $("#search"), $context = $("p");  
  $input.on("input", function() {
    var term = $(this).val();
    $context.show().unmark();
    if (term) {
      $context.mark(term);
    }
  });
});
mark {
    color: black;
    background: greenyellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/jquery.mark.min.js">
</script>
<input id="search" type="text" />
<p>
  <span>jQuery selektori</span> 
  omogućavaju selektovanje i upravljanje HTML elementima. 
  Selektori traže HTML elemente na osnovu njihovih identi೰katora, 
  klasa, atributa, vrednosti atributa i dr. 
  Bazirani su na CSS selektorima, ali postoje još neki. Svi
  selektori u <span>jQuery-ju</span> počinju sa znakom dolara i zagradama: $() .
</p>
<p id="paragraph">
  <span>Selektor $("*
        ")</span> selektuje sve elemente.
  <span>– Selektor $(this)</span> 
  selektuje element na koji se odnosi funkcija koja ga obuhvata.
  <span>– Selektor $("p.intro")</span> 
  selektuje sve p elemente sa atributom class="intro" . 
  Uvod u Veb i Internet Tehnologije 133
  <span>– Selektor $("p:first")</span> 
  selektuje prvi p element.
  <span>– Selektor $("ul li:first")</span> 
  selektuje prvi li element prvog ul elementa.
  <span>– Selektor $("ul li:first child")</span> 
  selektuje prvi li element svakog ul elementa.
  <span>– Selektor $("[href]")</span> 
  selektuje sve elemente koje imaju postavljen atribut href . – 
  Selektor $("a[target='_blank']") selektuje sve elemente 
  a sa atributom target="_blank" . 
  – Selektor $("a[target!='_blank']") selektuje sve elemente a koji
  nemaju atribut target="_blank" . – Selektor
</p>

Why using a selfmade highlighting function is a bad idea:

Community
  • 1
  • 1
ℛɑƒæĿᴿᴹᴿ
  • 4,983
  • 4
  • 38
  • 58