user14879075
user14879075

Reputation:

Show 'no matches' message when filtering a list returns no results

I have written a filtering system which compares the input value with the names of the list items. It only display items which match the input value.

What I want to do is to display a message like "No items found" if the input value doesn't match any name in the list items. How can I do that?

<input class="search-bar" type="search" name="search">

<div id="items">
  <ul>
    <li>tree</li>
    <li>apple</li>
    <li>car</li>
    <li>bike</li>
  </ul>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
   $(document).ready(function () {
        $('.search-bar').on("keyup", function () {
            var value = $(this).val().toLowerCase();
            $("#items ul li").filter(function () {
                $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1);
            });
        });
    });
</script>

Upvotes: 1

Views: 571

Answers (1)

Rory McCrossan
Rory McCrossan

Reputation: 337590

Firstly note that your use of filter() isn't quite correct. That method is intended to reduce a collection of elements based on a given condition, and return them. Given your use here that should be changed to an each() call instead.

However to do what you require you can store a reference to the li elements and then use filter() to find this which are visible. If there aren't any then you can display a 'No matches' warning. Try this:

jQuery($ => {
  let $li = $("#items ul li");
  let $noMatches = $('p.no-matches');

  $('.search-bar').on('input', function() {
    let value = $(this).val().toLowerCase();
    $li = $li.each(function() {
      $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1);
    });

    $noMatches.toggle(!$li.filter(':visible').length)
  });
});
.no-matches {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<input type="text" class="search-bar" />
<div id="items">
  <ul>
    <li>foo</li>
    <li>bar</li>
    <li>fizz</li>
    <li>buzz</li>
  </ul>
  <p class="no-matches">No items found</p>
</div>

Upvotes: 1

Related Questions