Coder Wrap provides free to use snippets Coder Wrap provides free to use snippets

Back to Others
Preview Source Code
Download
HTML
CSS
/**Typeo CSS Start**/
@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,400;0,500;0,600;0,700;1,400&display=swap');

* {
 box-sizing: border-box;
}

body {
 font-family: "Poppins", sans-serif;
 color: #000;
}

/**Typeo CSS End**/
.boxlist {
 width: 100%;
 max-width: 1200px;
 padding: 0px 15px;
 display: flex;
 flex-flow: row wrap;
 margin: auto;
}

.boxlist .boxitem {
 background-color: #606060;
 font-size: 30px;
 text-transform: uppercase;
 font-weight: 400;
 display: flex;
 flex-flow: row wrap;
 align-items: center;
 justify-content: center;
 color: #fff;
 width: 31%;
 margin: 1.1% 1.1%;
 height: 200px;
}

.pagination {
 display: flex;
 flex-flow: row wrap;
 justify-content: center;
 padding: 20px 0;
}

.pagination button {
 user-select: none;
 -webkit-user-select: none;
 -moz-user-select: none;
 padding: 12px 24px 10px 24px;
 text-transform: uppercase;
 font-size: 20px;
 border: none;
 line-height: 1.1;
 cursor: pointer;
 background-color: #3d3d3d;
 color: #fff;
 border-radius: 2px;
 margin: 0px 10px;
}

.pagination button:hover {
 background-color: #000;
}

.pagination .disabled {
 pointer-events: none;
 opacity: 0.5;
}

@media(max-width:992px) {
 .boxlist .boxitem {
  width: 48%;
  margin: 1%;
 }

}

@media(max-width:567px) {
 .boxlist .boxitem {
  width: 100%;
  margin: 10px 0;
  height: 300px;
 }

}
JS
//DOM Elements
const itemsContainer = document.querySelector(".boxlist");
const items = document.querySelectorAll(".boxitem");
const nav = document.querySelector(".pagination");
const buttons = document.querySelectorAll("button");
const nextBtn = document.querySelector(".next");
const prevBtn = document.querySelector(".prev");

//Object holds different states
const state = {
  allItems: [...items],
  maximumItems: 12,
  initialPage: 1,
  totalPages() {
    return Math.ceil(state.allItems.length / state.maximumItems);
  },
  curPage: 1,
};

//get 10 items per each page;
const getItems = (page) => {
  state.allItems.forEach((item) => item.remove());
  const min = (page - 1) * state.maximumItems;
  const max = page * state.maximumItems;

  //slicing items based on page
  return state.allItems.slice(min, max);
};

//render items in DOM
const renderItems = (page) => {
  const items = getItems(page);
  items.forEach((item) => itemsContainer.append(item));
};

//render by default the first 10 when DOM loads
renderItems(state.initialPage);

//Display btns if conditions are met. By default they are set to display = none (class="disabled")

const displayBtns = (page) => {
  //If there's only one page, hide btns
  if (state.totalPages() === state.initialPage) {
    buttons.forEach((btn) => btn.classList.add("disabled"));
  }

  //If the last page, display only prev. btn
  if (page === state.totalPages() && page !== state.initialPage) {
    nextBtn.classList.add("disabled");
    prevBtn.classList.remove("disabled");
  }

  //If the 1st page, display only next btn
  if (page === state.initialPage && state.totalPages() > state.initialPage) {
    nextBtn.classList.remove("disabled");
    prevBtn.classList.add("disabled");
  }

  //If not the 1st page and not the last one
  if (page !== state.initialPage && page < state.totalPages()) {
    nextBtn.classList.remove("disabled");
    prevBtn.classList.remove("disabled");
  }
};

//Display btns based on met conditions when DOM loads
displayBtns(state.initialPage);

// controlling btns and rendering items
const controlBtns = (e) => {
  const pagesNb = state.totalPages();

  if (e.target.classList.contains("next") && state.initialPage !== pagesNb) {
    state.curPage++;
    renderItems(state.curPage);
  }

  if (e.target.classList.contains("prev") && state.initialPage !== state.curPage) {
    state.curPage--;
    renderItems(state.curPage);
  }

  displayBtns(state.curPage);
};

//attaching handler to btns
nav.addEventListener("click", controlBtns);

Related Snippets

Leave a comment

Your email address will not be published. Required fields are marked *