Webflow Dynamic CMS Slider

This Webflow Dynamic CMS Slider using Vanilla JavaScript enables you to create a dynamic slider with the native Webflow Slider and Collections. You can use Data Attributes to deliver multiple sliders and further enhance them with mixed-content sliders that pull divs into the slider from anywhere on the page.

Post 1

Post 2

Post 3

Post 4

Post 5

Usage

1. Add the 'Webflow Dynamic CMS Slider' script below before the closing </body> tag in the page code as per this page.

2. Add instance(s) of Webflow Dynamic CMS Slider and wrap in a div and set data attribute Name: data-dynamic-slider Value: 1. If you are using one slider per page, then you can put the attribute directly on the 'Slider'.

3. Add instance(s) of Webflow Collections, with the Collection Items styled as you want them to appear in the slider and wrap in a div and set data attribute Name: data-dynamic-slider-collection Value: 1. If you are using one slider per page then you can put the attribute directly on the 'Collection Wrapper'.

4. If your collection(s) items pull from divs outside the slider container, set the Collection List style to display none in Style settings.

5. Publish

Code

The Webflow Dynamic CMS Slider script shoudl be added before the closing </body> tag in the page code as per this page.

  // This Webflow Dynamic CMS Slider Script is Free to use in your projects with Credit to Slick Media in the code
  // Credit Slick Media https://slickmedia.io
  // Ver 5.1

  function initializeDynamicSlider() {
    const sliders = document.querySelectorAll("[data-dynamic-slider]");
    const collections = document.querySelectorAll("[data-dynamic-slider-collection]");

    sliders.forEach((slider) => {
      const sliderNumber = slider.getAttribute("data-dynamic-slider");
      const matchingCollection = Array.from(collections).find(
        (collection) => collection.getAttribute("data-dynamic-slider-collection") === sliderNumber
      );

      if (matchingCollection) {
        const sliderMask = slider.querySelector(".w-slider-mask");
        const baseSlide = sliderMask.firstElementChild;
        const itemItems = matchingCollection.querySelectorAll(".w-dyn-item");
        const divsToAdd = Array.from(document.querySelectorAll(`[data-dynamic-slider-div="${sliderNumber}"]`))
                               .filter(div => !div.classList.contains('w-condition-invisible'));

        const totalSlidesNeeded = itemItems.length + divsToAdd.length;

        for (let i = 0; i < totalSlidesNeeded - 1; i++) {
          const clone = baseSlide.cloneNode(true);
          sliderMask.appendChild(clone);
        }

        const slides = sliderMask.querySelectorAll(":scope > .w-slide");
        const sliderNav = slider.querySelector(".w-slider-nav");
        const sliderArrows = slider.querySelectorAll(".w-slider-arrow-left, .w-slider-arrow-right");
        const sliderNavSetting = slider.getAttribute("data-dynamic-slider-nav") || "true";
        const sliderArrowsSetting = slider.getAttribute("data-dynamic-slider-arrows") || "true";

        function insertDivIntoSlide(div, slide) {
          const clonedDiv = div.cloneNode(true);
          slide.appendChild(clonedDiv);
          div.parentNode.removeChild(div);
        }

        let occupiedIndexes = [];
        divsToAdd.forEach(div => {
          const position = div.getAttribute("data-dynamic-slider-div-position") || "first";
          let targetSlideIndex = 0;

          if (position === "last") {
            targetSlideIndex = slides.length - 1;
          } else if (position === "random") {
            do {
              targetSlideIndex = Math.floor(Math.random() * slides.length);
            } while (occupiedIndexes.includes(targetSlideIndex));
          } else if (!isNaN(parseInt(position))) {
            targetSlideIndex = Math.min(parseInt(position) - 1, slides.length - 1);
          }

          insertDivIntoSlide(div, slides[targetSlideIndex]);
          occupiedIndexes.push(targetSlideIndex);
        });

        itemItems.forEach((item) => {
          for (let i = 0; i < slides.length; i++) {
            if (!occupiedIndexes.includes(i)) {
              slides[i].appendChild(item);
              occupiedIndexes.push(i);
              break;
            }
          }
        });

        // Update visibility function
        const updateVisibility = (element, setting, numberOfSlides) => {
          if (element) {
            const shouldBeVisible = setting === 'true' || (setting && numberOfSlides > parseInt(setting));
            element.style.display = shouldBeVisible ? '' : 'none';
          }
        };

        // Apply visibility settings
        updateVisibility(sliderNav, sliderNavSetting, slides.length);
        sliderArrows.forEach(arrow => updateVisibility(arrow, sliderArrowsSetting, slides.length));

        // Detecting the active slide
        const observer = new MutationObserver(mutations => {
          mutations.forEach(mutation => {
            if (mutation.attributeName === 'aria-hidden') {
              const slide = mutation.target;
              if (!slide.hasAttribute("aria-hidden")) {
                slide.classList.add("w-slide-active");
              } else {
                slide.classList.remove("w-slide-active");
              }
            }
          });
        });

        slides.forEach(slide => {
          observer.observe(slide, { attributes: true });
        });

        // Add .w-slide-active class to the first slide initially
        const firstSlide = sliderMask.querySelector(":scope > .w-slide");
        if (firstSlide) {
          firstSlide.classList.add("w-slide-active");
        }

        slides.forEach((slide, index) => {
          slide.style.zIndex = slides.length - index;
        });

        Webflow.require('slider').redraw();

        // Dispatch the custom event after completing slider initialization
        document.dispatchEvent(new CustomEvent("dynamicSliderInitialized"));
      }
    });
  }

  Webflow.push(initializeDynamicSlider);

