Hey there, does this catch your eye, or were you aiming for something different?
I concentrated on ensuring that you apply the show
classes to all parent <tr>
elements of matched items and remove the class on reset. Additionally, using $() tags around elements allows you to properly access their object model -- it seemed like you were attempting jQuery manipulation on the HTML elements directly.
CSS and HTML mostly unchanged. I'm not sure what the noMatches and .hint were meant to be -- some kind of feedback element?
HTML:
<!DOCTYPE html> <head>
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="600c0f0401130820544e51574e5151">[email protected]</a>/lodash.min.js">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1
/mark.min.js"></script>
</head>
<body>
<div class="input-wrap">
<label>
Search Titles:
<input id="myInput" type="text" required
placeholder="Search Titles" />
</label>
</div>
<div class="hintsWrap">
<p id="noMatches"></p>
<p class="hints">
Hints: type "not working", "working" ...
</p>
</div>
<table id="myTable" style="width: 100%" class="style1">
<tr>
<td>
<table><tr><td>not working</td></tr></table>
</td>
</tr>
<tr>
<td>
working
</td>
</tr>
</table>
</body>
CSS:
.input-wrap {
margin-bottom: 12px;
}
#myInput:invalid~.hints {
display: block;
}
#noMatches:empty, #noMatches:empty + .hints {
display: none;
}
.style1 tr {
display: none;
}
.style1 .show {
display: table-row;
}
mark {
background: orange;
font-weight: bold;
color: black;
}
JS:
var input, table, rows, noMatches, markInstance;
$(document).ready(function init() {
input = document.getElementById('myInput');
noMatches = document.getElementById('noMatches');
table = document.getElementById('myTable');
rows = table.querySelectorAll('tr');
markInstance = new Mark(table);
input.addEventListener('keyup', _.debounce(ContactsearchFX, 250));
});
function ContactsearchFX() {
resetContent();
markInstance.unmark({ done: highlightMatches });
}
function resetContent() {
$('.noMatchErrorText').remove();
//Remove this line to have a log of searches
//noMatches.textContent = '';
rows.forEach(function(row) {
$(row).removeClass('show');
});
}
function highlightMatches() {
markInstance.mark(input.value, {
each: showRow,
noMatch: onNoMatches,
})
}
function showRow(element) {
//alert(element);
$(element).parents('tr').addClass('show');
//Parents in case of several nestings
}
function onNoMatches(text) {
$('#myInput').after('<p class="noMatchErrorText">No records match: "' + text + '"</p>');
}
Further Nesting...
To address your comments on adding the ability to show the full sub-table, one would likely add this line in JS:
$(element).parents('tr').siblings('tr').addClass('show');
. This tells not only the parent table row to display properly but also any siblings of that parent that are
<tr>
tags, thus as long as the table is at least semi-normal, it'll show the table of the matched items. Try typing "Title" -- notice that it shows both tables. Then try "Title2," and note that it only shows the relevant table, as the
<tr>
tags of the first table are cousins, not siblings.
Also, I modified the HTML a bit. To have it work properly, you either need a parent table with id="myTable"
that all of the tables are under, OR you can set up myTable
as a class, perhaps with a few changes in the code to account for the fact that table
is an array.
New HTML (new content):
<!DOCTYPE html> <head>
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0e62616a6f7d664e3a203f39203f3f">[email protected]</a>/lodash.min.js">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1
/mark.min.js"></script>
</head>
<body>
<div class="input-wrap">
<label>
Search Titles:
<input id="myInput" type="text" required
placeholder="Search Titles" />
</label>
</div>
<div class="hintsWrap">
<p id="noMatches"></p>
<p class="hints">
Hints: type "Title1", "Title2", "Title3"...
</p>
</div>
<table id="myTable" style="width: 100%" class="style1">
<tr><td><table id="myTabledawa" style="width: 100%" class="style1">
<tr>
<td>
<br />
<table style="width: 100%">
<tr>
<td>Title1</td>
</tr>
<tr>
<td>
<img data-src- hq="/th?id=ODL.53f33f407ba28930afd14f3d9390813c&w=197& h=110&c=7&rs=1&qlt=80&dpr=1.76&pid=RichNav" alt="Iran seizes 'fuel-smuggling' tanker in Gulf" data- priority="2" id="emb6E9DDF7A" class="rms_img" src="https://www.bing.com /th?id=ODL.53f33f407ba28930afd14f3d9390813c&w=197&h=110& amp;c=7&rs=1&qlt=80&dpr=1.76&pid=RichNav" data- bm="50" width="197" height="110" />Description1</td>
</tr>
<tr>
<td>Date1</td>
</tr>
</table>
</td>
</tr></table></td></tr>
<tr><td>
<table id="myTable0" style="width: 100%" class="style1">
<tr>
<td>
<br />
<table style="width: 100%">
<tr>
<td>Title2</td>
</tr>
<tr>
<td>
<img data-src- hq="/th?id=ODL.22386d3e20f0b540ee8cc4874bdd4ba4&w=197&h=110&c=7&rs=1&qlt=80&dpr=1.76&pid=RichNav" alt="Flying ants: Swarms appear on weather map as 'rain'" data-priority="2" id="emb13B6D9078" class="rms_img" src="https://www.bing.com/th?id=ODL.22386d3e20f0b540ee8cc4874bdd4ba4&w=197&h=110&c=7&rs=1&qlt=80&dpr=1.76&pid=RichNav" data-bm="51" width="197" height="110" />Description2</td>
</tr>
<tr>
<td>Date2</td>
</tr>
</table>
</td>
</tr>
</table></td></tr>
</table>
</body>
CSS remains exactly the same.
New JS (small edit):
var input, table, rows, noMatches, markInstance;
$(document).ready(function init() {
input = document.getElementById('myInput');
noMatches = document.getElementById('noMatches');
table = document.getElementById('myTable');
rows = table.querySelectorAll('tr');
markInstance = new Mark(table);
input.addEventListener('keyup', _.debounce(ContactsearchFX, 250));
});
function ContactsearchFX() {
resetContent();
markInstance.unmark({ done: highlightMatches });
}
function resetContent() {
$('.noMatchErrorText').remove();
//Remove this line to have a log of searches
//noMatches.textContent = '';
rows.forEach(function(row) {
$(row).removeClass('show');
});
}
function highlightMatches() {
markInstance.mark(input.value, {
each: showRow,
noMatch: onNoMatches,
})
}
function showRow(element) {
//alert(element);
$(element).parents('tr').addClass('show'); $(element).parents('tr').siblings('tr').addClass('show');
//Parents incase of several nestings
}
function onNoMatches(text) {
$('#myInput').after('<p class="noMatchErrorText">No records match: "' + text + '"</p>');
}
Example Fiddle of Showing Full Table