Search code examples
javascriptarraysfunctionobjectpagination

Display Paginated Objects on screen


I have an Array of Objects:

const myArray = [
    {myObject: "1"},
    {myObject: "2"},
    {myObject: "3"},
    {myObject: "4"},
    {myObject: "5"},
]

I have created a pagination system for this Array of Objects using the following code:

function paginator (items, page, per_page) {
    let offset = (page - 1) * per_page;
    let paginatedItems = items.slice(offset).slice(0, per_page);
    let total_pages = Math.ceil(items.length / per_page);

    return {
        page: page,
        per_page: per_page,
        pre_page: page - 1 ? page - 1 : nul,
        next_page: (total_pages > page) ? page + 1 : nul,
        total: items.length,
        total_pages: total_pages,
        data: paginatedItems
    };
}

When I have loged the results of this pagination system to the console, it has worked as expected. I now want to display each of the objects in myArray using this pagination system. How could I do this?

I have tried to use the append and append child functions in order to dislpay the objects on screen. I have also looked at multiple different videos and articles and have not been able to find a solution.

Along with the next and previous buttons, I also want to add the numbered buttons to the screen. Each button's inner text should be the page number and should lead to the correct page.

My code:

let products = [
    productName: "Brand Name",
    category: "category",
    price: "30",
    image: "images/main_img.jpg",
  },
]
function createCards(products) {
  for (let i of products) {
    //Create Card
    const card = document.createElement("div");
    //Card should have category and should stay hidden initially
    card.classList.add("card", i.category);
    //image div
    const imgContainer = document.createElement("div");
    imgContainer.classList.add("image-container");
    //img tag
    const image = document.createElement("img");
    image.setAttribute("src", i.image);
    imgContainer.appendChild(image);
    card.appendChild(imgContainer);
    //container
    const container = document.createElement("div");
    container.classList.add("container");
    //product name
    const name = document.createElement("h5");
    name.classList.add("product-name");
    name.innerText = i.productName.toUpperCase();
    container.appendChild(name);
    //price
    const price = document.createElement("h6");
    price.innerText = "$" + i.price;
    container.appendChild(price);

    card.appendChild(container);
    document.getElementById("products").appendChild(card);
    }
}

Solution

  • Fixing the nul->null

    I think this will help you

    The code is self explanatory

    const paginator = (items, page, per_page) => {
      let offset = (page - 1) * per_page;
      let paginatedItems = items.slice(offset).slice(0, per_page);
      let total_pages = Math.ceil(items.length / per_page);
    
      return {
        page: page,
        per_page: per_page,
        pre_page: page - 1 ? page - 1 : null,
        next_page: (total_pages > page) ? page + 1 : null,
        total: items.length,
        total_pages: total_pages,
        data: paginatedItems
      };
    };
    const createCard = item => `<div class="card ${item.category}">
      <div class="image-container"><img src="${item.image}" /></div>
      <div class="container">
        <h5 class="product-name">${item.productName.toUpperCase()}</h5>
        <h6>$${item.price}</h6>
      </div>
    </div>`;
    
    window.addEventListener("DOMContentLoaded", () => {
      const productContainer = document.getElementById("products");
      const buttonContainer = document.getElementById("buttons");
      const prev = document.getElementById("prev");
      const next = document.getElementById("next");
      let currentPage = 1;
      const perPage = 2;
      const lastPage = Math.floor(products.length / perPage) + 1;
      document.getElementById("nav").addEventListener("click", (e) => {
        const tgt = e.target;
        if (["prev", "next"].includes(tgt.id)) {
          const dir = e.target.id === "next" ? 1 : -1;
          currentPage += dir;
          if (currentPage < 1) currentPage = 1;
          if (currentPage >= lastPage) currentPage = lastPage;
        } else {
          currentPage = +tgt.textContent;
        }
        prev.disabled = currentPage === 1;
        next.disabled = currentPage === lastPage;
        buttonContainer.querySelectorAll('button')
          .forEach((button, i) => button.classList.toggle('active', i === currentPage - 1)); // currentPage starts from 1, i starts from 0
        productContainer.innerHTML = paginator(products, currentPage, perPage)
          .data.map(item => createCard(item)).join("");
      });
      buttonContainer.innerHTML = Array.from({
          length: lastPage
        })
        .map((_, i) => `<button type="button">${i+1}</button>`).join("");
      prev.click(); // start
    });
    .active {
      font-weight: bold;
    }
    
    .card { padding: 5px; width: 80vw; border: 1px dotted black; } 
    .image-container { border: 3px solid black; width:100px; height:100px; }
    .category1 { background-color: teal; }
    .category2 { background-color: yellow; }
    .category3 { background-color: pink; }
    <nav id="nav">
      <button type="button" id="prev">Prev</button>
      <span id="buttons"></span>
      <button type="button" id="next">Next</button>
    </nav>
    <hr/>
    <div id="products"></div>
    
    
    <script>
      // test data 
      const products = [{
          productName: "Brand Name 1",
          category: "category1",
          price: "30",
          image: "https://dummyimage.com/100x100/fff/000.png&text=Product+1"
        },
        {
          productName: "Brand Name 2",
          category: "category1",
          price: "40",
          image: "https://dummyimage.com/100x100/fff/000.png&text=Product+2"
        },
        {
          productName: "Brand Name 3",
          category: "category1",
          price: "50",
          image: "https://dummyimage.com/100x100/fff/000.png&text=Product+3"
        },
        {
          productName: "Brand Name 4",
          category: "category2",
          price: "60",
          image: "https://dummyimage.com/100x100/fff/000.png&text=Product+4"
        },
        {
          productName: "Brand Name 5",
          category: "category2",
          price: "70",
          image: "https://dummyimage.com/100x100/fff/000.png&text=Product+5"
        },
        {
          productName: "Brand Name 6",
          category: "category3",
          price: "80",
          image: "https://dummyimage.com/100x100/fff/000.png&text=Product+6"
        },
        {
          productName: "Brand Name 7",
          category: "category3",
          price: "90",
          image: "https://dummyimage.com/100x100/fff/000.png&text=Product+7"
        }
      ];
    </script>