Search code examples
javascripthtmlobjecttiny-slider

Iterate the data dynamically using Tiny Slider JS


I have array of objects that includes name and description. My goal here is to display the name and description dynamically in my image carousel with the help of Tiny Slider js.

I try the following attempt but failed.

  1. Use .getElementById() to get the slider element and .map() to render the data inside the object but unfortunately the whole data was rendered in one slider only.

The actual result: enter image description here

index.html

                   <div id="sliderCont" class="my-slider">
                        <div>
                            <div class="slide">
                                <div class="slide-img" style="background-image: url('src/images/img-1.jpg')">
                                    <a href="http://">View More</a>
                                </div>
                                <br>
                                <div class="slide-info">
                                    <h3 id="project-name"></h3>
                                    <p id="project-description" class="subtext"></p>
                                </div>
                            </div>
                        </div>
                    </div>

app.js

const project = [
  {
    image: "",
    name: "Project 1",
    description: "Project Description here.",
  },
  {
    image: "",
    name: "Project 2",
    description: "Project Description here. 2",
  },
  {
    image: "",
    name: "Project 3",
    description: "Project Description here. 3",
  },
  {
    image: "",
    name: "Project 4",
    description: "Project Description here. 4",
  },
];

document.getElementById("project-name").innerHTML = project.map((proj) => proj.name);
document.getElementById("project-description").innerHTML = project.map((proj) => proj.description);

Tiny Slider Config

let slider = tns({
  container: ".my-slider",
  slideBy: 1,
  speed: 200,
  nav: false,
  controlsContainer: "#controls",
  prevButton: ".previous",
  nextButton: ".next",
  preventScrollOnTouch: "auto",
  autoplay: true,
  autoplayButtonOutput: false,
  responsive: {
    1600: {
      items: 4,
      gutter: 20,
    },
    1024: {
      items: 3,
      gutter: 20,
    },
    768: {
      items: 2,
      gutter: 20,
    },
    480: {
      items: 1,
    },
  },
});

Solution

  • project.map((proj) => proj.name) 
    

    ...returns an array:

    ["Project 1", "Project 2", "Project 3", "Project 4"]
    

    When assigning this array to document.getElementById("project-name").innerHTML it is converted to the string "Project 1,Project 2,Project 3,Project 4".

    So you're essentially assigning this string to the .project-name innerHTMLvalue:

    document.getElementById("project-name").innerHTML = "Project 1,Project 2,Project 3,Project 4";
    

    The same thing happens with:

    document.getElementById("project-description").innerHTML = project.map(
        (proj) => proj.description
    );
    

    Instead, first iterate, forEach(), over the project array, and in the loop block add a slide.

    To create multiple slides use cloneNode() to copy the .slide DIV. (Since you're duplicating this DIV and it's child nodes, don't use IDs. Use class names instead: .project-name and .project-description.) And append the new node to the .slide's parentNode.

    After the project array loop is exited, remove, removeChild(), the original .slide-info DIV.

    const project = [
      {
        image: "https://source.unsplash.com/random?w=200",
        url: "p1.html",
        name: "Project 1",
        description: "Project Description here."
      },
      {
        image: "https://source.unsplash.com/random?w=200",
        url: "p2.html",
        name: "Project 2",
        description: "Project Description here. 2"
      },
      {
        image: "https://source.unsplash.com/random?w=200",
        url: "p3.html",
        name: "Project 3",
        description: "Project Description here. 3"
      },
      {
        image: "https://source.unsplash.com/random?w=200",
        url: "p4.html",
        name: "Project 4",
        description: "Project Description here. 4"
      },
    ];
    
    // get target DIV, containing .slide-img, .project-url, .project-name, and .project-description
    const slide = document.querySelector(".slide");
    
    // iterate over project array
    project.forEach(proj => {
    
      // make a clone of .slide for new slide
      const newslide = slide.cloneNode(true);
    
      // add image background to .slide-img div
       newslide.querySelector(".slide-img").style.backgroundImage = `url('${proj.image}')`;
    
      // add url href to .project-url anchor tag
      newslide.querySelector(".project-url").href = proj.url;
    
      // add name to .project-name header
      newslide.querySelector(".project-name").innerHTML = proj.name;
    
      // add description to .project-description paragraph
      newslide.querySelector(".project-description").innerHTML = proj.description;
      
      // add slide to .slide parent
      slide.parentNode.appendChild(newslide);
    });
    
    // remove original slide
    slide.parentNode.removeChild(slide);
    <div>
        <div class="slide">
            <div class="slide-img">
                <a class="project-url" href="" style="color: white;">View More</a>
            </div>
            <br>
            <div class="slide-info">
                <h3 class="project-name"></h3>
                <p class="project-description subtext"></p>
            </div>
        </div>
    </div>