angularbootstrap-5angular16

Bootstrap carousel dynamic attribute in Angular


I am using a Bootstrap 5 carousel that comes with the data-bs-ride="carousel" attribute to autoplay the slides. By using "false" instead of "carousel" it doesn't auto play.

I am trying to swap "carousel" with "false" with buttons so the user can pause the auto play mode:

This is my HTML code:

<div class="container">
      <!-- WHEN data-bs-ride="carousel" it auto-plays, when data-bs-ride="false" it stops -->
      <div #carousel id="carousel" class="carousel slide" data-bs-ride="carousel" data-bs-pause="false">
        <div class="carousel-indicators">
          <button type="button" data-bs-target="#carousel" data-bs-slide-to="0" class="active" aria-current="true" aria-label="Slide 1"></button>
          <button type="button" data-bs-target="#carousel" data-bs-slide-to="1" aria-label="Slide 2"></button>
          <button type="button" data-bs-target="#carousel" data-bs-slide-to="2" aria-label="Slide 3"></button>
        </div>
        
        <div class="carousel-inner">

          <div *ngFor="let item of carouselItemsHorizontal" class="carousel-item {{item.activeClass}}" data-bs-interval="3000">
            <img src="{{item.imageSrc}}" class="carouselImage d-flex justify-content-center" alt="{{item.imageAlt}}">
              <div class="carousel-caption d-none d-md-block">
                <button routerLink="about" class="btn">Learn more</button>
              </div>
          </div>
          
        </div>
        
        <div class="carouselPlayPause">
          <svg (click)="playClick()" *ngIf="isPlaying" xmlns="http://www.w3.org/2000/svg" width="30" height="30" fill="currentColor" class="bi bi-play playPauseColor" viewBox="0 0 16 16">
            <path d="M10.804 8 5 4.633v6.734zm.792-.696a.802.802 0 0 1 0 1.392l-6.363 3.692C4.713 12.69 4 12.345 4 11.692V4.308c0-.653.713-.998 1.233-.696z"/>
            <path d="M14 1a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2z"/>
          </svg>

          <svg (click)="pauseClick()" *ngIf="!isPlaying" xmlns="http://www.w3.org/2000/svg" width="30" height="30" fill="currentColor" class="bi bi-pause playPauseColor" viewBox="0 0 16 16">
            <path d="M6 3.5a.5.5 0 0 1 .5.5v8a.5.5 0 0 1-1 0V4a.5.5 0 0 1 .5-.5m4 0a.5.5 0 0 1 .5.5v8a.5.5 0 0 1-1 0V4a.5.5 0 0 1 .5-.5"/>
            <path d="M14 1a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2z"/>
          </svg>
        </div>
        
      </div>
    </div>

This is my TypeScript class:

export class HomeCarouselComponent {

  dataRide:string = 'carousel';
  isPlaying:boolean = false;

  playClick():void {
    this.dataRide = 'carousel';
    this.isPlaying = !this.isPlaying;
  }

  pauseClick():void {
    this.dataRide = 'false';
    this.isPlaying = !this.isPlaying;
  }

  carouselItemsHorizontal:CarouselItems[] = [
    {
      imageSrc: '../../assets/images/home-images/carousel/main-artboard.png',
      imageAlt: 'Welcome to "Learning Angular" Application banner.',
      activeClass: 'active'
    },
    {
      imageSrc: '../../assets/images/home-images/carousel/sections-artboard.png',
      imageAlt: 'sections',
    },
    {
      imageSrc: '../../assets/images/home-images/carousel/projects-artboard.png',
      imageAlt: 'projects',
    },
  ]
}

There's this interface on top as well, for the items shape:

interface CarouselItems {
  imageSrc:string;
  imageAlt:string;
  activeClass?:string;
}

I tried this [data-bs-ride]="dataRide" but gives this error: Can't bind to 'data-bs-ride' since it isn't a known property of 'div'.ngtsc(-998002)

I also tried this [attr.data-bs-ride]="dataRide", no errors but the buttons don't pause/play the carousel.

Can't use string interpolation either.

Any good suggestions please?

Thank you very much in advance!!!

[data-bs-ride]="dataRide" gives error: ngtsc(-998002)

[attr.data-bs-ride]="dataRide", no errors but the buttons don't pause/play the carousel.


Solution

  • No, that won't work, because you cannot pause/start carousel instance with HTML element attributes.

    Instead, control it with JavaScript.

    Simply get carousel instance in the component, and then instead of changing data attributes, pause or slide with .pause and .cycle methods in your corresponding component methods.

    Try this:

    // get element and instantiate carousel
    
    @ViewChild('carousel') carouselEl!:ElementRef;
    carousel!:Carousel;
    
    ngAfterViewInit() {
        this.carousel = Carousel.getOrCreateInstance(this.carouselEl.nativeElement);
    } 
    

    now simply control instance in your methods:

    // pause/play
    
    playClick():void {
    this.carousel.cycle();
    this.isPlaying = !this.isPlaying;
    }
    
    pauseClick():void {
    this.carousel.pause();
    this.isPlaying = !this.isPlaying;
    }
    

    Stackblitz demo