1. Web Design
  2. UX/UI
  3. UX Design

How to Implement a “Load More” Button With Vanilla JavaScript

Scroll to top

We’ve covered Pagination and Infinite Scrolling in previous tutorials. On this occasion, we’ll be looking at another method of controlling how content is displayed on a page: using a “Load More” button.

A “Load More” button adds more content to a page when clicked by a user. This is a common approach for blogs as it allows the user to decide how and when information is displayed. 

Here’s a look at the final product we’ll work on today—scroll to the bottom of the pen and click the button to add more content to the page:

Please accept marketing cookies to load this content.

1. Card Container and Button HTML

We’ll start by placing the container for our cards on the page. We’ll be adding the cards to the container using JavaScript so the div will be empty.

1
<div id="card-container"></div>

Our implementation includes a “load more” button and also displays the current number of cards being shown and the total number of cards available. We’ll include these features in a card-actions div. The content in card-count and card-total will be added with JavaScript.

1
<div class="card-actions">
2
  <button id="load-more">Load more</button>
3
  <span>Showing 
4
    <span id="card-count"></span> of 
5
    <span id="card-total"></span> cards      
6
  </span>
7
</div>

2. Styling the Cards and Button

The cards we’ll be adding to the card-container div will have a classname of “card”. 

1
#card-container {
2
  display: flex;
3
  flex-wrap: wrap;
4
}
5
6
.card {
7
  height: 55vh;
8
  width: calc((100% / 3) - 16px);
9
  margin: 8px;
10
  border-radius: 3px;
11
  transition: all 200ms ease-in-out;
12
  display: flex;
13
  align-items: center;
14
  justify-content: center;
15
}
16
17
.card:hover {
18
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
19
}

We’ll style our load-more button in a similar manner to the cards and add a disabled pseudo-selector to show when the end of the cards have been reached.

1
.card-actions {
2
  margin: 8px;
3
  padding: 16px 0;
4
  display: flex;
5
  justify-content: space-between;
6
  align-items: center;
7
}
8
9
#load-more {
10
  width: calc((100% / 3) - 8px);
11
  padding: 16px;
12
  background-color: white;
13
  border: none;
14
  cursor: pointer;
15
  transition: all 200ms ease-in-out;
16
  border-radius: 3px;
17
  font-size: 0.75rem;
18
  text-transform: uppercase;
19
  letter-spacing: 0.15rem;
20
}
21
22
#load-more:not([disabled]):hover {
23
  box-shadow: 0 1px 9px rgba(0, 0, 0, 0.2);
24
}
25
26
#load-more[disabled] {
27
  background-color: #eaeaea !important;
28
}

3. Adding Functionality With JavaScript

This is what the functional implementation for the load more button will look like:

  1. Define a number of cards to be added to the page each time the user clicks the button.
  2. Detect when the total number of cards have been added and disable the button.

Defining Constants

First, get all the elements we’ll need from our DOM:

1
const cardContainer = document.getElementById("card-container");
2
const loadMoreButton = document.getElementById("load-more");
3
const cardCountElem = document.getElementById("card-count");
4
const cardTotalElem = document.getElementById("card-total");

Now we need to define our global variables.

We’ll need a value for the max number of cards to be added to the page. If you’re getting your data from a server, this value is the length of the response from the server. Let’s initialise a card limit of 99. 

1
const cardLimit = 99;

The cardTotalElem is the element for displaying the max number of cards on the page so we can set the innerHTML to the cardLimit value;

1
cardTotalElem.innerHTML = cardLimit;

Then we’ll define a variable for how many cards we want to increase the page by:

1
const cardIncrease = 9;

Much like with our infinite scrolling tutorial, we’ll want to know how many “pages” we’ll have i.e. how many times can we increase the content till we reach the max limit. For example, with our defined cardLimit and cardIncrease variables, we can increase the content 10 times (assuming we’ve already loaded the first 9 elements) until we reach the limit. We’ll do this by dividing the cardLimit by the cardIncrease.

1
const pageCount = Math.ceil(cardLimit / cardIncrease);

Then we’ll define a value to determine which page we’re on:

1
let currentPage = 1;

Creating a New Card

Now we have all our constants, let’s make a function to add a new card to the card container. We’ll set the innerHTML of our cards to the index value so we can keep track of the number of cards we’re adding.

A fun feature in this demo is that each card has a randomly generated background color.

