stimulus-carousel
stimulus-carousel copied to clipboard
Reference multiple instances from controller
Hi,
I've been struggling to work out how to achieve the swiper thumbs navigation like here:
How would i set up multiple carousels and pass the reference of one to the other with stimulus? Like this:
<script>
var swiper = new Swiper(".mySwiper", {
spaceBetween: 10,
slidesPerView: 4,
freeMode: true,
watchSlidesProgress: true,
});
var swiper2 = new Swiper(".mySwiper2", {
spaceBetween: 10,
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev",
},
thumbs: {
swiper: swiper,
},
});
</script>
Hi,
I think in this case, you should override the controller and do this inside it
Hi, @guillaumebriday!
is it possible to implement it regularly in your module?
To implement something like https://codepen.io/rogerkuik/pen/abZOLXr, I created a stimulus controller ad_carousel:
import { Controller } from '@hotwired/stimulus'
import Swiper from 'swiper/bundle'
export default class extends Controller {
connect() {
let galleryThumbs = new Swiper(".gallery-thumbs", {
centeredSlides: true,
centeredSlidesBounds: true,
direction: "horizontal",
spaceBetween: 10,
slidesPerView: 3,
freeMode: false,
watchSlidesVisibility: true,
watchSlidesProgress: true,
watchOverflow: true,
breakpoints: {
480: {
direction: "vertical",
slidesPerView: 3
}
}
})
let galleryTop = new Swiper(".gallery-top", {
direction: "horizontal",
spaceBetween: 10,
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev"
},
a11y: {
prevSlideMessage: "Previous slide",
nextSlideMessage: "Next slide",
},
keyboard: {
enabled: true,
},
thumbs: {
swiper: galleryThumbs
}
})
galleryTop.on("slideChangeTransitionStart", function () {
galleryThumbs.slideTo(galleryTop.activeIndex)
})
galleryThumbs.on("transitionStart", function () {
galleryTop.slideTo(galleryThumbs.activeIndex)
})
}
}
Placed the following code in the view:
<div class="swiper-container-wrapper" data-controller="ad_carousel">
<!-- Slider main container -->
<div class="swiper-container gallery-top">
...
</div>
How can this code be improved? Is there any way to override your controller? Create two controllers and somehow use one controller in another via options?
Please show examples. Thank you in advance!
After small changes:
import {Controller} from '@hotwired/stimulus'
import Swiper from 'swiper/bundle'
export default class extends Controller {
static targets = ["thumbs", "top"]
static values = {
thumbs: Object,
top: Object
}
initialize() {
this.gallery_thumbs = new Swiper(this.thumbsTarget, {
...this.defaultThumbsOptions,
...this.thumbsValue
})
this.gallery_top = new Swiper(this.topTarget, {
...this.defaultTopOptions,
...this.topValue
})
}
connect() {
let galleryTop = this.gallery_top
let galleryThumbs = this.gallery_thumbs
galleryTop.on("slideChangeTransitionStart", function () {
galleryThumbs.slideTo(galleryTop.activeIndex)
})
galleryThumbs.on("transitionStart", function () {
galleryTop.slideTo(galleryThumbs.activeIndex)
})
}
disconnect() {
this.gallery_thumbs.destroy()
this.gallery_thumbs = undefined
this.gallery_top.destroy()
this.gallery_top = undefined
}
get defaultTopOptions() {
return {
direction: "horizontal",
spaceBetween: 10,
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev"
},
a11y: {
prevSlideMessage: "Previous slide",
nextSlideMessage: "Next slide",
},
keyboard: {
enabled: true,
},
thumbs: {
swiper: this.gallery_thumbs
}
}
}
get defaultThumbsOptions() {
return {
centeredSlides: true,
centeredSlidesBounds: true,
direction: "horizontal",
spaceBetween: 10,
slidesPerView: 3,
freeMode: false,
watchSlidesVisibility: true,
watchSlidesProgress: true,
watchOverflow: true,
breakpoints: {
480: {
direction: "vertical",
slidesPerView: 3
}
}
}
}
}
In view:
<div class='swiper-container-wrapper' data-carousel-with-thumbs-thumbs-value='{}' data-carousel-with-thumbs-top-value='{ "a11y": { "prevSlideMessage": "Prev", "nextSlideMessage": "Next" } }' data-controller='carousel-with-thumbs'>
<!-- Slider main container -->
<div class='swiper-container gallery-top' data-carousel-with-thumbs-target='top'>
<!-- Additional required wrapper -->
...
</div>
</div>