Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript Pagination & Content Filter

Neil Bircumshaw
seal-mask
.a{fill-rule:evenodd;}techdegree
Neil Bircumshaw
Full Stack JavaScript Techdegree Student 14,597 Points

Really struggling here... need message to show when all list items have a display set to none

So I've tried to code this but have been unsuccessful. nothing I seem to pass into an if statement seems to be correct and won't run it how I am intending it. If maybe there was a way to check if all li elements in a loop passed the condition that they must all have a display set to none, then the code might work. here is my HTML followed by my JS for this task. As you will see in the code, there are buttons that when clicked hide the list items, and when the page loads hide list items. There is also an input field made to be a search bar which will hide list items if they are not the same as what is written by the user in the input field.

HTML:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>Students</title>
    <link rel="stylesheet" href="css/reset.css">
    <link rel="stylesheet" href="css/design.css">
  </head>
  <body>
    <div class="page">
      <div class="page-header cf">
        <h2>Students</h2>


      </div>
      <ul class="student-list">
        <li class="student-item cf">
            <div class="student-details">
                <img class="avatar" src="https://randomuser.me/api/portraits/thumb/women/67.jpg">
                <h3>iboya vat</h3>
                <span class="email">iboya.vat@example.com</span>
            </div>
            <div class="joined-details">
                   <span class="date">Joined 07/15/15</span>
           </div>
        </li>
        <li class="student-item cf">
            <div class="student-details">
                <img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/75.jpg">
                <h3>aapo niskanen</h3>
                <span class="email">aapo.niskanen@example.com</span>
            </div>
            <div class="joined-details">
                   <span class="date">Joined 06/15/12</span>
           </div>
        </li>
        <li class="student-item cf">
            <div class="student-details">
                <img class="avatar" src="https://randomuser.me/api/portraits/thumb/men/34.jpg">
                <h3>phillip cox</h3>
                <span class="email">phillip.cox@example.com</span>
            </div>
            <div class="joined-details">
                   <span class="date">Joined 09/11/14</span>
           </div>
        </li>
        <li class="student-item cf">
            <div class="student-details">
                <img class="avatar" src="https://randomuser.me/api/portraits/thumb/women/38.jpg">
                <h3>zilda moreira</h3>
                <span class="email">zilda.moreira@example.com</span>
            </div>
            <div class="joined-details">
                   <span class="date">Joined 07/15/15</span>
           </div>
        </li>
        <li class="student-item cf">
            <div class="student-details">
                <img class="avatar" src="https://randomuser.me/api/portraits/thumb/women/23.jpg">
                <h3>lilou le gall</h3>
                <span class="email">lilou.le gall@example.com</span>

this type of code repeats 50 more times for different list item data.

// selecting elements and creating elements

var ul = document.querySelector(".student-list");
var li = ul.children;
var button1 = document.createElement("button");
var button2 = document.createElement("button");
var button3 = document.createElement("button");
var button4 = document.createElement("button");
var button5 = document.createElement("button");
var button6 = document.createElement("button");
var page = document.querySelector(".page");
var header = document.querySelector(".page-header");
var searchButton = document.createElement("button");
var input = document.createElement("input");
var message = document.createElement("div");
var allLi = document.querySelectorAll("li.student-item cf")


//when the page loads only 10 items from the list of items will be displayed, the rest will be hidden.

window.addEventListener("load", function(){
    for (var i = 0; i < li.length; i++){
        if (i >= 10){
            li[i].style.display = "none"
        }

        else {li[i].style.display = "block"
        }
    }

})

//giving the varibles of the selected items from the HTML properties.

button1.textContent = "1";
button1.className = "buttons highlighted"

button2.textContent = "2";
button2.className = "buttons"

button3.textContent = "3";
button3.className = "buttons"

button4.textContent = "4";
button4.className = "buttons"

button5.textContent = "5";
button5.className = "buttons"

button6.textContent = "6";
button6.className = "buttons"

searchButton.textContent = "Search";
searchButton.className = "searchButton";

