Link to home
Start Free TrialLog in
Avatar of ROM
ROMFlag for United Kingdom of Great Britain and Northern Ireland

asked on

JQuery - I have a filtered list.. but only want to show first 3 matches

Hi Everyone,

I have a list that filters on a text field.
But I am struggling to work out how to hide anything over 3 (My real requirement includes over a 100 - my test has 5 :) ).

I am just unsure how to evalute if found and count of 3 or more... instead I just keep unhiding my filtered DIVs. Probably bc I do not understand the filtering properly.

Please help

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <script src="https://code.jquery.com/jquery-3.1.0.js"></script>
  <script>
  $(function(){
   
   
    $(document).ready(function(){
  $("#searchname").on("keyup", function() {
   var mycount = 0;
    var value = $(this).val().toLowerCase();
    $("#wrapper .empcard").filter(function() {
      $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
     //console.log("Count:"+mycount);     
    });   
   console.log("Typed");
   
   if (!$(this).val()){
      console.log("EMPTY");
      for (let element of document.getElementsByClassName("empcard")){
         element.style.display="none";
      }
   }
   else
   {
         console.log("STUFF");   
   }
   
  });
  
  //hide all cards on load
        for (let element of document.getElementsByClassName("empcard")){
         element.style.display="none";
      }
  
});
   
   
   
  });
  </script>
  <style>
   .empcard {
   border: 1px solid red;
   width:100px;
   }
  </style>
</head>
<body>


 
  <input type="text" id="searchname" value="">
<div id="parentwrapper">
<div id="wrapper">
   <div id="1" class="empcard"><div id="name">Francis Smith</div>
            <div id="dob">15/09/1963</div>
            <div id="dept">HR</div>
            <div id="appttime" class="apptstart">Appt Start: 10:00</div></div>
   <div id="2" class="empcard"><div id="name">Frank Doogle<div>
            <div id="dob">15/11/1963</div>
            <div id="dept">SALES</div>
            <div id="appttime" class="apptstart">Appt Start: 11:00</div></div>
   <div id="3" class="empcard"><div id="name">Alan Smith</div>
            <div id="dob">19/01/1970</div>
            <div id="dept">HR</div>
            <div id="appttime" class="apptstart">Appt Start: 12:00</div></div>
   <div id="4" class="empcard"><div id="nam4">Diane Smith</div>
            <div id="dob">29/09/1981</div>
            <div id="dept">IT</div>
            <div id="appttime" class="apptstart">Appt Start: 13:00</div></div>
   <div id="5" class="empcard"><div id="name5">Francis Cotton</div>
            <div id="dob">10/09/1992</div>
            <div id="dept">Admin</div>
            <div id="appttime" class="apptstart">Appt Start: 14:00</div></div>
</div>
</div>

</body>
</html>

Open in new window

So I need that to perform as described. But limit the display of EMPCARDS by X... X being 3 in my request.

So only the first 3 cards are found.

Many thanks in advance

R
Avatar of David H.H.Lee
David H.H.Lee
Flag of Malaysia image

you can use jQuery to show what you want conditionally without full iteration of each items.
eg:

$(".empcard").hide(); //hide all the div that referring the same css class name

Open in new window


//limit the display of EMPCARDS by X... X being 3 in my request.
$("div[class='empcard']")
  .filter(function() {
    return this.id.match(/[1-3]/);//since your div is naming with 1,2,3...
  })
  .show();

Open in new window

 
Full Sample:
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.1.0.js" > < /script>

</head>
<body>

<div id="parentwrapper">

<div id="wrapper">
   <div id="1" class="empcard"><div id="name">Francis Smith</div>
            <div id="dob">15/09/1963</div>
            <div id="dept">HR</div>
            <div id="appttime" class="apptstart">Appt Start: 10:00</div>    </div>
   <div id="2" class="empcard"><div id="name">Frank Doogle<div>
            <div id="dob">15/11/1963</div>
            <div id="dept">SALES</div>
            <div id="appttime" class="apptstart">Appt Start: 11:00</div></div>
   <div id="3" class="empcard"><div id="name">Alan Smith</div>
            <div id="dob">19/01/1970</div>
            <div id="dept">HR</div>
            <div id="appttime" class="apptstart">Appt Start: 12:00</div></div>
   <div id="4" class="empcard"><div id="nam4">Diane Smith</div>
            <div id="dob">29/09/1981</div>
            <div id="dept">IT</div>
            <div id="appttime" class="apptstart">Appt Start: 13:00</div></div>
<div id="5" class="empcard"><div id="name5">Francis Cotton</div>
            <div id="dob">10/09/1992</div>
            <div id="dept">Admin</div>
            <div id="appttime" class="apptstart">Appt Start: 14:00</div></div>
            
</div>
</div>

<script>
$(document).ready(function(){
  $(".empcard").hide();
  
$("div[class='empcard']")
  .filter(function() {
    return this.id.match(/[1-3]/);
  })
  .show();
  
});
</script>

</body>
</html>

Open in new window

Avatar of ROM

ASKER

Hi David thank you. You have removed the input field to generate the filter and the text match.
My actual implementation the cards are not called 1,2,3 they are more like 1000,1300,1211 etc.. so checking ID numbers will not work it is about after the first 3 then hiding that is why I was referring to count.

Thank you

R
I did the quick sample show to you how you can show the result via jquery and sample code that you shared.
Example:
//Your code...
for (let element of document.getElementsByClassName("empcard")){
         element.style.display="none";
      }

//can be replaced with one single line via jquery hide() method.
$(".empcard").hide(); //hide all the div that referring the same css class name

Open in new window


