JSFiddle - React, Tailwind, and code Playground
by joshmoto
HTML
<div id="faq">
<input type="search" placeholder="Filter FAQ" />
<ul class="repeater">
<li>
<div data-question>Whats the best way to search repeater fields?</div>
<div data-answer>Use some jQuery to filter repeater fields.</div>
</li>
<li>
<div data-question>Why do we use Advanced Custom Fields?</div>
<div data-answer>Because its awesome!</div>
</li>
<li>
<div data-question>Is this method fast?</div>
<div data-answer>Yes it works instantly on every keyup.</div>
</li>
<li>
<div data-question>Why do we use Wordpress?</div>
<div data-answer>Because it's a great content management system!</div>
</li>
<li class="filter-no-results">
No results found in repeater fields.
</li>
</ul>
</div>
CSS
#faq {
padding: 1rem;
}
INPUT[type="search"] {
margin-bottom: 1rem;
}
.repeater LI {
margin-bottom: 1rem;
}
[data-question]::before {
content: 'Q. ';
font-weight: bold;
}
[data-answer]::before {
content: 'A. ';
font-weight: bold;
}
.filter-visible {
display: block;
}
.filter-hidden {
display: none;
}
.filter-no-results {
display: none;
}
JavaScript
// faq repeater field filter
$('#faq').on('keyup', 'INPUT[type="search"]', function(event) {
// get our elements
let $faq = $(event.delegateTarget);
// get the search filter value
let search = $(this).val().replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
// get the repeater list in faq object
let $repeater = $('.repeater', $faq);
// items visible counter
let itemsVisible = 0;
// return false early if we dont have a list
if ($repeater.length < 1) return false;
// loop through each item in the repeater list
$("LI:not('.filter-no-results')", $repeater).each(function(key, item) {
$(this).html($(this).html().replaceAll(/<(\/?|\!?)(mark)>/g, ""));
// store our q and a text
let text = $(this).text();
// check if the item is visible using regular expression match
let itemVisible = text.match(new RegExp(search, 'i'));
// remove these classes
$(item).removeClass('filter-visible filter-hidden');
// check if we have a match
$(item).addClass('filter-' + (itemVisible ? 'visible' : 'hidden'));
// for each div inside the list item
$('div',this).each(function(){
// highlight the matched search text by wrapping it with a mark tag
let newText = $(this).html().replace(itemVisible, '<mark>' + itemVisible + '</mark>');
// update th
$(this).html(newText);
});
// if item is visible, increment our count
if (itemVisible) ++itemsVisible;
});
// check if we have no items visible then show hide no results message
if (itemsVisible === 0) {
$('LI.filter-no-results', $repeater).show();
} else {
$('LI.filter-no-results', $repeater).hide();
}
});