input.type = "text";
input.name = "searchBar";
input.className = "searchBar";
input.value = "Search for students...";

message.textContent = "Sorry, there was noone by that name in our system!";
message.className = "message";
message.style.display = "none";


//appending the selected HTML elements to a parent.

page.appendChild(button1);
page.appendChild(button2);
page.appendChild(button3);
page.appendChild(button4);
page.appendChild(button5);
page.appendChild(button6);
header.appendChild(searchButton);
header.appendChild(input);
header.appendChild(message)


/*this button will only show the first 10 items, the rest will be hidden. 
It will also have the "highlighed" class attached to it when it is clicked. Futhermore it
will scroll to the top of the page when clicked, just for user convenience. 


*/

button1.addEventListener("click", function(){
    for (var i = 0; i < li.length; i++){
        if (i >= 10){
            li[i].style.display = "none"
        }

        else {li[i].style.display = "block"
        }
    }

    button1.className = "buttons highlighted";
    button2.className = "buttons ";
    button3.className = "buttons";
    button4.className = "buttons";
    button5.className = "buttons";
    button6.className = "buttons";

    document.body.scrollTop = document.documentElement.scrollTop = 0;

})


/*this button will only show the next set of 10 items, the rest will be hidden. 
It will also have the "highlighed" class attached to it when it is clicked. Futhermore it
will scroll to the top of the page when clicked, just for user convenience. 


*/



button2.addEventListener("click", function(){
    for (var i = 0; i < li.length; i++){
        if (i < 11 ){
            li[i].style.display = "none"

        }
        else if (i >20){li[i].style.display = "none"}

        else {li[i].style.display = "block"
        }
    }
    button1.className = "buttons";
    button2.className = "buttons highlighted";
    button3.className = "buttons";
    button4.className = "buttons";
    button5.className = "buttons";
    button6.className = "buttons";

    document.body.scrollTop = document.documentElement.scrollTop = 0;
})

/*this button will only show the next set of 10 items, the rest will be hidden. 
It will also have the "highlighed" class attached to it when it is clicked. Futhermore it
will scroll to the top of the page when clicked, just for user convenience. 


*/

button3.addEventListener("click", function(){
    for (var i = 0; i < li.length; i++){
        if (i < 21 ){
            li[i].style.display = "none"

        }
        else if (i > 30){li[i].style.display = "none"}

        else {li[i].style.display = "block"
        }
    }

    button1.className = "buttons";
    button2.className = "buttons";
    button3.className = "buttons highlighted";
    button4.className = "buttons";
    button5.className = "buttons";
    button6.className = "buttons";

    document.body.scrollTop = document.documentElement.scrollTop = 0;

})

/*this button will only show the next set of 10 items, the rest will be hidden. 
It will also have the "highlighed" class attached to it when it is clicked. Futhermore it
will scroll to the top of the page when clicked, just for user convenience. 


*/

button4.addEventListener("click", function(){
    for (var i = 0; i < li.length; i++){
        if (i < 31 ){
            li[i].style.display = "none"

        }
        else if (i > 40){li[i].style.display = "none"}

        else {li[i].style.display = "block"
        }
    }

    button1.className = "buttons";
    button2.className = "buttons";
    button3.className = "buttons";
    button4.className = "buttons highlighted";
    button5.className = "buttons";
    button6.className = "buttons";

    document.body.scrollTop = document.documentElement.scrollTop = 0;

})

/*this button will only show the next set of 10 items, the rest will be hidden. 
It will also have the "highlighed" class attached to it when it is clicked. Futhermore it
will scroll to the top of the page when clicked, just for user convenience. 


*/

button5.addEventListener("click", function(){
    for (var i = 0; i < li.length; i++){
        if (i < 41 ){
            li[i].style.display = "none"

        }
        else if (i > 50){li[i].style.display = "none"}

        else {li[i].style.display = "block"
        }
    }

    button1.className = "buttons";
    button2.className = "buttons";
    button3.className = "buttons";
    button4.className = "buttons";
    button5.className = "buttons highlighted";
    button6.className = "buttons";

    document.body.scrollTop = document.documentElement.scrollTop = 0;

})

