0

Using TailwindCSS and Flowbite to add a Carousel to my page. I have also added a toggle switch element that basically allows me to cycle between the two items in the Carousel (checked = slide 2, unchecked = slide 1).

This WORKS - where I'm stuck is attempting to set it to "slide 2" on load based on the stored value of that toggle in localStorage.

I've verified that my localStorage value is being saved/retrieved properly (as "yes" and "no" strings). I then attempt to set the Carousel to either slide 1 ("no" value) or slide 2 ("yes" value) on load, but no matter what I attempt, it always displays slide 1.

I've attempted both the "slideTo()" and the "next()" methods, but neither seem to work (they DO work in the change event, but not in my load function).

There are NO errors in the console. And like I said, the toggle works fine after page load and cycles properly between the slides, it just doesn't set the correct slide on page load (so the slide displayed doesn't match the accurate setting of the toggle).

Flowbite carousel docs: https://flowbite.com/docs/components/carousel/

Here is my code:

window.addEventListener('load', function () {
    show_loader("service-suspended-container");

    // Sidebar Toggle Defaults and Handler
    const exclude_suspended_toggle = document.getElementById('exclude-suspended-toggle');

    // Determine which slide to display based on user's preference
    var starting_item = 0;
    if (('metrics-exclude-suspended' in localStorage) && localStorage.getItem('metrics-exclude-suspended') === 'yes') {
        starting_item = 1;
    }
    
    const carousel_items = [
        {
            position: 0,
            el: document.getElementById('carousel-item-1')
        },
        {
            position: 1,
            el: document.getElementById('carousel-item-2')
        }
    ];

    const options = {
        defaultPosition: starting_item
    }

    // Carousel object for controlling slide
    var carousel = new Carousel(carousel_items, options);

    // Ecclude suspended toggle handler
    exclude_suspended_toggle.addEventListener('change',  (event) => {
        console.log("Event fired");
        if (event.currentTarget.checked) {
            // Make toggle checked
            console.log("Toggle now checked");
            localStorage.setItem('metrics-exclude-suspended', 'yes');
            carousel.slideTo(1);
        } else {
            // Uncheck toggle
            console.log("Toggle now unchecked");
            localStorage.setItem('metrics-exclude-suspended', 'no');
            carousel.slideTo(0);
        }
    });

    // Determine default check state of toggle and slide from user's preferences
    if (('metrics-exclude-suspended' in localStorage) && localStorage.getItem('metrics-exclude-suspended') === 'yes') {
        console.log("enabled from storage...");
        // Make toggle checked
        exclude_suspended_toggle.checked = true;
        carousel.slideTo(1);
    } else {
        console.log("disabled from storage...");
        // Uncheck toggle
        exclude_suspended_toggle.checked = false;
        carousel.slideTo(0);
    }
});
Source Matters
  • 1,110
  • 2
  • 15
  • 35

1 Answers1

0

You are changing the checked attribute programmatically, which doesn't fire the change event. Since the change event isn't fired, the event listener isn't called.

One way to fire the change event:

const changeEvent = new Event("change")
exclude_suspended_toggle.dispatchEvent(changeEvent)

So, in your code, it would become:

const changeEvent = new Event("change")

// Determine default check state of toggle and slide from user's preferences
if (('metrics-exclude-suspended' in localStorage) && localStorage.getItem('metrics-exclude-suspended') === 'yes') {
    console.log("enabled from storage...");
    // Make toggle checked
    exclude_suspended_toggle.checked = true;
    exclude_suspended_toggle.dispatchEvent(changeEvent)
} else {
    console.log("disabled from storage...");
    // Uncheck toggle
    exclude_suspended_toggle.checked = false;
    exclude_suspended_toggle.dispatchEvent(changeEvent)
}
Geshode
  • 3,600
  • 6
  • 18
  • 32
  • I actually tried that originally too with no luck. Used your code above and seeing same exact behavior. No matter how toggle is set (saved), when I refresh, the toggle reflects the localStorage setting, but the carousel always shows the first slide. – Source Matters May 12 '23 at 01:13
  • So, you get the console.logs, that the event was fired, but the carousel isn't changed? – Geshode May 12 '23 at 01:15
  • Correct - on page refresh with the toggle "checked" already, here is the console output: index: 694 enabled from storage... index:676 Event fired index:679 Toggle now checked – Source Matters May 12 '23 at 01:17
  • Strange, especially because you also set the `defaultPosition` of the carousel based on if it is toggled or not. – Geshode May 12 '23 at 01:23