Home > Mobile >  Why won't my error message show when a filter returns empty
Why won't my error message show when a filter returns empty

Time:12-13

I have a test shop with some basic filters, but I want to display an error message if one or more of the filters returns empty. If you click on the (this will not work) button you will see an empty page but want the error message to show there, the error message shows up on the index but not on the empty page as needed.

What am I doing wrong?

let message = $("p");
message.hide();

$('.filter-list button').click(function() {
   $(this).toggleClass('active');

   let filterArr = $(".filter-list button.active").map(function() {
       return $(this).data('filter');
   });

   let filterItem = $(".item");

   if(filterArr.length <= 0) {
       filterItem.show();
       message.show();
   } else {
       filterItem.hide();
       message.hide();
       filterItem.each(function () {
           for(let i = 0; i < filterArr.length; i  ) {
               if($(this).hasClass(filterArr[i])) {
                   $(this).show();
               }
           }
       });
   }
});
$('.clear-all').click(function() {
    message.hide();
    $('.filter-list button').removeClass('active');
    $(".item").show();
});

let message = $("p");
message.hide();

$('.filter-list button').click(function() {
  $(this).toggleClass('active');

  let filterArr = $(".filter-list button.active").map(function() {
    return $(this).data('filter');
  });

  let filterItem = $(".item");

  if (filterArr.length <= 0) {
    filterItem.show();
    message.show();
  } else {
    filterItem.hide();
    message.hide();
    filterItem.each(function() {
      for (let i = 0; i < filterArr.length; i  ) {
        if ($(this).hasClass(filterArr[i])) {
          $(this).show();
        }
      }
    });
  }
});
$('.clear-all').click(function() {
  message.hide();
  $('.filter-list button').removeClass('active');
  $(".item").show();
});
body {
  background-color: #ccc;
  font-family: arial;
}

button {
  background-color: #fff;
  border: 0;
  padding: 1rem;
  margin-right: 5px;
}

.content-control {
  background-color: #eee;
  display: flex;
}

.grid {
  display: flex;
}

.item {
  background-color: #f1f1f1;
  width: 200px;
  height: 200px;
  margin: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
  <h1>Test shop filters</h1>
  <div >
    <div >
      <button  data-filter="filter1">Filter 1</button>
      <button  data-filter="filter2">Filter 2</button>
      <button  data-filter="filter3">Filter 3</button>
      <button  data-filter="filter4">Filter 4</button>
      <button  data-filter="filter6">This will not work</button>
    </div>
    <button >Clear all</button>
  </div>
  <div >
    <div >
      <div >filter1</div>
      <div >filter1</div>
      <div >filter2</div>
      <div >filter2</div>
      <div >filter3</div>
      <div >filter3</div>
      <div >filter4</div>
      <div >filter5</div>
      <div >filter5</div>
    </div>
    <p>Error this filter does not exist</p>
  </div>
</div>

CodePudding user response:

Instead of a loop, use .filter() to get all the items that match the class you're filtering with. Then you can test the length of this to see if it matches anything, and display an error message if not.

let message = $("p");
message.hide();

$('.filter-list button').click(function() {
  $(this).toggleClass('active');

  let filterArr = $(".filter-list button.active").map(function() {
    return $(this).data('filter');
  });

  let filterItem = $(".item");
  filterItem.hide();
  message.hide();
  filterArr.each((i, filter) => {
    let theseItems = filterItem.filter(`.${filter}`);
    if (theseItems.length == 0) {
      message.show();
    } else {
      theseItems.show();
    }
  });
});

$('.clear-all').click(function() {
  message.hide();
  $('.filter-list button').removeClass('active');
  $(".item").show();
});
body {
  background-color: #ccc;
  font-family: arial;
}

button {
  background-color: #fff;
  border: 0;
  padding: 1rem;
  margin-right: 5px;
}

.content-control {
  background-color: #eee;
  display: flex;
}

.grid {
  display: flex;
}

.item {
  background-color: #f1f1f1;
  width: 200px;
  height: 200px;
  margin: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
  <h1>Test shop filters</h1>
  <div >
    <div >
      <button  data-filter="filter1">Filter 1</button>
      <button  data-filter="filter2">Filter 2</button>
      <button  data-filter="filter3">Filter 3</button>
      <button  data-filter="filter4">Filter 4</button>
      <button  data-filter="filter6">This will not work</button>
    </div>
    <button >Clear all</button>
  </div>
  <div >
    <div >
      <div >filter1</div>
      <div >filter1</div>
      <div >filter2</div>
      <div >filter2</div>
      <div >filter3</div>
      <div >filter3</div>
      <div >filter4</div>
      <div >filter5</div>
      <div >filter5</div>
    </div>
    <p>Error this filter does not exist</p>
  </div>
</div>

CodePudding user response:

From what I can see your issue is around this

let notFound = true;

 filterItem.hide();
    message.hide();
    filterItem.each(function() {
      for (let i = 0; i < filterArr.length; i  ) {
        if ($(this).hasClass(filterArr[i])) {
          $(this).show();
          notFound =false;
        }
      }
    });
    if(notFound){
      filterItem.hide();
      message.show();
    }

Where your found or not found items should be evaluated differently

  • Related