In this tutorial, we’ll learn how to sync two nestable sliders in Bricks: one will be the main slider and the other one will be a thumbnail slider.
Table of Contents
- Introduction
- The DOM tree
- The JSON settings for the Thumbnail slider
- The JavaScript Code
- The result
- Resources
Introduction
This tutorial is a follow-up to the great video of Udoro ‘Cracka’ Essien shared recently in the group. He explained how to sync two nested sliders in Bricks: one main slider and one used as a thumbnail.
This tutorial enhances the previous code shared by Cracka and allows you to:
- set and forget the Javascript Code. Once enqueued, you don’t have to touch it again as it’s based on classes rather than IDs
- insert multiple sync sliders on the same page
- avoid possible conflict with other plugins/snippets
- reduce the amount of JS calculation by debouncing the function on resize
Let’s dive into it!
The DOM tree
In order to work, we need
- a container (or a section / block / div) with the class
.sync-sliders-wrapper
- the two sliders to be children of the container
- the main slider needs the class
.sync-sliders-main
- the thumbnail slider needs the class
.sync-sliders-thumb
The JSON settings for the Thumbnail slider
As explained by Cracka in his video, you need to insert a custom JSON object as the thumbnail slider setting options. I’ll just paste the code for reference:
{
"type":"slide",
"direction":"ltr",
"keyboard":"global",
"height":"auto",
"gap":10,
"start":0,
"perPage":"3",
"perMove":1,
"speed":400,
"interval":3000,
"autoHeight":true,
"autoplay":false,
"pauseOnHover":false,
"pauseOnFocus":false,
"arrows":false,
"pagination":false,
"focus": "center",
"isNavigation": true,
"updateOnMove": true,
"breakpoints":{
"580":{
"perPage":"2"
}
}
}
The most important string here is "isNavigation": true
that will set the slider as a navigation slider.
The JavaScript Code
Enqueue the following code in your child theme or use a code snippet plugin:
document.addEventListener('DOMContentLoaded', () => {
// Query all the wrappers
const wrappers = document.querySelectorAll('.sync-sliders-wrapper');
// Stop the function if there is no sync slider
if (wrappers.length < 1) return;
// Debounce function
const debounce = (fn, threshold) => {
var timeout;
threshold = threshold || 200;
return function debounced() {
clearTimeout(timeout);
var args = arguments;
var _this = this;
function delayed() {
fn.apply(_this, args);
}
timeout = setTimeout(delayed, threshold);
};
};
// Init function
const init = (mainSliderId, thumbSliderId) => {
const main = bricksData.splideInstances[mainSliderId],
thumbnail = bricksData.splideInstances[thumbSliderId];
// Mount the sync slider
main.sync(thumbnail);
};
// Loop into each wrapper
wrappers.forEach(wrapper => {
// Set the ID of the main slider
const mainSlider = wrapper.querySelector('.sync-sliders-main');
// Check if the main slider class is correctly set
if (!mainSlider) return console.log('No .sync-sliders-main class found');
const mainSliderId = mainSlider.dataset.scriptId;
// Set the ID of the thumb slider
const thumbSlider = wrapper.querySelector('.sync-sliders-thumb');
// Check if the thumb slider class is correctly set
if (!thumbSlider) return console.log('No .sync-sliders-thumb class found');
const thumbSliderId = thumbSlider.dataset.scriptId;
// Run the function on load
setTimeout(() => {
init(mainSliderId, thumbSliderId);
}, 0);
// Rerun the function on resize because bricks reinit the sliders on each resize event
window.addEventListener("resize", debounce(() => {
init(mainSliderId, thumbSliderId);
}, 300));
});
});
The result
If everything worked, you should see this result on frontend:
Resources
Debounce function
https://www.freecodecamp.org/news/javascript-debounce-example/
7 comments
Dale Donnolly
Hi Sridhar,
I've implemented both versions of this method (Maxime & Cracka) and both work as expected.
I am however trying to open the Main Slider Image (sync-sliders-main) in a lightbox when clicked by setting the Link To 'Lightbox' option in Bricks. The lightbox opens but as it zooms in it opens the Placeholder image > '/wp-content/themes/bricks/assets/images/placeholder-image-800x600.jpg' instead of the product / gallery image.
How can I remedy this?
Gustavo Denecken
Hi all !
It worked very good for me but...
Even when the "big images" are not shown and lazy loaded, when I run the site on Google's PageSpeed, it shows "white squares" (that are the slider's images not being yet shown) telling me to use a "Proper Image Size" for those images...
Is there any way to improve that and allow the images to load ONLY when the thumbnail is clicked or similar?
Thanks !
Travis Reason
Any help?
Sridhar Katakam
Just took a look and the fix is quite simple.
In the JSON code ensure that there is no comma near the end.
It should be like this: https://d.pr/i/7HGxGj
and not https://d.pr/i/dWOUQI.
Travis Reason
As far as I can tell, I've followed everything in these instructions (including watching both of Cracka's videos) but I can't figure out what I'm doing wrong. The bottom slider (thumb) will not display for me. As soon as I set the Options type to Custom and paste in the json, the thumb slider shrinks down very small, but only displays 1 slide, not 3. then, when I look on the front end there's nothing there. It's in the DOM, but not displaying.
I've set this up in a template and here's an example post: https://spacecityfencing.northonyx.com/fencing/spring-break-camp/
Any advice?
Sridhar Katakam
Hi Travis. While you are waiting for a reply from Maxime just want to let you know that this can be done w/o writing any code using our BricksExtras plugin.
https://bricksextras.com/docs/pro-slider/
https://brickssections.com/acf-gallery-thumbnail-slider/
Travis Reason
yeah, i was debating buying into BricksLabs or getting BricksExtras (just for this one slider on one site! :/ ). I decided to try this method first so I don't have to have another plugin on the site just for this one feature.