Search code examples
angularswiper.js

Angular and SwiperJS - Reset nested slider index on parent slider index change


I have a nested slider (one vertical, the parent one, and one horizontal, the child one) and i would like to reset the index of the child on parent index change. Slides are created dinamically based on a list of object.

Maybe someone can hint me on how to get the current horizontal swiper so i can access its index and change it?

Thanks to everyone :)

swiper-homepage.component.html:

 <div>
  <div class="col-10 offset-1 col-md-3 offset-md-4 col-lg-3 offset-lg-4 col-xl-4 offset-xl-4 center">
    <div class="card">
  <swiper #verticalSwiper [config]="verticalConfig" (swiper)="onVerticalSwiper($event)"
    (slideChange)="onVerticalSlideChange($event)" (transitionEnd)="onVerticalTransitionEnd($event)"
    (transitionStart)="onTransictionStart($event)">

    <ng-template swiperSlide *ngFor="let company of companies">
      <div class="text-white">

        <swiper [attr.ib]="'horSwiper' + currentCompanyIndex" [config]="horizontalConfig"
          (swiper)="onHorizontalSwiper($event)" (transitionEnd)="onHorizontalTransitionEnd($event)"
          (slideChange)="onHorizontalSlideChange($event)">
          <ng-template swiperSlide>
            <detail-slide [company]="company">
            </detail-slide>
          </ng-template>
          <ng-template swiperSlide *ngFor="let multimedia of company.multiMedia">
            <img [src]="multimedia.mediaURL" class="card-img center-page-image" alt="...">
            <div class="card-img-overlay lower-third-company-name">
              <button type="button" class="btn btn-light" (click)="goToPage('detail')">{{
                company.companyName }}</button>
              <p class="card-text description-with-top-margin">{{ company.companyDescription }}</p>
            </div>
          </ng-template>
        </swiper>

      </div>
    </ng-template>

  </swiper>
  
</div>

swiper-homepage.components.ts:

 import { Component, OnInit, ViewChild } from '@angular/core';
import { Router } from '@angular/router';
import { withLatestFrom } from 'rxjs';
import { RouterControllerComponent } from 'src/app/component/router-controller/router-controller.component';
import { GestureController } from 'src/app/interfaces/gesture-controller';
import { Company } from 'src/app/object/company';
import { CompanyService } from 'src/app/service/company.service';
import SwiperCore, { Swiper, SwiperOptions } from 'swiper';
import { SwiperComponent } from 'swiper/angular';

@Component({
  selector: 'app-swiper-homepage',
  templateUrl: './swiper-homepage.component.html',
  styleUrls: ['./swiper-homepage.component.css']
})
export class SwiperHomepageComponent extends RouterControllerComponent implements OnInit{

  verticalConfig: SwiperOptions = {
    slidesPerView: 1,
    spaceBetween: 50,
    direction: 'vertical',
    preloadImages: false,
    // Enable lazy loading
    lazy: true,
    initialSlide: 0
  };

  horizontalConfig: SwiperOptions = {
    slidesPerView: 1,
    spaceBetween: 50,
    direction: 'horizontal',
    preloadImages: false,
    // Enable lazy loading
    lazy: true,
    observeParents: true,
    initialSlide: 1
  }

  private currentHorizontalSwiper = new Swiper('', {});
  

  public currentCompanyIndex = 0;
  public isReadyToDetail = false;
  public companies: Company[] = [];
  
  constructor(
    private readonly companyService: CompanyService,
    readonly router: Router
  ) {
    super(router);
   }

  ngOnInit(): void {
    this.loadPage();
  }

  //TODO manage the company arrangement, allow infinite

  loadPage(){
    this.companyService.getAllCompanies().subscribe(gettedCompanies =>{
      this.companies = gettedCompanies;
    });
  }

  onVerticalSwiper(swiper: any) {
    console.log(swiper);
  }

  onHorizontalSwiper(swiper: any) {}

  onVerticalSlideChange(swiper: any) {
    console.log(swiper);

  }

  onHorizontalSlideChange(swiper: any) {
    this.currentCompanyIndex = swiper.activeIndex;
    if(swiper.activeIndex === 0)
      this.isReadyToDetail = true;
  }

  onVerticalTransitionEnd(swiper: any){
    console.log("END");
    console.log(swiper);
  }

  onHorizontalTransitionEnd(swiper: any){
    if(swiper.activeIndex === 0)
      this.isReadyToDetail = true;
  }
  
  onTransictionStart(swiper: any){
    console.log("START");
    console.log(swiper);
  }

  onBeforeTransiction(swiper: any){
    console.log("BEFORE START");
    console.log(swiper);
  }

  //TODO capire come funzionano gli observer, per resettare i vari index
  

}

Solution

  • As we won't have access to dynamically created swiper instances, we may consider creating a wrapper Angular component (which in turn renders swiper by taking props from the loop) and render that in your loop. When ever your parent slider changes, use your preferred Angular's event mechanism to alert all wrapper components so that they would reset themselves.

    As we pass swiper props to wrapper component, we can use @ViewChild to get hold of swiper instance