Image Slider for multiple Records

output

I’ve built a simple Image Slider for an Attachment Field for multiple records. So this is basically a styled list component.

Create a Custom List Component and Paste the Code below into the corresponding tabs. Make sure to adjust to your fields. “field_299” is my image and “field_1510” is a link triggered when the image is clicked.

Template

<h3> Weitere Tourneen</h3>
<section class="slider-wrapper">
  <button class="slide-arrow" id="slide-arrow-prev">
    &#8249;
  </button>
  
  <button class="slide-arrow" id="slide-arrow-next">
    &#8250;
  </button>
  
  <ul class="slides-container" id="slides-container">
    {{#each records}}
    <li class="slide"><a href="{{field_1510}}"><img src="{{field_299}}"></a></li>
    {{/each}}
  </ul>
</section>

CSS

* {
  box-sizing: border-box;
}

.slider-wrapper {
  margin: 1rem;
  position: relative;
  overflow: hidden;
}

.slides-container {
  height: auto;
  width: 100%;
  display: flex;
  overflow: scroll;
  scroll-behavior: smooth;
  list-style: none;
  margin: 0;
  padding: 0;
  text-align: center;
    border: solid 2px white;
    border-radius: 5px;
}

.slide-arrow {
  position: absolute;
  display: flex;
  top: 0;
  bottom: 0;
  margin: auto;
  height: 4rem;
  background-color: white;
  border: none;
  width: 2rem;
  font-size: 3rem;
  padding: 0;
  cursor: pointer;
  opacity: 0.5;
  transition: opacity 100ms;
}

.slide-arrow:hover,
.slide-arrow:focus {
  opacity: 1;
}

#slide-arrow-prev {
  left: 0;
  padding-left: 0.25rem;
  border-radius: 0 2rem 2rem 0;
}

#slide-arrow-next {
  right: 0;
  padding-left: 0.75rem;
  border-radius: 2rem 0 0 2rem;
}

.slide {
  width: 100%;
  height: 100%;
  flex: 1 0 100%;
}

.slide img {
  width: 100%; /* Bild wird proportional zur Breite des Containers skaliert */
  height: auto; /* Höhe passt sich automatisch an, um das Seitenverhältnis beizubehalten */
  object-fit: cover; /* Optional: schneidet das Bild zu, um es in den Container zu passen */
  border-radius:5px;
}

footer {
  padding: 1em;
  text-align: center;
  background-color: #FFDFB9;
}

footer a {
  color: inherit;
  text-decoration: none;
}

footer .heart {
  color: #DC143C;
}

.slides-container {
    scrollbar-width: none; /* Firefox */
    -ms-overflow-style: none;  /* Internet Explorer 10+ */
}
/* WebKit */
.slides-container::-webkit-scrollbar { 
    width: 0;
    height: 0;
}

JS

const slidesContainer = document.getElementById("slides-container");
const slide = document.querySelector(".slide");
const prevButton = document.getElementById("slide-arrow-prev");
const nextButton = document.getElementById("slide-arrow-next");

let slideIndex = 0; // Aktueller Index des Bildes

nextButton.addEventListener("click", () => {
  const slideWidth = slide.clientWidth;
  // Nach dem letzten Bild wieder zum ersten springen
  if (slideIndex < slidesContainer.children.length - 1) {
    slideIndex++;
  } else {
    slideIndex = 0;
  }
  slidesContainer.scrollLeft = slideWidth * slideIndex;
});

prevButton.addEventListener("click", () => {
  const slideWidth = slide.clientWidth;
  // Vor dem ersten Bild wieder zum letzten springen
  if (slideIndex > 0) {
    slideIndex--;
  } else {
    slideIndex = slidesContainer.children.length - 1;
  }
  slidesContainer.scrollLeft = slideWidth * slideIndex;
});
3 Likes

Use this JS instead of the one above to have it auto advance

const slidesContainer = document.getElementById("slides-container");
const slides = document.querySelectorAll(".slide"); // Get all slides
const prevButton = document.getElementById("slide-arrow-prev");
const nextButton = document.getElementById("slide-arrow-next");

let slideIndex = 0; // Current index of the slide

function updateSlidePosition() {
  const slideWidth = slides[0].clientWidth; // Get the width of a single slide
  slidesContainer.scrollLeft = slideWidth * slideIndex;
}

function goToNextSlide() {
  if (slideIndex < slides.length - 1) {
    slideIndex++;
  } else {
    slideIndex = 0;
  }
  updateSlidePosition();
}

function goToPrevSlide() {
  if (slideIndex > 0) {
    slideIndex--;
  } else {
    slideIndex = slides.length - 1;
  }
  updateSlidePosition();
}

nextButton.addEventListener("click", goToNextSlide);
prevButton.addEventListener("click", goToPrevSlide);

// Auto advance every 5 seconds
let autoAdvance = setInterval(goToNextSlide, 10000);

// Optional: Pause auto-advance when user interacts
function resetAutoAdvance() {
  clearInterval(autoAdvance);
  autoAdvance = setInterval(goToNextSlide, 10000);
}

nextButton.addEventListener("click", resetAutoAdvance);
prevButton.addEventListener("click", resetAutoAdvance);

// Ensure the code runs after the DOM and images are loaded
window.addEventListener('load', () => {
  // Update slide positions in case images affect layout
  updateSlidePosition();
});
1 Like
  • Click the radio button if you would like this image slider to be available as a plugin?
0 voters

Nice work @andreas ! can we have this as a plugin please?

Well it’s probably better off as a custom component Template