Search code examples
javascriptprogress-barcarouselbootstrap-5

Bootstrap 5 carousel to have one progressbar


I'm trying to get my bootstrap 5 carousel to have a progress bar with left and right arrows and the number of slides like this one.

Example

So, because I am a javascript noob, I need a little help. I did my research and found two ways, but both of them been using bootstrap 3 and didn't work on my bootstrap 5 but finally I found a similar thread but the thing that the java script written is made to work manual per click and not automatic so technically I want the same thing but I want the numbers to have an active class and to switch from 1-2 to 2-3 and so on and I want this to be applied on the progress bar according to the slides. Thats the thread

I Really appreciate any help

Thats what i have currently :

const myCarousel = document.getElementById("carouselExampleIndicators2");
const carouselIndicators = myCarousel.querySelectorAll(
  ".carousel-indicators button span"
);
let intervalID;

const carousel = new bootstrap.Carousel(myCarousel);

window.addEventListener("load", function () {
  fillCarouselIndicator(1);
});

myCarousel.addEventListener("slide.bs.carousel", function (e) {
  let index = e.to;
  fillCarouselIndicator(++index);
});

function fillCarouselIndicator(index) {
  let i = 0;
  for (const carouselIndicator of carouselIndicators) {
    carouselIndicator.style.width = 0;
  }
  clearInterval(intervalID);
  carousel.pause();

  intervalID = setInterval(function () {
    i++;

    myCarousel.querySelector(".carousel-indicators .active span").style.width =
      i + "%";

    if (i >= 100) {
      // i = 0; -> just in case
      carousel.next();
    }
  }, 50);
}
#carouselExampleIndicators2 .carousel-item p{ 
  font-family:'Giove',sans-serif; 
  text-transform: uppercase;
  margin:  16px 200px;
  font-size: 22px;
  color: #e9c8b9;
}

#carouselExampleIndicators2 .carousel-item p::before {
  content: url(../images/vec.png);
  position: absolute;
  top: 0%;
  left: 21.5%;
  opacity: 14%;
}

#carouselExampleIndicators2 .carousel-indicators [data-bs-target] {
  position: relative;
  width: 60px;
  height: 6px;
  border: none;
  border-radius: 24px;
}

#carouselExampleIndicators2 .carousel-indicators [data-bs-target] span {
  content: "";
  position: absolute;
  top: 0%;
  left: 0;
  width: 0;
  height: 100%;
  background: #bb440d;
  border-radius: inherit;
}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container-fluid text-center section0 px-0 bg-dark">
  <div id="carouselExampleIndicators2" class="carousel slide" data-bs-ride="carousel" data-bs-pause="true">
    <div class="carousel-indicators">
      <button type="button" data-bs-target="#carouselExampleIndicators2" data-bs-slide-to="0" class="active" aria-current="true" aria-label="Slide 1">
        <span></span>
      </button>
      <button type="button" data-bs-target="#carouselExampleIndicators2" data-bs-slide-to="1" aria-label="Slide 2">
        <span></span>
      </button>
      <button type="button" data-bs-target="#carouselExampleIndicators2" data-bs-slide-to="2" aria-label="Slide 3">
        <span></span>
      </button>
    </div>
    <div class="carousel-inner pb-5">
      <div class="carousel-item active">
        <p>The most exclusive listings in Europe and the Middle East, <br>
          carefully handpicked to deliver state-of-the-art <br>
          customer experience.</p>
          <!-- <div class="number">1</div> -->
      </div>
      <div class="carousel-item">
        <p>The most exclusive listings in Europe and the Middle East, <br>
          carefully handpicked to deliver state-of-the-art <br>
          customer experience.</p>
      </div>
      <div class="carousel-item">
        <p>The most exclusive listings in Europe and the Middle East, <br>
          carefully handpicked to deliver state-of-the-art <br>
          customer experience.</p>
      </div>
    </div>
    <button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleIndicators2" data-bs-slide="prev">
      <span class="carousel-control-prev-icon" aria-hidden="true"></span>
      <span class="visually-hidden">Previous</span>
    </button>
    <button class="carousel-control-next" type="button" data-bs-target="#carouselExampleIndicators2" data-bs-slide="next">
      <span class="carousel-control-next-icon" aria-hidden="true"></span>
      <span class="visually-hidden">Next</span>
    </button>
  </div>
 </div>