My actual implementation the cards are not called 1,2,3 they are more like 1000,1300,1211 etc.. so checking ID numbers will not work it is about after the first 3 then hiding that is why I was referring to count.
In this case, just tweak my existing filter() function to show first 3 matches. Do you need any special matching of your actual ID in this case? 
Avatar of ROM

ASKER

How would I tweak to say first 3?
Do a count? Rather than ID check... please help me with this bit.

Thank you

R
Since you didn't need to filter by any criteria, to display the first 3 matches you can use slice() function.

$("div[class='empcard']").slice(0,3).show();//show first 3 matched items only

Open in new window

Avatar of ROM

ASKER

I am filtering my criteria.. That is what is in my sample code. You removed it in your example.

What I would like is that BEFORE and as I filter.. I only see the first 3 items found.
Many thanks in advance

R
In this case, you can combine the filter criteria before use slice() function to display the three matched items only.

$("div[class='empcard']")
  .filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1);
 return $(this).id; }).slice(0,3).show();

Open in new window

Avatar of ROM

ASKER

I just tried this and it still shows 5 and does not limit by 3.

Please can you post back a working copy using my example.

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <script src="https://code.jquery.com/jquery-3.1.0.js"></script>
  <script>
  $(function(){
   
   
    $(document).ready(function(){
  $("#searchname").on("keyup", function() {
    var value = $(this).val().toLowerCase();
    $("div[class='empcard']").filter(function() {
      $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1);

    }).slice(0,3).show();
   
   console.log("Typed");
   
   if (!$(this).val()){
      console.log("EMPTY");
      for (let element of document.getElementsByClassName("empcard")){
         element.style.display="none";
      }
   }
   else
   {
         console.log("STUFF");   
         

   }
   
  });
  
  //hide all cards on load
     $("div[class='empcard']").hide()
  
});
   
   
   
  });
  </script>
  <style>
   .empcard {
   border: 1px solid red;
   width:100px;
   }
  </style>
</head>
<body>


 
  <input type="text" id="searchname" value="">
<div id="parentwrapper">
<div id="wrapper">
   <div id="1" class="empcard"><div id="name">Francis Smith</div>
            <div id="dob">15/09/1963</div>
            <div id="dept">HR</div>
            <div id="appttime" class="apptstart">Appt Start: 10:00</div></div>
   <div id="2" class="empcard"><div id="name">Frank Doogle<div>
            <div id="dob">15/11/1963</div>
            <div id="dept">SALES</div>
            <div id="appttime" class="apptstart">Appt Start: 11:00</div></div>
   <div id="3" class="empcard"><div id="name">Alan Smith</div>
            <div id="dob">19/01/1970</div>
            <div id="dept">HR</div>
            <div id="appttime" class="apptstart">Appt Start: 12:00</div></div>
   <div id="4" class="empcard"><div id="nam4">Diane Smith</div>
            <div id="dob">29/09/1981</div>
            <div id="dept">IT</div>
            <div id="appttime" class="apptstart">Appt Start: 13:00</div></div>
   <div id="5" class="empcard"><div id="name5">Francis Cotton</div>
            <div id="dob">10/09/1992</div>
            <div id="dept">Admin</div>
            <div id="appttime" class="apptstart">Appt Start: 14:00</div></div>
</div>
</div>

</body>
</html>

Open in new window


Thank you

R
Can I know what's your matching criteria? It seem like you're comparing the list items with lowercase using indexof function?

I may rewrite with the better matching rules
$(this).toggle($(this).text().toLowerCase().indexOf(value)

Open in new window

Try this:
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <script src="https://code.jquery.com/jquery-3.1.0.js"></script>
  <script>
  $(function(){
   
   
    $(document).ready(function(){
    
  $("#searchname").on("keyup", function() {
    var value = $(this).val().toLowerCase();
    
    $("div[class='empcard']").filter(function() {
      //$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1);
      if($(this).text().toLowerCase().indexOf(value) > -1){
        return $(this);
      }
    }).slice(0,3).show();
   
   console.log("Typed");
   
   if (!$(this).val()){
      console.log("EMPTY");
      //for (let element of document.getElementsByClassName("empcard")){
      //   element.style.display="none";
      //}
      $("div[class='empcard']").hide();
   }
   else
   {
         console.log("STUFF");   
   }
   
  })
  
  //hide all cards on load
     $("div[class='empcard']").hide();
  
});
   
   
   
  });
  </script>
  <style>
   .empcard {
   border: 1px solid red;
   width:100px;
   }
  </style>
</head>
<body>


 
  <input type="text" id="searchname" value="">
<div id="parentwrapper">
<div id="wrapper">
   <div id="1" class="empcard"><div id="name">Francis Smith</div>
            <div id="dob">15/09/1963</div>
            <div id="dept">HR</div>
            <div id="appttime" class="apptstart">Appt Start: 10:00</div></div>
   <div id="2" class="empcard"><div id="name">Frank Doogle<div>
            <div id="dob">15/11/1963</div>
            <div id="dept">SALES</div>
            <div id="appttime" class="apptstart">Appt Start: 11:00</div></div>
   <div id="3" class="empcard"><div id="name">Alan Smith</div>
            <div id="dob">19/01/1970</div>
            <div id="dept">HR</div>
            <div id="appttime" class="apptstart">Appt Start: 12:00</div></div>
   <div id="4" class="empcard"><div id="nam4">Diane Smith</div>
            <div id="dob">29/09/1981</div>
            <div id="dept">IT</div>
            <div id="appttime" class="apptstart">Appt Start: 13:00</div></div>
   <div id="5" class="empcard"><div id="name5">Francis Cotton</div>
            <div id="dob">10/09/1992</div>
            <div id="dept">Admin</div>
            <div id="appttime" class="apptstart">Appt Start: 14:00</div></div>
</div>
</div>

</body>
</html>

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Scott Fell
Scott Fell
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial