Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

284
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda