1

If searched keyword matches I am able to show the matched input text and its related div with category name. Now what I am trying is to search over category names as well. If searched keyword matches with the category name this div should visible. also if searched keyword matches with the input names this is also visible with its category name.

$('.bar-input').on('keyup', function() {
            var search_input = $(this).val().toLowerCase();
            var tags = $('.wrap label');
            var count = tags.length;
            var text_input = $(this).val().length;
            var category = $('.category-type');
           

            // // searching for tags
            for (i = 0; i < count; i++) {
                if (!search_input || tags[i].textContent.toLowerCase().indexOf(search_input) > -1) {
                    tags[i].parentNode.style['display'] = 'block';

                } else {
                    tags[i].parentNode.style['display'] = 'none';
                }
            }

            // If no tags found category will be hidden 
            $(".category").not(".stcw-screen").map(function() {
                let flag = true;
                $(this).find('.wrap').map(function() {
                    if ($(this).css("display") != "none") {
                        flag = false;
                    }
                });
                if (flag) {
                    $(this).css("display", "none");
                } else {
                    $(this).css("display", "block");
                }
            });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input class="bar-input" type="text" placeholder="search">
    <div class="category">
        <div class="category-name">
            <h5>Country</h5>
        </div>
        <div class="options">
            <div class="wrap">
                 <label><input type="checkbox">America</label>
            </div><div class="wrap">
                <label><input type="checkbox">France</label>
           </div>
        </div>
    </div>
    <div class="category">
        <div class="category-type">
            <h5>Sports</h5>
        </div>
        <div class="options">
            <div class="wrap">
                 <label><input type="checkbox">Football</label>
            </div><div class="wrap">
                <label><input type="checkbox">Cricket</label>
           </div>
        </div>
    </div>
    <div class="category">
        <div class="category-type">
            <h5>Operating system </h5>
        </div>
        <div class="options">
            <div class="wrap">
                 <label><input type="checkbox">linux</label>
            </div><div class="wrap">
                <label><input type="checkbox">windows</label>
           </div>
        </div>
    </div>
David
  • 13
  • 2

1 Answers1

0

To do what you require you can loop through each category and first determine if the .category-type matches the search term using a case-insensitive implementation of :contains and then display that section with all options visible, or if not you can look at each option in turn using the same :icontains() selector and show them individually.

The logic would look something like this:

// case-insensitive :contains implementation (credit: https://stackoverflow.com/a/8747204/519413)
jQuery.expr[':'].icontains = (a, i, m) => $(a).text().toUpperCase().indexOf(m[3].toUpperCase()) >= 0;

var $categories = $('.category');
var $types = $('.category-type');

$('.bar-input').on('input', function() {
  var search_input = $(this).val().toLowerCase().trim();
  if (search_input.length == 0) {
    // no search term entered, reset state to show all items
    $('.wrap label').add($types).show()
    return;
  }

  $categories.each((i, category) => {
    let $cat = $(category);
    let $type = $cat.find('.category-type').hide();
    let $labels = $cat.find('.wrap label').hide();

    if ($type.is(`:icontains("${search_input}")`)) {
      // match on category type, show category-type and all child options
      $type.add($labels).show();
    } else {
      // no match on category, show only if match on child option
      let $matches = $labels.filter(`:icontains("${search_input}")`).show();
      $type.toggle($matches.length > 0);
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input class="bar-input" type="text" placeholder="search">

<div class="category">
  <div class="category-type">
    <h5>Country</h5>
  </div>
  <div class="options">
    <div class="wrap">
      <label><input type="checkbox">America</label>
    </div>
    <div class="wrap">
      <label><input type="checkbox">France</label>
    </div>
  </div>
</div>
<div class="category">
  <div class="category-type">
    <h5>Sports</h5>
  </div>
  <div class="options">
    <div class="wrap">
      <label><input type="checkbox">Football</label>
    </div>
    <div class="wrap">
      <label><input type="checkbox">Cricket</label>
    </div>
  </div>
</div>
<div class="category">
  <div class="category-type">
    <h5>Operating system </h5>
  </div>
  <div class="options">
    <div class="wrap">
      <label><input type="checkbox">linux</label>
    </div>
    <div class="wrap">
      <label><input type="checkbox">windows</label>
    </div>
  </div>
</div>
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339