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>Becasue 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>Becuause 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) {

    // 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'));

    // 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();
  }

});