I have a series of title elements with text in them and a text input. When I put a string into the text input I want to highlight (wrapp in <span>
with a class) the responding character(s) within the title elements.
For example, if the text input contains the word "world" then I want that same word to be wrapped in high light span, eg
<div class="title">Hello <span class="highlight">World</span>! This is a title</div>
I have achieved this somewhatr with .replace()
eg:
// value is .val recieved from input
function highlight(value) {
$('.title').each(function() {
var original = $(this).text();
var newText = original.replace(value, "<span class='highlight'>" + value + "</span>");
$(this).html(newText);
});
};
However, this has a couple of limitations:
It doesn't work with capitalisation (if user enters world
the string World
won't be highlighted).
It only works on the first instance of the word (if there are multiple instances of the word world
in the string it will only highlight the first.
I tried to approach this a different way by inserting the <span>
s by getting the start and end positions of each inputted string, but this just created a mess:
function highlight(value, el) {
$(el).each(function() {
var original = $(this).text();
var startPosition = original.indexOf(value);
if (startPosition !== 0 || startPosition !== -1) {
var endPosition = (startPosition + value.length);
var newString = original.slice(0, startPosition)
+ '<span class="highlight">'
+ original.slice(startPosition, endPosition)
+ '</span>'
+ original.slice(startPosition);
$(this).html(newString);
}
});
};
Would anyone know if this is possible to do? Can anyone point me in the right direction?
(PS: I'd rather not use plugins if possible)
You can use a regexp
There is not much gained by only grabbing titles containing the word, since that will loop too
function highlight(value) {
$('.title').each(function() {
let textContent = $(this).text();
const wordArr = [...new Set(textContent.match(new RegExp(value, 'ig')))];
if (wordArr.length > 0) {
wordArr.forEach(word => textContent = textContent.split(word).join(`<span class="highlight">${word}</span>`));
$(this).html(textContent);
}
});
};
highlight("wor");
.highlight {
color: red
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1 class="title">Hello world</h1>
<h1 class="title">Hello World</h1>
<h1 class="title">Hello World Hello world</h1>