/*this button will only show the next set of 10 items, the rest will be hidden. 
It will also have the "highlighed" class attached to it when it is clicked. Futhermore it
will scroll to the top of the page when clicked, just for user convenience. 


*/

button6.addEventListener("click", function(){
    for (var i = 0; i < li.length; i++){
        if (i < 51 ){
            li[i].style.display = "none"

        }
        else if (i > 60){li[i].style.display = "none"}

        else {li[i].style.display = "block"
        }
    }

    button1.className = "buttons";
    button2.className = "buttons";
    button3.className = "buttons";
    button4.className = "buttons";
    button5.className = "buttons";
    button6.className = "buttons highlighted";


    document.body.scrollTop = document.documentElement.scrollTop = 0;

})

// this will make the searchbar called "input" become an empty string when clicked.

input.addEventListener("click", function (){
    input.value = "";

})

/* this will only show list items when they match with what is written by the user in the 
search bar by looking at the list items innterHTML*/

searchButton.addEventListener("click", function(){
    for (var i = 0; i < li.length; i++){


        if (li[i].innerHTML.toUpperCase().includes(input.value.toUpperCase())){
            li[i].style.display = "block"
        }



        else {li[i].style.display = "none"
        }



}}) 

I will add the css too.

body{
  background-color: #e1f1f6;
  font-family: Helvetica, sans-serif;
  color: #222;
}

.page{
  margin: 50px auto;
  width: 70%;
  background-color: #fff;
  border-radius: 5px;
  padding: 50px;

}
.buttons {
    position:relative;
    left:32em;
    margin:0.5em;   
    display:block;

    float:left;

}

.page-header{
  margin-bottom: 20px;
}
  .page-header h2{
    float: left;
    font-size: 22px;
    text-transform: uppercase;
    font-weight: bold;
    color: #555;
  }

  .page-header .student-search{
    float: right;
  }

    .page-header .student-search input{
      border-radius: 5px;
      border: 1px solid #eaeaea;
      padding: 8px 15px;
      font-size: 14px;
    }

    .page-header .student-search button{
      border-radius: 5px;
      border: 1px solid #eaeaea;
      padding: 8px 15px;
      font-size: 14px;
      background-color: #4ba6c3;
      color: #fff
    }

.student-list{}

  .student-item{
    margin: 0 0 20px 0;
    padding: 0 0 20px 0;
    border-bottom: 1px solid #eaeaea;
  }

    .student-details{
      width: 50%;
      float: left;
    }

      .student-details .avatar{
        width: 40px;
        height: auto;
        border-radius: 20px;
        float: left;
        margin-right: 14px
      }

      .student-details h3{
        margin: 4px 0 2px 0;
        font-weight: bold;
        color: #4ba6c3;
      }

      .student-details .email{
        color: #888;
        font-size: 14px;
      }


    .joined-details{
      width: 50%;
      float: left;
      text-align: right;
    }

      .joined-details .date{
        margin-top: 15px;
        display: block;
        font-size: 14px;
        color: #999;
      }

  .student-item:last-child{
    margin: 0;
    padding: 0;
    border-bottom: none;
  }

