Search code examples
javascriptarraysloopsobjectcomponents

Javascript - loop to create list of cards


HTML and simple JS (no react / vue). I need to do a list of cards and would like to do a loop to avoid repeating the html.

My current code :

<div id="products-cards-container">
    <div class="products-cards">              
        <div class="product-header">
            <img src="../assets/img/image1.png"/>
        </div>
        <div class="product-content">
            <h4>title 1</h4>
            <p>super content 1</p>
        </div> 
        <button class="info-button">+ info</button>
    </div>
    <div>
        <div class="product-header">
            <img src="../assets/img/cards/products/image2.png"/>
        </div>
        <div class="product-content">
            <h4>title 2</h4>
            <p>super content 2</p>
        </div> 
        <button class="info-button">+ info</button>
    </div>
    <div>
        <div class="product-header">
            <img src="../assets/img/cards/products/image-3.png"/>
        </div>
        <div class="product-content">
            <h4>title 3</h4>
            <p>blablablablbalbalbabla blablaba</p>
        </div> 
        <button class="info-button">+ info</button>
    </div>\
</div>

I am trying to return html

script.js

const valuesCards = [
    { 
    image: '../img/image1.png', 
    title: 'title 1', 
    content: 'super content 1',
    },
    {
    image: '../img/image2.png', 
    title: 'title 2', 
    content: 'super content 2'
    },
    { 
    image: '../img/image-3.png', 
    title: 'title3', 
    content: 'blablablablbalbalbabla blablaba'
    },
   ]

creating a function that inserts the list of cards in the .products-cards div :

    function returnCards() => {
    ----- AND HERE I AM STUCK
   (as well, all tries I did with a simple array / object returned only the last info) ----
    }

Solution

  • Use Array.prototype.map function and a template literal.

    const container = document.getElementById('products-cards-container');
    const valuesCards = [{
        image: '../img/image1.png',
        title: 'title 1',
        content: 'super content 1',
      },
      {
        image: '../img/image2.png',
        title: 'title 2',
        content: 'super content 2'
      },
      {
        image: '../img/image-3.png',
        title: 'title3',
        content: 'blablablablbalbalbabla blablaba'
      },
    ]
    
    function returnCards(valuesCards) {
      return "<div class=\"products-cards\">" + valuesCards.map(valuesCard => `
      <div>
        <div class="product-header">
          <img src="${valuesCard.image}"/>
        </div>
        <div class="product-content">
          <h4>${valuesCard.title}</h4>
          <p>${valuesCard.content}</p>
        </div> 
        <button class="info-button">+ info</button>
      </div>`).join('') + "</div>";
    }
    
    container.innerHTML = returnCards(valuesCards);
    <div id="products-cards-container"></div>