Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

278
Views
Highlight only matching text within a string (JQuery/Javascript)

I'm trying to highlight only matching text within a string at any point.

I have an input box which filters the results. Originally this worked fine to highlight the FIRST character, but the remit has changed to highlight the text within a string at any position.

Fiddle: Highlight matching text

It filters perfectly as it should, but highlights letters starting at the front, not the matching ones. I tried to use indexOf valThis to sort it out but I was probably doing it wrong.

Any help or pointers would be really appreciated.

$('#box').keyup(function () {

var valThis = this.value.toLowerCase();
var length  = this.value.length;

$('.objType').each(function () {
    var text  = $(this).text(),
        textL = text.toLowerCase(),
        //n = textL.indexOf(valThis);
     var htmlR = '<b>' + text.substr(0, length) + '</b>' + text.substr(length);

    if(textL.includes(valThis))
    {
      $(this).html(htmlR).show()
    }
    else
    {
        $(this).hide();
    }
});

});
about 4 years ago · Santiago Trujillo
3 answers
Answer question

0

The line

var htmlR = '<b>' + text.substr(0, length) + '</b>' + text.substr(length);

says "take length characters from the beginning of the string." You want to start with the first matching character, so you need to know where that is. So you want String#indexOf, not String#includes.

You also want to save the original text so you can compare against that, not against the text updated by the previous filter operation:

// Grab the original text
$(".objType").each(function() {               // ***
    $(this).data("original", $(this).text()); // ***
})                                            // ***
$('#box').keyup(function() {
  var valThis = this.value.toLowerCase();
  var length = this.value.length;

  $('.objType').each(function() {
    var text = $(this).data("original"),      // ***
      textL = text.toLowerCase(),
      index = textL.indexOf(valThis);         // ***

    if (index !== -1) {
      var htmlR = text.substr(0, index) + '<b>' + text.substr(index, length) + '</b>' + text.substr(index + length); // ***
      $(this).html(htmlR).show()
    } else {
      $(this).hide();
    }
  });
});

Updated Fiddle, snippet:

// Grab the original text
$(".objType").each(function() {               // ***
	$(this).data("original", $(this).text()); // ***
})                                            // ***
$('#box').keyup(function() {
  var valThis = this.value.toLowerCase();
  var length = this.value.length;

  $('.objType').each(function() {
    var text = $(this).data("original"),      // ***
      textL = text.toLowerCase(),
      index = textL.indexOf(valThis);         // ***

    if (index !== -1) {
      var htmlR = text.substr(0, index) + '<b>' + text.substr(index, length) + '</b>' + text.substr(index + length); // ***
      $(this).html(htmlR).show()
    } else {
      $(this).hide();
    }
  });
});
input[type="text"] {
  width: 50%;
  font-size: 110%;
  margin: 10px;
  padding: 5px;
  float: left;
  clear: left;
}

span {
  float: left;
  clear: left;
  margin: 10px 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input placeholder="Filter results" id="box" type="text" />

<span class="objType" id="item1">Accepted Event Relation</span>
<span class="objType" id="item2">Case Status Value</span>
<span class="objType" id="item3">External Data Source</span>
<span class="objType" id="item4">Navigation Link Set</span>

about 4 years ago · Santiago Trujillo Report

0

I guess you need to use a combination of indexOf, RegEx and substring to find and highlight the position of the word in each string.

See Fiddle here: https://jsfiddle.net/sxk7qj40/

$('#box').keyup(function () {
  const valThis = this.value;
  const length  = this.value.length;

  $('.objType').each(function () {
    const text  = $(this).text();
    const textL = text.toLowerCase();
    const position = textL.indexOf(valThis.toLowerCase());

    if (position !== -1) {
      const matches = text.substring(position, (valThis.length + position));
      const regex = new RegExp(matches, 'ig');
      const highlighted = text.replace(regex, `<mark>${matches}</mark>`);

      $(this).html(highlighted).show();
    } else {
      $(this).text(text);
      $(this).hide();
    }
  });
});

You would not want to hardcode your substring position at 0, as this will always begin at the start of the string regardless.

Instead, you need to use indexOf, which will return the starting position. You can then use that in the substring to find the starting point that you want to replace. Note that indexOf will return -1 if not found, hence the if statement.

Where to end though? Well, this will come in as a combination of the start position we already have + the string length you just typed.

NOTE: For my own convenience, I used some es2015 features like const and template literals, but you can't use es2015, simply run it through Babel, or manually replace these parts with var and string concatenation respectively.

Hope this makes sense?

e.g. ES5 safe:

$('#box').keyup(function () {
  var valThis = this.value;
  var length  = this.value.length;

  $('.objType').each(function () {
    var text  = $(this).text();
    var textL = text.toLowerCase();
    var position = textL.indexOf(valThis.toLowerCase());

    if (position !== -1) {
      var matches = text.substring(position, (valThis.length + position));
      var regex = new RegExp(matches, 'ig');
      var highlighted = text.replace(regex, '<mark>' + matches + '</mark>');

      $(this).html(highlighted).show();
    } else {
      $(this).text(text);
      $(this).hide();
    }
  });
});
about 4 years ago · Santiago Trujillo Report

0

Try this. It does non-destructive copying

$('#box').keyup(function () {
    var valThis = this.value.toLowerCase(),
        length  = this.value.length;

    $('.objType').each(function () {
        var text  = $(this).text(),
            textL = text.toLowerCase(),
            textStart = textL.indexOf(valThis),
            textEnd = textStart+valThis.length;
            //n = textL.indexOf(valThis);
         var htmlR = text.substring(0,textStart)+'<b>' + text.substring(textStart,textEnd) + '</b>' + text.substring(textStart+length);
        
        if(textStart!=-1) {
          $("#"+this.id+"r").html(htmlR).show()
        	$(this).hide();
        }
        else {
         $("#"+this.id+"r").empty();
        	$(this).hide();
        }
    });

});
input[type="text"] { 
    width: 50%;
    font-size: 110%;
    margin:10px;
    padding: 5px;
    float:left;
    clear:left;
}
span{
  float:left;
  clear:left;
  margin:10px 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input placeholder="Filter results" id="box" type="text" />

<span class="objType" id="item1">Accepted Event Relation</span><span id="item1r"></span>
<span class="objType" id="item2">Case Status Value</span><span id="item2r"></span>
<span class="objType" id="item3">External Data Source</span><span id="item3r"></span>
<span class="objType" id="item4">Navigation Link Set</span><span id="item4r"></span>

about 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!