Similar questions might have been asked already, but please read the details carefully.
I am using kind of a self-made autocomplete, and now I want to highlight the search term inside the result set. This works so far, but only on plain text. The problem is: I need to keep the html structure, if there is one in the result div. Please see my sample: currently I am loosing the included span's with the class bold. How can I keep them?
Thank you for any advice!
$('#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();
}
});
});
input[type="text"] {
width: 50%;
margin:10px;
padding: 5px;
float:left;
clear:left;
}
div{
float:left;
clear:left;
margin:10px 10px;
}
.bold {
font-weight: 700;
}
table td {
border: solid 1px #ccc;
padding: 3px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<input placeholder="Filter results" id="box" type="text" />
<div class="objType" id="item1">
<span class="bold">Accepted</span> Event Relation
<table>
<tr>
<td>Lorem</td>
<td>ipsum</td>
</tr>
</table>
</div>
<div class="objType" id="item2">
Case <span class="bold">Status</span> Value
<table>
<tr>
<td>Lorem</td>
<td>ipsum</td>
</tr>
</table>
</div>
<div class="objType" id="item3">
External <span class="bold">Data Source</span>
<table>
<tr>
<td>Lorem</td>
<td>ipsum</td>
</tr>
</table>
</div>
<div class="objType" id="item4">
Navigation <span class="bold">Link</span> Set
<table>
<tr>
<td>Lorem</td>
<td>ipsum</td>
</tr>
</table>
</div>
PS: a JSFiddle for this in addition might be helpful => https://jsfiddle.net/SchweizerSchoggi/6x3ak5d0/7/
The <mark> HTML element is used to highlight text, so is the perfect element for this use case.
The HTML <mark> tag is used to mark or highlight text that is of special interest or relevance in an HTML document. Browsers traditionally render the text found within the <mark> tag as text with a yellow background color.
Here is a possible base using only native javascript. This behave somewhat like CTRL+F.
This seems to preserve the <td>
elements.
The clear function replace the mark
elements by a wbr
element:
On UTF-8 encoded pages,
<wbr>
behaves like the U+200B ZERO-WIDTH SPACE code point. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/wbr
function mark(it){
clearIt()
if (it.length > 2){
let c = new RegExp(it, "ig")
main.innerHTML = main.innerHTML.replace(c,"<mark>"+it+"</mark>")
}
}
function clearIt(){
let b = new RegExp("mark>", "ig")
main.innerHTML = main.innerHTML.replace(b,"wbr>")
}
mark(search.value)
input[type="text"] {
width: 50%;
margin:10px;
padding: 5px;
float:left;
clear:left;
}
div{
float:left;
clear:left;
margin:10px 10px;
}
.bold {
font-weight: 700;
}
table td {
border: solid 1px #ccc;
padding: 3px;
}
<input onfocusout="clearIt()" oninput="mark(this.value)" value="Lorem" id="search" placeholder="Lorem">
<button onclick="mark(search.value)">SEARCH</button>
<button onclick="clearIt()">CLEAR</button>
<div id="main">
<div class="objType" id="item1">
<span class="bold">Accepted</span> Event Relation
<table>
<tr>
<td>Lorem</td>
<td>ipsum</td>
</tr>
</table>
</div>
<div class="objType" id="item2">
Case <span class="bold">Status</span> Value
<table>
<tr>
<td>Lorem</td>
<td>ipsum</td>
</tr>
</table>
</div>
<div class="objType" id="item3">
External <span class="bold">Data Source</span>
<table>
<tr>
<td>Lorem</td>
<td>ipsum</td>
</tr>
</table>
</div>
<div class="objType" id="item4">
Navigation <span class="bold">Link</span> Set
<table>
<tr>
<td>Lorem</td>
<td>ipsum</td>
</tr>
</table>
</div>
</div>
By the way the restored/cleared markup isn't the original, to fully restore it, you might need to copy the whole html before marking it up.
Using mark.js
plugin
$('#box').on('input', function() {
const valThis = this.value;
const options = {
filter: function(node, term, totalCounter, counter) {
$(node).parents('.objType').show()
return true
}
};
$('.objType').unmark({
done: function() {
$('.objType')
.toggle(valThis.length === 0)
.mark(valThis, options);
}
})
});
input[type="text"] {
width: 50%;
margin: 10px;
padding: 5px;
float: left;
clear: left;
}
div {
float: left;
clear: left;
margin: 10px 10px;
}
.bold {
font-weight: 700;
}
table td {
border: solid 1px #ccc;
padding: 3px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/jquery.mark.min.js" integrity="sha256-4HLtjeVgH0eIB3aZ9mLYF6E8oU5chNdjU6p6rrXpl9U=" crossorigin="anonymous"></script>
<input placeholder="Filter results" id="box" type="text" />
<div class="objType" id="item1">
<span class="bold">Accepted</span> Event Relation
<table>
<tr>
<td>Lorem</td>
<td>ipsum</td>
</tr>
</table>
</div>
<div class="objType" id="item2">
Case <span class="bold">Status</span> Value
<table>
<tr>
<td>Lorem</td>
<td>ipsum</td>
</tr>
</table>
</div>
<div class="objType" id="item3">
External <span class="bold">Data Source</span>
<table>
<tr>
<td>Lorem</td>
<td>ipsum</td>
</tr>
</table>
</div>
<div class="objType" id="item4">
Navigation <span class="bold">Link</span> Set
<table>
<tr>
<td>Lorem</td>
<td>ipsum</td>
</tr>
</table>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With