Home > Net >  How to filter through cards in HTML
How to filter through cards in HTML

Time:03-30

I'm trying to create a site which allows you to search through different profiles by their first name. I'm trying to use bootstraps "data-title" to search through, but it isn't working. Right now it just displays the entire row.

This is my main code

<!--create search bar-->
<div >
 <!--<a href="#about">Search Profies</a> -->
  <input type="text" placeholder="Search.." id="search-box">
  <button type="searchButton">Search</button>
  <button type="recButton">Recommend</button>
  <button type="filterButton">Filter</button>
  

  <!--create line break before profiles-->

  <div >
      <hr>

  </div>

  <!---create row 1 of profiles-->

  <div class ="container-fluid">
    <div >
      <div class ="col-2" >
        <div  data-title="terry">
          <img src="https://api.time.com/wp-content/uploads/2017/12/terry-crews-person-of-year-2017-time-magazine-2.jpg"  alt="Avatar" style="height: 150px; width: 188px;">
            <h6><b>Terry Crews</b></h6>
        </div> 
      </div>
      <div class ="col-2">
          <div  data-title="cute">
            <img src="https://api.time.com/wp-content/uploads/2017/12/terry-crews-person-of-year-2017-time-magazine-2.jpg" style = "width: 150px;height: 150px;"alt="">
            <h3>cute animal</h3>
         </div>
     </div>
     <div class ="col-2">
      <div >
        <img src="https://api.time.com/wp-content/uploads/2017/12/terry-crews-person-of-year-2017-time-magazine-2.jpg" alt="Avatar" style="height: 150px; width: 188px;">
        <h6><b>Terry Crews</b></h6>
    </div>
 </div>
 <div class ="col-2">
  <div >
    <img src="https://api.time.com/wp-content/uploads/2017/12/terry-crews-person-of-year-2017-time-magazine-2.jpg" alt="Avatar" style="height: 150px; width: 188px;">
    <h6><b>Terry Crews</b></h6>
</div>
</div>

This is my script


  <script>

let searchBox = document.querySelector('#search-box');
   let images = document.querySelectorAll('.container .row .col-2 .card');
   
   searchBox.oninput = () =>{
      images.forEach(hide => hide.style.display = 'none');
      let value = searchBox.value;
      images.forEach(filter =>{
         let title = filter.getAttribute('data-title');
         if(value == title){
            filter.style.display = 'block';
         }
         if(searchBox.value == ''){
            filter.style.display = 'block';
         }
      });
   };


  </script>

I have tried to use data-title in col-2, and the cards but neither work.

CodePudding user response:

If this is not what you are looking to accomplish, let me know and I can adjust my answer.

You need to iterate over the .card elements and then compare the event.targets value with the elements dataset.title while iterating over the nodelist, if there is a match, then display the node.

You could check the el.dataset.title and make sure it includes the value being typed as the user types ( keyup event ), if each value typed into the input is included in the dataset attribute => val.dataset.title.includes(e.target.value) then we show the element.

let searchBox = document.querySelector('#search-box');
let images = document.querySelectorAll('.card');


function getResults(e) {
  images.forEach(val => {
    val.style.display = 'none';
    val.dataset.title.includes(e.target.value) ?
      val.style.display = 'block' : null;
  })
}

searchBox.addEventListener('keyup', getResults)
<!--create search bar-->
<div >
  <!--<a href="#about">Search Profies</a> -->
  <input type="text" placeholder="Start typing to search..." id="search-box">
  <button type="searchButton">Search</button>
  <button type="recButton">Recommend</button>
  <button type="filterButton">Filter</button>


  <!--create line break before profiles-->

  <div >
    <hr>

  </div>

  <!---create row 1 of profiles-->

  <div >
    <div >
      <div >
        <div  data-title="white">
          <img src="https://cdn.pixabay.com/photo/2014/11/30/14/11/cat-551554_960_720.jpg"  alt="Avatar" style="height: 150px;">
          <h6><strong>White Kitty</strong></h6>
        </div>
      </div>
      <div >
        <div  data-title="black">
          <img src="https://cdn.pixabay.com/photo/2015/03/27/13/16/maine-coon-694730_960_720.jpg" style="height: 150px;" alt="">
          <h6>Black Kitty</h6>
        </div>
      </div>
      <div >
        <div  data-title="orange">
          <img src="https://cdn.pixabay.com/photo/2014/04/13/20/49/cat-323262_960_720.jpg"  alt="Avatar" style="height: 150px;">
          <h6><b>Orange Kitty</b></h6>
        </div>
      </div>
      <div >
        <div  data-title="gray">
          <img src="https://cdn.pixabay.com/photo/2015/11/16/14/43/cat-1045782_960_720.jpg"  alt="Avatar" style="height: 150px;">
          <h6><b>Gray Kitty</b></h6>
        </div>
      </div>

CodePudding user response:

You have 2 problems. The "card" class and title data attribute seem to be inconsistently applied and your .container .row .col-2 .card selector references .container which does not exist in the supplied HTML.

Assuming that the class "card" will be applied consistently we can do this easier by toggling a CSS Class based on the match.

const searchBox = document.getElementById("search-box");
//NOTE: the selector has been changed to match your HTML.
const images = document.querySelectorAll('.container-fluid .row .col-2 .card');

function filter(filterString) {
  //loop the images
  images.forEach((el) => {
    //toggle the hidden class based on match
    el.classList.toggle("filtered", filterString !== "" && el.dataset.title !== filterString)
  });
}

//Add the event listener, this is the prefered way to do it
//as existing listeners are preservered and can be removed with "removeEventListener"
searchBox.addEventListener("input", function() {
  filter(this.value)
});
.filtered {
  display: none;
}
<div >
  <!--<a href="#about">Search Profies</a> -->
  <input type="text" placeholder="Search.." id="search-box">
  <button type="searchButton">Search</button>
  <button type="recButton">Recommend</button>
  <button type="filterButton">Filter</button>


  <!--create line break before profiles-->

  <div >
    <hr>

  </div>

  <!---create row 1 of profiles-->

  <div >
    <div >
      <div >
        <div  data-title="terry">
          <img src="https://api.time.com/wp-content/uploads/2017/12/terry-crews-person-of-year-2017-time-magazine-2.jpg"  alt="Avatar" style="height: 150px; width: 188px;">
          <h6><b>Terry Crews</b></h6>
        </div>
      </div>
      <div >
        <div  data-title="cute">
          <img src="https://api.time.com/wp-content/uploads/2017/12/terry-crews-person-of-year-2017-time-magazine-2.jpg" style="width: 150px;height: 150px;" alt="">
          <h3>cute animal</h3>
        </div>
      </div>
      <div >
        <div  data-title="not cute">
          <img src="https://api.time.com/wp-content/uploads/2017/12/terry-crews-person-of-year-2017-time-magazine-2.jpg"  alt="Avatar" style="height: 150px; width: 188px;">
          <h6><b>Terry Crews</b></h6>
        </div>
      </div>
      <div >
        <div  data-title="terry">
          <img src="https://api.time.com/wp-content/uploads/2017/12/terry-crews-person-of-year-2017-time-magazine-2.jpg"  alt="Avatar" style="height: 150px; width: 188px;">
          <h6><b>Terry Crews</b></h6>
        </div>
      </div>
    </div>
  </div>

  • Related