.pagination{
  margin: 40px 0 0 0;
  text-align: center;
}

  .pagination li{
    display: inline;
  }

    .pagination li a{
      border: 1px solid #eaeaea;
      border-radius: 5px;
      padding: 3px 8px;
      text-decoration: none;
      color: #4ba6c3;
    }

    .pagination li a.active,
    .pagination li a:hover{
      background-color: #4ba6c3;
      color: #fff;
    }

    /*css properties for the javascript objects*/

    .buttons {
    position:relative;
    left:38%;
    margin:0.5em;   
    display:block;
    float:left;
    border-radius:20%;
    background-color:white;
    color:#4ba6c3;
    font-weight:bold;
    outline: none;
    }

    .buttons:hover {
    cursor: pointer;
}

    .highlighted {background-color:#4ba6c3;
    color:white;}

    .searchButton {
    background-color:#4ba6c3;
    color:white;
    border-radius:8%;
    font-weight:bold;
    padding: 0.5em 1em;
    float:right;
    outline: none;


    }

    .searchButton:hover {
    cursor: pointer;
    }

    .searchBar {
        color:grey;
        border-radius:5%;
        border:1px solid #d9d9d9;
        padding:0.58em 0.8em;
        float:right;
        outline-color:#4ba6c3;
        margin:0px 10px;

    }

5 Answers

Steven Parker
Steven Parker
229,771 Points

It looks like you could do this in your handler functions.

If I understand correctly what you want, you can easily add a boolean to your reveal loop, and after the loop you can check to see if there are any visible items. Something like this (using button3 as an example):

button3.addEventListener("click", function() {
  let visible = false;   // boolean to show if any items visible
  for (var i = 0; i < li.length; i++) {
    if (i < 21 || i > 30) {
      li[i].style.display = "none"
    } else {
      li[i].style.display = "block"
      visible = true;    // there's at least one visible
    }
  }
  if (!visible) {
    // do what you want here when nothing is visible
  }
}

The same thing could be done with the handlers for the other buttons, including the search button.

Suggestion: When sharing large and/or multiple items, consider making a snapshot of your workspace and post the link to it.

Steven Parker
Steven Parker
229,771 Points

Here's another example, specifically for the search button:

searchButton.addEventListener("click", function() {
  let visible = false;   // boolean to show if any items visible
  for (var i = 0; i < li.length; i++) {
    if (li[i].innerHTML.toUpperCase().includes(input.value.toUpperCase())) {
      li[i].style.display = "block"
      visible = true;    // there's at least one visible
    } else {
      li[i].style.display = "none"
    }
  }
  message.style.display = visible ? "none" : "block";  // show message only when nothing visible
});
blake guyan
blake guyan
8,297 Points

you are already looking at the object display property,

why not create a new if loop that looks at the display property and set the loop so that if the number of objects with display: block < 1 then run a prompt saying "all students hidden" or something?

Neil Bircumshaw
seal-mask
.a{fill-rule:evenodd;}techdegree
Neil Bircumshaw
Full Stack JavaScript Techdegree Student 14,597 Points

It doesn't need to trigger off the buttons which paginate, it's more off the button that is affiliated with the input search bar. It's if someone types a persons name in and they aren't found a message pops up saying "no one is found by that name in the list"

Like you suggest Blake, something like this:

searchButton.addEventListener("click", function(){
    for (var i = 0; i < li.length; i++){


        if (li[i].style.display = "block" < 1 ){
            message.style.display = "block"
        }



        else {message.style.display = "none"


        }



}})

however that doesn't seem to work. So I'm trying to say, if there are less than 1 li with the display of block then show the message. But I'm not sure how to write this. Any ideas guys?

Steven Parker
Steven Parker
229,771 Points

The example I first gave can be applied to any of the buttons, including the search button.

I've added another example above specifically for the search button. You will still need to apply the same thing to all the buttons so the message will go away when they are used and something is displayed.

Neil Bircumshaw
seal-mask
.a{fill-rule:evenodd;}techdegree
Neil Bircumshaw
Full Stack JavaScript Techdegree Student 14,597 Points

Steven you're a genius! I've got it to work and added code to the pagination buttons so that the message doesn't show when I click them.

I have to ask though how does this work exactly ?

So you have a variable called visible which is false. If the if statement is true the visible becomes true.

so then if not true the message is shown because the input does not match with the list items innerHTML.

So essentially you're assigning a Boolean to a test, is that right?

Steven Parker
Steven Parker
229,771 Points

Yes, the boolean becomes true for any (and every) item that gets displayed. So if none of them ever do, it will still be false when you use it to determine whether to show or hide the message.