Search code examples
javascriptjquerycarouseljcarousel

Using two instances of Connected Carousels (jCarousel) on the same page


I am using jCarousel, specifically the Connected Carousels that you can see at https://sorgalla.com/jcarousel/examples/connected-carousels/. For an A/B testing experiment, I need to use two instances of the Connected Carousels. The first one works correctly. The second one does not. For the second instance, I click the thumbnail pictures and the big pictures do not change. I do not think the official documentation provides examples for having multiple Connected Carousels on a single page. Any hints about how to achieve it? What I have tried is to investigate how https://sorgalla.com/jcarousel/docs/reference/api.html#reload could be used. I was thinking about maybe incorporating this in my main JavaScript file:

$('.jcarousel').jcarousel('reload', {
    animation: 'slow'
});

However, that is not fixing the problem for me. Any hints? Thank you.

UPDATE 1:

See the original code at https://github.com/jsor/jcarousel/blob/master/examples/connected-carousels/index.html. Now see what I am trying to do adding a second instance of the connected carousel:

<!doctype html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Connected Carousels - jCarousel Examples</title>

        <!-- Shared assets -->
        <link rel="stylesheet" type="text/css" href="../_shared/css/style.css">

        <!-- Example assets -->
        <link rel="stylesheet" type="text/css" href="jcarousel.connected-carousels.css">

        <script type="text/javascript" src="../../vendor/jquery/jquery.js"></script>
        <script type="text/javascript" src="../../dist/jquery.jcarousel.min.js"></script>

        <script type="text/javascript" src="jcarousel.connected-carousels.js"></script>

    </head>
    <body>

        <div class="wrapper">
            <h1>Connected Carousels</h1>

            <p>This example shows how to connect two carousels together so that one carousels acts as a navigation for the other.</p>

            <div class="connected-carousels">
                <div class="stage">
                    <div class="carousel carousel-stage">
                        <ul>
                            <li><img src="../_shared/img/img1.jpg" width="600" height="400" alt=""></li>
                            <li><img src="../_shared/img/img2.jpg" width="600" height="400" alt=""></li>
                            <li><img src="../_shared/img/img3.jpg" width="600" height="400" alt=""></li>
                            <li><img src="../_shared/img/img4.jpg" width="600" height="400" alt=""></li>
                            <li><img src="../_shared/img/img5.jpg" width="600" height="400" alt=""></li>
                            <li><img src="../_shared/img/img6.jpg" width="600" height="400" alt=""></li>
                        </ul>
                    </div>
                    <p class="photo-credits">
                        Photos by <a href="http://www.mw-fotografie.de">Marc Wiegelmann</a>
                    </p>
                    <a href="#" class="prev prev-stage"><span>&lsaquo;</span></a>
                    <a href="#" class="next next-stage"><span>&rsaquo;</span></a>
                </div>

                <div class="navigation">
                    <a href="#" class="prev prev-navigation">&lsaquo;</a>
                    <a href="#" class="next next-navigation">&rsaquo;</a>
                    <div class="carousel carousel-navigation">
                        <ul>
                            <li><img src="../_shared/img/img1_thumb.jpg" width="50" height="50" alt=""></li>
                            <li><img src="../_shared/img/img2_thumb.jpg" width="50" height="50" alt=""></li>
                            <li><img src="../_shared/img/img3_thumb.jpg" width="50" height="50" alt=""></li>
                            <li><img src="../_shared/img/img4_thumb.jpg" width="50" height="50" alt=""></li>
                            <li><img src="../_shared/img/img5_thumb.jpg" width="50" height="50" alt=""></li>
                            <li><img src="../_shared/img/img6_thumb.jpg" width="50" height="50" alt=""></li>
                        </ul>
                    </div>
                </div>
            </div>



            <div class="connected-carousels">
                <div class="stage">
                    <div class="carousel carousel-stage">
                        <ul>
                            <li><img src="../_shared/img/img1.jpg" width="600" height="400" alt=""></li>
                            <li><img src="../_shared/img/img2.jpg" width="600" height="400" alt=""></li>
                            <li><img src="../_shared/img/img3.jpg" width="600" height="400" alt=""></li>
                            <li><img src="../_shared/img/img4.jpg" width="600" height="400" alt=""></li>
                            <li><img src="../_shared/img/img5.jpg" width="600" height="400" alt=""></li>
                            <li><img src="../_shared/img/img6.jpg" width="600" height="400" alt=""></li>
                        </ul>
                    </div>
                    <p class="photo-credits">
                        Photos by <a href="http://www.mw-fotografie.de">Marc Wiegelmann</a>
                    </p>
                    <a href="#" class="prev prev-stage"><span>&lsaquo;</span></a>
                    <a href="#" class="next next-stage"><span>&rsaquo;</span></a>
                </div>

                <div class="navigation">
                    <a href="#" class="prev prev-navigation">&lsaquo;</a>
                    <a href="#" class="next next-navigation">&rsaquo;</a>
                    <div class="carousel carousel-navigation">
                        <ul>
                            <li><img src="../_shared/img/img1_thumb.jpg" width="50" height="50" alt=""></li>
                            <li><img src="../_shared/img/img2_thumb.jpg" width="50" height="50" alt=""></li>
                            <li><img src="../_shared/img/img3_thumb.jpg" width="50" height="50" alt=""></li>
                            <li><img src="../_shared/img/img4_thumb.jpg" width="50" height="50" alt=""></li>
                            <li><img src="../_shared/img/img5_thumb.jpg" width="50" height="50" alt=""></li>
                            <li><img src="../_shared/img/img6_thumb.jpg" width="50" height="50" alt=""></li>
                        </ul>
                    </div>
                </div>
            </div>


        </div>

    </body>