1
const getRandomColor = () => {
2
  const h = Math.floor(Math.random() * 360);
3
4
  return `hsl(${h}deg, 90%, 85%)`;
5
};
6
7
const createCard = (index) => {
8
  const card = document.createElement("div");
9
  card.className = "card";
10
  card.innerHTML = index;
11
  card.style.backgroundColor = getRandomColor();
12
  cardContainer.appendChild(card);
13
};

We can also apply this function to our load-more button on page load to give it a random background color as well:

1
window.onload = function () {
2
  loadMoreButton.style.backgroundColor = getRandomColor();
3
};

Adding Cards to the Container

We’ll add our cards to our container using a similar functionality to what we used in the Infinite Scrolling tutorial.

First, determine the range of cards to be added to the page. The addCards function will accept a pageIndex parameter, which will update the global currentPage value. If we’re on page 1, we’ll add cards 1 to 9. If we’re on page 2, we’ll add cards 10 to 18 and so on.

We can define that mathematically as:

1
const addCards = (pageIndex) => {
2
  currentPage = pageIndex;
3
  
4
  const startRange = (pageIndex - 1) * cardIncrease;
5
  const endRange = pageIndex * cardIncrease;
6
  
7
  for (let i = startRange + 1; i <= endRange; i++) {
8
    createCard(i);
9
  }
10
};

In this function, our start range will always be one less than the value we’re trying to get (i.e. on page 1, the start range is 0, on page 2, the start range is 9) so we’ll account for that by setting the value of our for loop index to startRange + 1.

Detecting When Card Limit is Reached

A limit we’ll have to look out for is the endRange number. If we’re on the last page, we’ll want our end range to be the same as the cardLimit. For instance, if we have a cardLimit of 75 and a cardIncrease of 10 and we’re on page 8, our startRange will be 70 and our endRange value should be 75. 

We’ll modify our addCards function to account for this:

1
const addCards = (pageIndex) => {
2
  currentPage = pageIndex;
3
4
  const startRange = (pageIndex - 1) * cardIncrease;
5
  const endRange = currentPage == pageCount ? cardLimit : pageIndex * cardIncrease;
6
7
  for (let i = startRange + 1; i <= endRange; i++) {
8
    createCard(i);
9
  }
10
};

Our demo also includes a cardTotal element that displays the number of cards currently being shown on the page so we’ll set the innerHTML of this element as the end range.

1
const addCards = (pageIndex) => {
2
  currentPage = pageIndex;
3
4
  const startRange = (pageIndex - 1) * cardIncrease;
5
  const endRange = currentPage == pageCount ? cardLimit : pageIndex * cardIncrease;
6
  
7
  cardCountElem.innerHTML = endRange;
8
9
  for (let i = startRange + 1; i <= endRange; i++) {
10
    createCard(i);
11
  }
12
};

Another thing to look out for is disabling the load more button when the cardLimit is reached. We can define a handleButtonStatus function to determine whether to disable the button i.e. when the currentPage is equal to the cardLimit:

1
const handleButtonStatus = () => {
2
  if (pageCount === currentPage) {
3
    loadMoreButton.classList.add("disabled");
4
    loadMoreButton.setAttribute("disabled", true);
5
  }
6
};

We’ll then pass this new function into our addCards function:

1
const addCards = (pageIndex) => {
2
  currentPage = pageIndex;
3
4
  handleButtonStatus();
5
6
  const startRange = (pageIndex - 1) * cardIncrease;
7
  const endRange =
8
    pageIndex * cardIncrease > cardLimit ? cardLimit : pageIndex * cardIncrease;
9
  
10
  cardCountElem.innerHTML = endRange;
11
12
  for (let i = startRange + 1; i <= endRange; i++) {
13
    createCard(i);
14
  }
15
};

Loading Initial Cards

We’ve defined a feature for adding cards to the container so we’ll update our window.onload function to set the initial cards to be added to the page.

1
window.onload = function () {
2
  addCards(currentPage);
3
  loadMoreButton.style.backgroundColor = getRandomColor();
4
};

Handling Load More

We’ll handle adding the content by increasing the currentPage number by 1 every time the load more button is clicked. Since we’ve already added all the limit checks in our addCards function, we won’t need to do any other check within our click event.

1
window.onload = function () {
2
  addCards(currentPage);
3
  loadMoreButton.style.backgroundColor = getRandomColor();
4
  loadMoreButton.addEventListener("click", () => {
5
    addCards(currentPage + 1);
6
  });
7
};

Conclusion

And we’re done! We’ve successfully implemented a “Load More” button feature on our web page!

Please accept marketing cookies to load this content.