I have a fetch request for my sample application, that receive a json. I’ve mapped this json and i can potentially display over 100 elements with a single request.
The problem is that i want to implement a load more button to make the page more simple to read and load (for example i want to display 20 items, and other 20 if the load more button is triggered).
Here is my sample request in a reproducible demo: https://jsfiddle.net/0mc3gn9f/
How can i implement a load more button in vanilla js?
let tableBody = document.getElementById("tab-body"); fetch("https://api.coingecko.com/api/v3/coins/markets?vs_currency=eur&order=market_cap_desc&per_page=100&page=1&sparkline=false", {cache: "no-cache"}) .then((response) => response.json()) .then((data) => { this.criptoInfo = data; return this.criptoInfo; }) .then((coinMap) => { let cripto = coinMap.map((coin) => { console.log(coin) let tr = document.createElement("tr"); tableBody.appendChild(tr); tr.innerHTML = `<td> <div class="name-value coin-container"> <img class="coin-image" src="${coin.image}"> <p class="coin-name">${coin.name}</p> <p class="coin-abbrName">${coin.symbol}</p> </div> </td> <td><p class="price coin-name"><b>${coin.current_price} €</b></p></td> <td><p class="value-item coin-name">${coin.ath_change_percentage} %</p></td> <td><p class="value-item coin-name">${coin.high_24h} €</p></td> <td><p class="value-item coin-name">${coin.market_cap} €</p></td> <td><p class="value-item coin-name">${coin.total_supply} €</p></td> `; }); });
@import url("https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,100;0,400;0,700;0,900;1,100&display=swap"); nav { width: 100%; display: flex; justify-content: space-around; align-items: center; background-color: #040418; height: 20vh; } nav .logo { width: 110px; } nav .logo img { width: 100%; } nav a { margin: 1rem; text-decoration: none; font-weight: bolder; font-size: 1.8rem; color: #e0dada; } .box-table { margin-inline: 4rem; display: flex; justify-content: center; align-items: center; margin: 1rem; text-align: justify; } .box-table .coin-container { display: flex; align-items: center; justify-content: flex-start; gap: 0.5rem; padding: 1rem; } .box-table .coin-container img { width: 40px; } .box-table .coin-container .coin-abbrName { text-transform: uppercase; color: dimgray; } .box-table .name-value { width: 300px; } .box-table .price { width: 200px; } .box-table .value-item { width: 180px; } .box-table .more-coins { width: 250px; padding: 1rem; justify-content: center; } thead:after { content: "@"; display: block; line-height: 30px; text-indent: -99999px; } #tab-body > tr { box-shadow: rgba(0, 0, 0, 0.04) 0px 3px 5px; } .presentation { height: 80vh; display: flex; justify-content: space-around; flex-wrap: wrap; background: #3903f9; background: linear-gradient(352deg, #3903f9 45%, #040418 70%); } .presentation .titles { width: 50%; display: flex; flex-wrap: wrap; justify-content: center; } .presentation .titles h1 { color: rgba(40, 40, 236, 0.966); font-size: 3rem; padding: 1rem; text-align: center; line-height: 2rem; margin-top: 4rem; margin-bottom: 3rem; } .presentation .titles h2 { font-size: 2rem; width: 500px; line-height: 3rem; justify-self: center; color: #fff; } .presentation .image-home-container { width: 50%; display: flex; justify-content: center; } .presentation .image-home-container .image-home { width: 250px; align-self: center; border: 0; } .presentation .image-home-container .image-home img { width: 100%; } .presentation button { width: 250px; height: 80px; background-color: #080808; border: 2px solid white; margin-bottom: 1rem; border-radius: 30px; font-size: 1.6rem; color: #fff; } .presentation button:hover { width: 300px; transition: 2s; font-size: 2rem; background-color: #fff; color: black; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: "Lato", serif; } body, html { background-color: #fdfdfd; } .header-container { background-image: url(./assets/header.jpg); background-size: cover; background-repeat: no-repeat; background-position: center center; width: 100%; height: 400px; margin-bottom: 2rem; position: relative; } .header-container .heading-title { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: white; font-size: 2.48rem; font-family: Lato, serif; font-weight: 900; background: #0000005c; padding: 1rem; text-align: center; border-radius: 15px; } .header-container .heading-title h3 { font-size: 1.5rem; font-weight: 300; } /*# sourceMappingURL=style.css.map */
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"/> <meta http-equiv="X-UA-Compatible" content="IE=edge"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <title>Document</title> <link rel="stylesheet" href="style.css"/> <link href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;700&family=Roboto+Mono:wght@300&display=swap" rel="stylesheet" /> </head> <body> <!-- TABLE --> <section> <div class="box-table"> <table id="tab"> <thead id="table-head"> <tr> <th class="name-value">Nome</th> <th class="price">Prezzo</th> <th class="value-item">Variazione</th> <th class="value-item">Volume(24 h)</th> <th class="value-item">Capitalizzazione mercato</th> <th class="value-item">Offerta</th> </tr> </thead> <tbody id="tab-body"></tbody> </table> </div> <button id="load-more">Load More</button> </section> <script src="main.js"></script> </body> </html>
Advertisement
Answer
https://api.coingecko.com/api/v3/coins/markets?vs_currency=eur&order=market_cap_desc&per_page=100&page=1&sparkline=false
Actually, your API call already have
per_page=100
which is to get 100 items per page
page=1
which is to get data by page number
So we just need to change per_page=20
and make API call with incremental page
number correctly
//global variable for pageIndex and it starts from 1 let pageIndex = 1 let tableBody = document.getElementById("tab-body"); //populate a click event to load more button const loadMoreButton = document.getElementById("load-more"); loadMoreButton.addEventListener("click", () => { fetchData(pageIndex++) }); //every click pageIndex increases 1 //fetch data with page index value function fetchData(pageIndexValue = 1) { fetch(`https://api.coingecko.com/api/v3/coins/markets?vs_currency=eur&order=market_cap_desc&per_page=20&page=${pageIndexValue}&sparkline=false`, {cache: "no-cache"}) .then((response) => response.json()) .then((data) => { this.criptoInfo = data; return this.criptoInfo; }) .then((coinMap) => { let cripto = coinMap.map((coin) => { let tr = document.createElement("tr"); tableBody.appendChild(tr); tr.innerHTML = `<td> <div class="name-value coin-container"> <img class="coin-image" src="${coin.image}"> <p class="coin-name">${coin.name}</p> <p class="coin-abbrName">${coin.symbol}</p> </div> </td> <td><p class="price coin-name"><b>${coin.current_price} €</b></p></td> <td><p class="value-item coin-name">${coin.ath_change_percentage} %</p></td> <td><p class="value-item coin-name">${coin.high_24h} €</p></td> <td><p class="value-item coin-name">${coin.market_cap} €</p></td> <td><p class="value-item coin-name">${coin.total_supply} €</p></td> `; }); }); } //initial call when page load fetchData(pageIndex++)
@import url("https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,100;0,400;0,700;0,900;1,100&display=swap"); nav { width: 100%; display: flex; justify-content: space-around; align-items: center; background-color: #040418; height: 20vh; } nav .logo { width: 110px; } nav .logo img { width: 100%; } nav a { margin: 1rem; text-decoration: none; font-weight: bolder; font-size: 1.8rem; color: #e0dada; } .box-table { margin-inline: 4rem; display: flex; justify-content: center; align-items: center; margin: 1rem; text-align: justify; } .box-table .coin-container { display: flex; align-items: center; justify-content: flex-start; gap: 0.5rem; padding: 1rem; } .box-table .coin-container img { width: 40px; } .box-table .coin-container .coin-abbrName { text-transform: uppercase; color: dimgray; } .box-table .name-value { width: 300px; } .box-table .price { width: 200px; } .box-table .value-item { width: 180px; } .box-table .more-coins { width: 250px; padding: 1rem; justify-content: center; } thead:after { content: "@"; display: block; line-height: 30px; text-indent: -99999px; } #tab-body > tr { box-shadow: rgba(0, 0, 0, 0.04) 0px 3px 5px; } .presentation { height: 80vh; display: flex; justify-content: space-around; flex-wrap: wrap; background: #3903f9; background: linear-gradient(352deg, #3903f9 45%, #040418 70%); } .presentation .titles { width: 50%; display: flex; flex-wrap: wrap; justify-content: center; } .presentation .titles h1 { color: rgba(40, 40, 236, 0.966); font-size: 3rem; padding: 1rem; text-align: center; line-height: 2rem; margin-top: 4rem; margin-bottom: 3rem; } .presentation .titles h2 { font-size: 2rem; width: 500px; line-height: 3rem; justify-self: center; color: #fff; } .presentation .image-home-container { width: 50%; display: flex; justify-content: center; } .presentation .image-home-container .image-home { width: 250px; align-self: center; border: 0; } .presentation .image-home-container .image-home img { width: 100%; } .presentation button { width: 250px; height: 80px; background-color: #080808; border: 2px solid white; margin-bottom: 1rem; border-radius: 30px; font-size: 1.6rem; color: #fff; } .presentation button:hover { width: 300px; transition: 2s; font-size: 2rem; background-color: #fff; color: black; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: "Lato", serif; } body, html { background-color: #fdfdfd; } .header-container { background-image: url(./assets/header.jpg); background-size: cover; background-repeat: no-repeat; background-position: center center; width: 100%; height: 400px; margin-bottom: 2rem; position: relative; } .header-container .heading-title { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: white; font-size: 2.48rem; font-family: Lato, serif; font-weight: 900; background: #0000005c; padding: 1rem; text-align: center; border-radius: 15px; } .header-container .heading-title h3 { font-size: 1.5rem; font-weight: 300; } /*# sourceMappingURL=style.css.map */
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"/> <meta http-equiv="X-UA-Compatible" content="IE=edge"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <title>Document</title> <link rel="stylesheet" href="style.css"/> <link href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;700&family=Roboto+Mono:wght@300&display=swap" rel="stylesheet" /> </head> <body> <!-- TABLE --> <section> <div class="box-table"> <table id="tab"> <thead id="table-head"> <tr> <th class="name-value">Nome</th> <th class="price">Prezzo</th> <th class="value-item">Variazione</th> <th class="value-item">Volume(24 h)</th> <th class="value-item">Capitalizzazione mercato</th> <th class="value-item">Offerta</th> </tr> </thead> <tbody id="tab-body"></tbody> </table> </div> <button id="load-more">Load More</button> </section> <script src="main.js"></script> </body> </html>
The full implementation here https://jsfiddle.net/691jp7cy/