Multiple Sliders

Change the numeric values of the data attributes, such as data-dynamic-slider Value:and data-dynamic-slider-collection Value: 2.

The current version is 5.1. Please keep the code credits as per the code.

Post 1

Post 2

Post 3

Post 4

Post 5

Mixed Content Sliders

In addition to the main Collection Items, you can pull additional divs into the slider for mixed content. This functionality is useful where Collection content is limited, such as Divs with Background Videos or Webflow Components. Identify these additional divs with the data attribute data-dynamic-slider-div, which should correspond to the target slider, i.e. data-dynamic-slider-div="1". The default position is the first slide, but you can use additional attributes to set the position.
Additional Div (First)
Another Div (Set Random)
Another Div (Set 3rd)
Another Div (Set Last)

Post 1

Post 2

Post 3

Post 4

Post 5

Webflow Dynamic CMS Slider Add-on Script

Automatically add slide number to the Slides with the ability to prepend the value such as 'Slide 1', Slide 2' etc. Add the following code to the closing body tag of your page: -

// Works with Webflow Dynamic CMS Slider 5.1 and Up
function updateSlideNumbers() {
  const sliders = document.querySelectorAll("[data-dynamic-slider]");

  sliders.forEach((slider) => {
    const numberTargetSelector = slider.getAttribute("data-dynamic-slider-number-target");
    let prependText = slider.getAttribute("data-dynamic-slider-number-text");

    // Check if prependText is not empty, append a space for formatting
    if (prependText) {
      prependText += " "; // Adds a space after the text
    }

    if (numberTargetSelector) {
      const slides = slider.querySelectorAll(".w-slide");
      slides.forEach((slide, slideIndex) => {
        const targetElement = slide.querySelector(numberTargetSelector);
        if (targetElement) {
          targetElement.textContent = `${prependText}${slideIndex + 1}`;
        }
      });
    }
  });
}

// Listen for the custom event and then call updateSlideNumbers
document.addEventListener("dynamicSliderInitialized", function() {
  updateSlideNumbers();
});
After adding the code add a div in the Slider Slide with a predefined Class (e.g. .slide-number) and then on the slider add the attribute 'data-dynamic-slider-number-target' with the value of your class. To prepend the slide number value add the data attribute data-dynamic-slider-number-text with a text value such as 'Slide'.

Data Attributes

For the Slider

data-dynamic-slider:

  • Purpose: This attribute uniquely identifies each slider.
  • Where to Set: Add this attribute to each slider element on your page.
  • Example: <div data-dynamic-slider="1" class="your-slider-class">...</div>

data-dynamic-slider-collection:

  • Purpose: Associates a collection of items with a specific slider.
  • Where to Set: Set this on collection items that you want to be part of the slider, matching the slider's data-dynamic-slider value.
  • Example: <div data-dynamic-slider-collection="1">...</div>

data-dynamic-slider-nav:

  • Purpose: Controls the visibility of the slider navigation dots.
  • Where to Set: On the slider element.
  • Options: "true" (always show), "false" (hide), or a number (hide if the number of slides is less than or equal to this number).
  • Example: <div data-dynamic-slider="1" data-dynamic-slider-nav="true">...</div>

data-dynamic-slider-arrows:

  • Purpose: Controls the visibility of the slider left/right arrows.
  • Where to Set: On the slider element.
  • Options: Same as data-dynamic-slider-nav.
  • Example: <div data-dynamic-slider="1" data-dynamic-slider-arrows="2">...</div>

For Dynamic Divs

data-dynamic-slider-div:

  • Purpose: Identifies additional divs to be included as individual slides in the slider.
  • Where to Set: On div elements that you want to include as slides, matching the data-dynamic-slider value of the slider.
  • Example: <div data-dynamic-slider-div="1">...</div>

data-dynamic-slider-div-position:

  • Purpose: Specifies the position of the div within the slider.
  • Where to Set: On the additional divs.
  • Options: "first", "last", "random", or a specific slide number (e.g., "1", "2").
  • Example: <div data-dynamic-slider-div="1" data-dynamic-slider-div-position="first">...</div>

The current version is 5.1. Please keep the code credits as per the code.

Courtesy of Slick Media