Solution

  • I believe that is what you are looking for, but I'm not sure if it is the best practice in terms of structure, but it is 100% responsive and functional.

    const myCarousel = document.getElementById("carouselExampleIndicators2");
    const carouselIndicators = myCarousel.querySelectorAll(
      ".carousel-indicators button span"
    );
    let intervalID;
    
    const carousel = new bootstrap.Carousel(myCarousel);
    
    window.addEventListener("load", function () {
      fillCarouselIndicator(1);
    });
    
    myCarousel.addEventListener("slide.bs.carousel", function (e) {
      let index = e.to;
      fillCarouselIndicator(++index);
    });
    
    function fillCarouselIndicator(index) {
      let i = 0;
      for (const carouselIndicator of carouselIndicators) {
        carouselIndicator.style.width = 0;
      }
      clearInterval(intervalID);
      carousel.pause();
    
      intervalID = setInterval(function () {
        i++;
    
        myCarousel.querySelector(".carousel-indicators .active span").style.width =
          i + "%";
    
        if (i >= 100) {
          // i = 0; -> just in case
          carousel.next();
        }
      }, 50);
    }
    #carouselExampleIndicators2 .carousel-item p{ 
      font-family:'Giove',sans-serif; 
      text-transform: uppercase;
      margin:  16px 200px;
      font-size: 22px;
      color: #e9c8b9;
    }
    
    #carouselExampleIndicators2 .carousel-item p::before {
      content: url(../images/vec.png);
      position: absolute;
      top: 0%;
      left: 21.5%;
      opacity: 14%;
    }
    
    
    #carouselExampleIndicators2 .carousel-indicators [data-bs-target] {
      position: absolute;
      width: 100px;
      height: 1.9px;
      border: 0.2px solid #e9c8b9;
      border-radius: 24px;
      background: transparent;
      cursor: default;
    }
    
    #carouselExampleIndicators2 .carousel-indicators [data-bs-target] span {
      content: "";
      position: absolute;
      top: 0%;
      left: 0%;
      width: 0;
      height: 100%;
      background: #e9c8b9;
      border-radius: inherit;
      cursor: default;
    }
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"/>
    <div class="container-fluid text-center section0 px-0 bg-dark">
      <div id="carouselExampleIndicators2" class="carousel slide" data-bs-ride="carousel" data-bs-pause="true">
        <div class="carousel-indicators">
          <button type="button" data-bs-target="#carouselExampleIndicators2" data-bs-slide-to="0" class="active" aria-current="true" aria-label="Slide 1">
            <span></span>
          </button>
          <button type="button" data-bs-target="#carouselExampleIndicators2" data-bs-slide-to="1" aria-label="Slide 2">
            <span></span>
          </button>
          <button type="button" data-bs-target="#carouselExampleIndicators2" data-bs-slide-to="2" aria-label="Slide 3">
            <span></span>
          </button>
        </div>
        <div class="carousel-inner pb-5">
          <div class="carousel-item active">
            <p>The most exclusive listings in Europe and the Middle East, <br>
              carefully handpicked to deliver state-of-the-art <br>
              customer experience.</p>
              <!-- <div class="number">1</div> -->
          </div>
          <div class="carousel-item">
            <p>The most exclusive listings in Europe and the Middle East, <br>
              carefully handpicked to deliver state-of-the-art <br>
              customer experience.</p>
          </div>
          <div class="carousel-item">
            <p>The most exclusive listings in Europe and the Middle East, <br>
              carefully handpicked to deliver state-of-the-art <br>
              customer experience.</p>
          </div>
        </div>
       
      </div>
     </div>