</html>

What happens is that the first row of thumbnails controls both big stage pictures, the one above and the one below. The second row of thumbnails does not work. You click on it and nothing happens:

enter image description here

UPDATE 2:

It seems to me that what I am trying to do is a basic and common thing that the jCarousel library should be able to handle easily. Nonetheless, I am not finding anything in the examples or documentation to achieve what I want and what I am considering is to modify https://github.com/jsor/jcarousel/blob/master/examples/connected-carousels/jcarousel.connected-carousels.js so that for example instead of only

// Setup the carousels. Adjust the options for both carousels here.
var carouselStage      = $('.carousel-stage').jcarousel();
var carouselNavigation = $('.carousel-navigation').jcarousel();

I can have for something like this:

// Setup the carousels. Adjust the options for both carousels here.
var carouselStage      = $('.carousel-stage').jcarousel();
var carouselNavigation = $('.carousel-navigation').jcarousel();
var carouselStage1      = $('.carousel-stage1').jcarousel();
var carouselNavigation1 = $('.carousel-navigation1').jcarousel();

What do you think about what I am planning to try (carouselStage1, carouselNavigation1, etc.)? I am not finding any other way to have both instances of jCarousel working correctly.


Solution

  • I made it work correctly by modifying all three files at https://github.com/jsor/jcarousel/tree/master/examples/connected-carousels. I am not sure if what I did was the most elegant solution and efficient solution, since as I mentioned in my question, from my point of view what I needed was a basic and common thing that the jCarousel library should be able to handle easily. Nonetheless, I tested my solution and it works correctly. Both jCarousels are now on the same page running correctly and independently from each other. See my solution:

    index.html

    <!doctype html>
    <html lang="en">
        <head>
            <meta charset="utf-8">
            <title>Connected Carousels - jCarousel Examples</title>
    
            <!-- Shared assets -->
            <link rel="stylesheet" type="text/css" href="../_shared/css/style.css">
    
            <!-- Example assets -->
            <link rel="stylesheet" type="text/css" href="jcarousel.connected-carousels.css">
    
            <script type="text/javascript" src="../../vendor/jquery/jquery.js"></script>
            <script type="text/javascript" src="../../dist/jquery.jcarousel.min.js"></script>
    
            <script type="text/javascript" src="jcarousel.connected-carousels.js"></script>
    
        </head>
        <body>
    
            <div class="wrapper">
                <h1>Connected Carousels</h1>
    
                <p>This example shows how to connect two carousels together so that one carousels acts as a navigation for the other.</p>
    
                <div class="connected-carousels">
                    <div class="stage">
                        <div class="carousel carousel-stage">
                            <ul>
                                <li><img src="../_shared/img/img1.jpg" width="600" height="400" alt=""></li>
                                <li><img src="../_shared/img/img2.jpg" width="600" height="400" alt=""></li>
                                <li><img src="../_shared/img/img3.jpg" width="600" height="400" alt=""></li>
                                <li><img src="../_shared/img/img4.jpg" width="600" height="400" alt=""></li>
                                <li><img src="../_shared/img/img5.jpg" width="600" height="400" alt=""></li>
                                <li><img src="../_shared/img/img6.jpg" width="600" height="400" alt=""></li>
                            </ul>
                        </div>
                        <p class="photo-credits">
                            Photos by <a href="http://www.mw-fotografie.de">Marc Wiegelmann</a>
                        </p>
                        <a href="#" class="prev prev-stage"><span>&lsaquo;</span></a>
                        <a href="#" class="next next-stage"><span>&rsaquo;</span></a>
                    </div>
    
                    <div class="navigation">
                        <a href="#" class="prev prev-navigation">&lsaquo;</a>
                        <a href="#" class="next next-navigation">&rsaquo;</a>
                        <div class="carousel carousel-navigation">
                            <ul>
                                <li><img src="../_shared/img/img1_thumb.jpg" width="50" height="50" alt=""></li>
                                <li><img src="../_shared/img/img2_thumb.jpg" width="50" height="50" alt=""></li>
                                <li><img src="../_shared/img/img3_thumb.jpg" width="50" height="50" alt=""></li>
                                <li><img src="../_shared/img/img4_thumb.jpg" width="50" height="50" alt=""></li>
                                <li><img src="../_shared/img/img5_thumb.jpg" width="50" height="50" alt=""></li>
                                <li><img src="../_shared/img/img6_thumb.jpg" width="50" height="50" alt=""></li>
                            </ul>
                        </div>
                    </div>
                </div>
    
    
    
                <div class="connected-carousels">
                    <div class="stage">
                        <div class="carousel carousel-stage1">
                            <ul>
                                <li><img src="../_shared/img/img1.jpg" width="600" height="400" alt=""></li>
                                <li><img src="../_shared/img/img2.jpg" width="600" height="400" alt=""></li>
                                <li><img src="../_shared/img/img3.jpg" width="600" height="400" alt=""></li>
                                <li><img src="../_shared/img/img4.jpg" width="600" height="400" alt=""></li>
                                <li><img src="../_shared/img/img5.jpg" width="600" height="400" alt=""></li>
                                <li><img src="../_shared/img/img6.jpg" width="600" height="400" alt=""></li>
                            </ul>
                        </div>
                        <p class="photo-credits">
                            Photos by <a href="http://www.mw-fotografie.de">Marc Wiegelmann</a>
                        </p>
                        <a href="#" class="prev prev-stage"><span>&lsaquo;</span></a>
                        <a href="#" class="next next-stage"><span>&rsaquo;</span></a>
                    </div>
    
                    <div class="navigation">
                        <a href="#" class="prev prev-navigation">&lsaquo;</a>
                        <a href="#" class="next next-navigation">&rsaquo;</a>
                        <div class="carousel carousel-navigation1">
                            <ul>
                                <li><img src="../_shared/img/img1_thumb.jpg" width="50" height="50" alt=""></li>
                                <li><img src="../_shared/img/img2_thumb.jpg" width="50" height="50" alt=""></li>
                                <li><img src="../_shared/img/img3_thumb.jpg" width="50" height="50" alt=""></li>
                                <li><img src="../_shared/img/img4_thumb.jpg" width="50" height="50" alt=""></li>
                                <li><img src="../_shared/img/img5_thumb.jpg" width="50" height="50" alt=""></li>
                                <li><img src="../_shared/img/img6_thumb.jpg" width="50" height="50" alt=""></li>
                            </ul>
                        </div>
                    </div>
                </div>
    
    
            </div>
    
        </body>
    </html>
    

    jcarousel.connected-carousels.css

    /** Stage container **/
    
    .connected-carousels .stage {
        width: 620px;
        margin: 20px auto;
        position: relative;
    }
    
    .connected-carousels .photo-credits {
        position: absolute;
        right: 15px;
        bottom: 0;
        font-size: 13px;
        color: #fff;
        text-shadow: 0 0 1px rgba(0, 0, 0, 0.85);
        opacity: .66;
    }
    
    .connected-carousels .photo-credits a {
        color: #fff;
    }
    
    /** Navigation container **/
    
    .connected-carousels .navigation {
        width: 260px;
        margin: 20px auto;
        position: relative;
    }
    
    /** Shared carousel styles **/
    
    .connected-carousels .carousel {
        overflow: hidden;
        position: relative;
    }
    
    .connected-carousels .carousel ul {
        width: 10000em;
        position: relative;
        list-style: none;
        margin: 0;
        padding: 0;
    }
    
    .connected-carousels .carousel li {
        float: left;
    }
    
    /** Stage carousel specific styles **/
    
    .connected-carousels .carousel-stage {
        height: 400px;
        border: 10px solid #fff;
        -webkit-border-radius: 5px;
           -moz-border-radius: 5px;
                border-radius: 5px;
        -webkit-box-shadow: 0 0 2px #999;
           -moz-box-shadow: 0 0 2px #999;
                box-shadow: 0 0 2px #999;
    }
    
    .connected-carousels .carousel-stage1 {
        height: 400px;
        border: 10px solid #fff;
        -webkit-border-radius: 5px;
           -moz-border-radius: 5px;
                border-radius: 5px;
        -webkit-box-shadow: 0 0 2px #999;
           -moz-box-shadow: 0 0 2px #999;
                box-shadow: 0 0 2px #999;
    }
    
    /** Navigation carousel specific styles **/
    
        .connected-carousels .carousel-navigation {
            height: 60px;
            width: 240px;
            background: #fff;
            border: 10px solid #fff;
            -webkit-border-radius: 5px;
               -moz-border-radius: 5px;
                    border-radius: 5px;
            -webkit-box-shadow: 0 0 2px #999;
               -moz-box-shadow: 0 0 2px #999;
                    box-shadow: 0 0 2px #999;
        }
    
        .connected-carousels .carousel-navigation1 {
            height: 60px;
            width: 240px;
            background: #fff;
            border: 10px solid #fff;
            -webkit-border-radius: 5px;
               -moz-border-radius: 5px;
                    border-radius: 5px;
            -webkit-box-shadow: 0 0 2px #999;
               -moz-box-shadow: 0 0 2px #999;
                    box-shadow: 0 0 2px #999;
        }
    
        .connected-carousels .carousel-navigation li {
            cursor: pointer;
        }
    
        .connected-carousels .carousel-navigation1 li {
            cursor: pointer;
        }
    
        .connected-carousels .carousel-navigation li img {
            display: block;
            border: 5px solid #fff;
        }
    
        .connected-carousels .carousel-navigation1 li img {
            display: block;
            border: 5px solid #fff;
        }
    
        .connected-carousels .carousel-navigation li.active img {
            border-color: #ccc;
        }
    
        .connected-carousels .carousel-navigation1 li.active img {
            border-color: #ccc;
        }
    
        /** Stage carousel controls **/
    
        .connected-carousels .prev-stage,
        .connected-carousels .next-stage {
            display: block;
            position: absolute;
            top: 0;
            width: 305px;
            height: 410px;
            color: #fff;
        }
    
        .connected-carousels .prev-stage {
            left: 0;
        }
    
        .connected-carousels .next-stage {
            right: 0;
        }
    
        .connected-carousels .prev-stage.inactive,
        .connected-carousels .next-stage.inactive {
            display: none;
        }
    
        .connected-carousels .prev-stage span,
        .connected-carousels .next-stage span {
            display: none;
            position: absolute;
            top: 50%;
            width: 30px;
            height: 30px;
            text-align: center;
            background: #4E443C;
            color: #fff;
            text-decoration: none;
            text-shadow: 0 0 1px #000;
            font: 24px/27px Arial, sans-serif;
            -webkit-border-radius: 30px;
               -moz-border-radius: 30px;
                    border-radius: 30px;
            -webkit-box-shadow: 0 0 2px #999;
               -moz-box-shadow: 0 0 2px #999;
                    box-shadow: 0 0 2px #999;
        }
    
        .connected-carousels .prev-stage span {
            left: 20px;
        }
    
        .connected-carousels .next-stage span {
            right: 20px;
        }
    
        .connected-carousels .prev-stage:hover span,
        .connected-carousels .next-stage:hover span {
            display: block;
        }
    
        /** Navigation carousel controls **/
    
        .connected-carousels .prev-navigation,
        .connected-carousels .next-navigation {
            display: block;
            position: absolute;
            width: 30px;
            height: 30px;
            background: #4E443C;
            color: #fff;
            text-decoration: none;
            text-shadow: 0 0 1px #000;
            font: 16px/29px Arial, sans-serif;
            -webkit-border-radius: 30px;
               -moz-border-radius: 30px;
                    border-radius: 30px;
            -webkit-box-shadow: 0 0 2px #999;
               -moz-box-shadow: 0 0 2px #999;
                    box-shadow: 0 0 2px #999;
        }
    
        .connected-carousels .prev-navigation {
            left: -15px;
            top: 22px;
            text-indent: 6px;
        }
    
        .connected-carousels .next-navigation {
            right: -15px;
            top: 22px;
            text-indent: 20px;
        }
    
        .connected-carousels .prev-navigation.inactive,
        .connected-carousels .next-navigation.inactive {
            opacity: .5;
            cursor: default;
        }
    

    jcarousel.connected-carousels.js

    (function($) {
        // This is the connector function.
        // It connects one item from the navigation carousel to one item from the
        // stage carousel.
        // The default behaviour is, to connect items with the same index from both
        // carousels. This might _not_ work with circular carousels!
        var connector = function(itemNavigation, carouselStage) {
            return carouselStage.jcarousel('items').eq(itemNavigation.index());
        };
    
        $(function() {
            // Setup the carousels. Adjust the options for both carousels here.
            var carouselStage      = $('.carousel-stage').jcarousel();
            var carouselNavigation = $('.carousel-navigation').jcarousel();
    
            var carouselStage1      = $('.carousel-stage1').jcarousel();
            var carouselNavigation1 = $('.carousel-navigation1').jcarousel();
    
            // We loop through the items of the navigation carousel and set it up
            // as a control for an item from the stage carousel.
            carouselNavigation.jcarousel('items').each(function() {
                var item = $(this);
    
                // This is where we actually connect to items.
                var target = connector(item, carouselStage);
    
                item
                    .on('jcarouselcontrol:active', function() {
                        carouselNavigation.jcarousel('scrollIntoView', this);
                        item.addClass('active');
                    })
                    .on('jcarouselcontrol:inactive', function() {
                        item.removeClass('active');
                    })
                    .jcarouselControl({
                        target: target,
                        carousel: carouselStage
                    });
            });
    
            carouselNavigation1.jcarousel('items').each(function() {
                var item = $(this);
    
                // This is where we actually connect to items.
                var target = connector(item, carouselStage1);
    
                item
                    .on('jcarouselcontrol:active', function() {
                        carouselNavigation1.jcarousel('scrollIntoView', this);
                        item.addClass('active');
                    })
                    .on('jcarouselcontrol:inactive', function() {
                        item.removeClass('active');
                    })
                    .jcarouselControl({
                        target: target,
                        carousel: carouselStage1
                    });
            });
    
    
            // Setup controls for the stage carousel
            $('.prev-stage')
                .on('jcarouselcontrol:inactive', function() {
                    $(this).addClass('inactive');
                })
                .on('jcarouselcontrol:active', function() {
                    $(this).removeClass('inactive');
                })
                .jcarouselControl({
                    target: '-=1'
                });
    
            $('.next-stage')
                .on('jcarouselcontrol:inactive', function() {
                    $(this).addClass('inactive');
                })
                .on('jcarouselcontrol:active', function() {
                    $(this).removeClass('inactive');
                })
                .jcarouselControl({
                    target: '+=1'
                });
    
            // Setup controls for the navigation carousel
            $('.prev-navigation')
                .on('jcarouselcontrol:inactive', function() {
                    $(this).addClass('inactive');
                })
                .on('jcarouselcontrol:active', function() {
                    $(this).removeClass('inactive');
                })
                .jcarouselControl({
                    target: '-=1'
                });
    
            $('.next-navigation')
                .on('jcarouselcontrol:inactive', function() {
                    $(this).addClass('inactive');
                })
                .on('jcarouselcontrol:active', function() {
                    $(this).removeClass('inactive');
                })
                .jcarouselControl({
                    target: '+=1'
                });
        });
    })(jQuery);