I wrote a custom Shopify section. The section contains a slider, and each block added to the section results in a new slide added to the slider.
When editing slides (blocks), the slider should automatically slide to the selected block for proper preview experience. I wrote a js function for that, that works perfectly fine:
if (Shopify.designMode) {
document.addEventListener('shopify:block:select', function(event) {
const sectionSelectedIsHero = event.target.classList.contains('hero-slide');
if(!sectionSelectedIsHero) return;
var selectedSlideId = $(event.target).attr("data-slide-id");
heroCarousel.to(selectedSlideId);
});
}
However, when a user edits a slide (block), for example the background color in a color picker, Shopify automatically reloads the section in the ThemeEditor to update the preview for the user.
While the shopify:block:select event is being fired again (I can track âeventâ variable in console.log()), the slider doesnt work at all after that. The first slide is in preview and the controls also stop working. When selecting different slides (blocks), nothing happens.
Appreciate any help. Thanks!
Hi @ecom3_1 ,
You can try changing it with the following code:
if (Shopify.designMode) {
document.addEventListener('shopify:block:select', function(event) {
const sectionSelectedIsHero = event.target.classList.contains('hero-slide');
if(!sectionSelectedIsHero) return;
const evt = document.createEvent('UIEvents');
evt.initUIEvent('resize', true, false, window, 0);
window.dispatchEvent(evt);
});
}
Hope it helps!
Hi @LitExtension ,
unfortunately this didnât change anything. After a user edits something, the section is being reloaded without any of the js functionality. Which is especially weird because the âshopify:block:selectâ-Event is being fired again after auto-reload of the section. I can console.log() it inside document.addEventListenerâŚ
The Shopify docs say that there are events being fired when sections are being re-rendered, and that js should be re-executed:
from: https://shopify.dev/themes/architecture/sections/integrate-sections-with-the-theme-editor
I have tried something like this, but i just cant seem to get it to work:
if (Shopify.designMode) {
document.addEventListener('shopify:block:select', slideToSelectedSlide = function(event) {
const sectionSelectedIsHero = event.target.classList.contains('hero-slide');
if(!sectionSelectedIsHero) return;
var selectedSlideId = $(event.target).attr("data-slide-id");
heroCarousel.to(selectedSlideId);
});
document.addEventListener('shopify:section:unload', function(e) {
console.log(e);
//Here is where I stuck - removeEventListeners? Call slideToSelectedSlide again?
//document.removeEventListener('shopify:block:select', slideToSelectedSlide);
//document.addEventListener('shopify:section:load', slideToSelectedSlide);
});
}
I now have a working solution. However, this is not optimal at all as im repeating code just to make it execute again. If anyone has a âbetter practiceâ-solution here, please share!
$( document ).ready(function() {
var heroCarouselElement = document.querySelector('#heroCarousel');
var heroCarousel = new bootstrap.Carousel(heroCarouselElement, {
interval: false,
keyboard: false,
wrap: true,
touch: true
});
$("#heroControlPrev").click(function() { heroCarousel.prev(); });
$("#heroControlNext").click(function() { heroCarousel.next(); });
if (Shopify.designMode) {
document.addEventListener('shopify:block:select', function(event) {
const sectionSelectedIsHero = event.target.classList.contains('hero-slide');
if(!sectionSelectedIsHero) return;
var selectedSlideId = $(event.target).attr("data-slide-id");
var heroCarouselElement = document.querySelector('#heroCarousel');
var heroCarousel = new bootstrap.Carousel(heroCarouselElement, {
interval: false,
keyboard: false,
wrap: true,
touch: true
});
$("#heroControlPrev").click(function() { heroCarousel.prev(); });
$("#heroControlNext").click(function() { heroCarousel.next(); });
heroCarousel.to(selectedSlideId);
});
}
});
1 Like
Had the same issue. This resolved it for me. Thank you!