Multiple Slider Navigation Selects

Hi all,

I am really stuck, spent all day tinkering with this to try to get it to work and not had much luck. Am trying to get multiple sliders to work on one page. I have manage to get them to auto slide together, but the little nav buttons below the images don’t cycle on the first two sliders, it only really works on the last, and even then it won’t remove the ‘selected’ on the anchor:

http://dev2.pelli.co.uk/multiple-coda-sliders/codaslider.html

I have renamed the containing div for each slider to: #slider, #slider_2 and #slider_3 and changed the corresponding code in the coda-slider.js file:

http://dev2.pelli.co.uk/multiple-coda-sliders/coda-slider.js

I have tried to manipulate the following code to try to get the selected buttons to activate for each but with no joy:


$('#slider .navigation').find('a').click(selectNav);
	
// handle nav selection
    function selectNav() {
        $(this)
            .parents('ul#nav1:first')
                .find('a')
                    .removeClass('selected')
                .end()
            .end()
            .addClass('selected');
    }

Please can anyone help? Not sure what else to try!

Many thanks

There were two issues here.

First: Everything happened in a single function.

Here’s what your coda-slider.js file looked like:


$(document).ready(function () {
    // create the first slider
    // create the second slider
    // create the third slider
});

The problem is, each “create the X slider” part relied on a function named “selectNav”. So each time you created that function, you actually overwrote the earlier one (that’s why the navigation was [kind of; see below] working on the last slider).

The drop-dead simplest way to fix this is to simply separate each bit into its own function:


$(document).ready(function () {
    // create the first slider
});
$(document).ready(function () {
    // create the second slider
});
$(document).ready(function () {
    // create the third slider
});

…But a much, much better way to go about it would be to abstract all of the “create a slider” code into a single function, and then call it three times:


function createSlider(/* whatever variables you need */) {
    // create the slider
}

$(document).ready(function () {
    createSlider(/* data for the first slider */);
    createSlider(/* data for the second slider */);
    createSlider(/* data for the third slider */);
});

Second: The “selected” class was never actually being removed.

Once you make the above change, you’ll notice that the navigation still doesn’t quite work. This is because of this part in your code:


function selectNav() {
    $(this)
        .parents('ul#nav1:first') // <-- this line right here
            .find('a')
                .removeClass('selected')
            .end()
        .end()
        .addClass('selected');
}

I’m not sure what you were trying to do; there is no element on the page with an ID of “nav1” (and even if there was, you wouldn’t need to specify an element or :first). Maybe your actual HTML is different from the example you gave, but this worked for me:


function selectNav() {
    $(this)
        .parents('.navigation')
            .find('a')
                .removeClass('selected')
            .end()
        .end()
        .addClass('selected');
}

Third: Profit?

There’s still an issue (in Chrome, at least) where the second slider doesn’t start until after the other two. Not really sure what was causing that… Maybe it was even intentional!

Thank so much, I have used the first example you mentioned but the much much better version, I can’t work out how to configure that, where and how do I add the remaining data for each!?

What do you mean by remaining data?

I messed around with the coda-slider.js file some more, and it looks like all you would need to pass to that function is the id of the slider. So something like this:


function createSlider(id) {
    var $start = $('#' + id),
        $container = $start.find('.scrollContainer'),
        $panels = $container.children('div'),
        /* etc., etc. */
}

Sorry I have been away all weekend… thanks very much for all your help, I’m just not sure how to configure the remainder of the code. Where you set the variable $start… how do I replace all the instances of #sldier/#slider_2 and #slider_3 with that variable?

This is the new Coda Slider file I created, but doesn’t work. (Sorry, am still trying to learn jQuery)


function createSlider(id) {
    var $start = $('#' + id),
        $container = $start.find('.scrollContainer'),
        $panels = $container.children('div'),

    var horizontal = true;

    if (horizontal) {
        $panels.css({
            'float' : 'left',
            'position' : 'relative' // IE fix to ensure overflow is hidden
        });
        $container.css('width', $panels[0].offsetWidth * $panels.length);
    }

    var $scroll = $(start + '.scroll').css('overflow', 'hidden');

    var cycleTimer = setInterval(function () {
 	  $scroll.trigger('next');
	}, 6000);

	$(start '.navigation').find('a').click(selectNav);
	
    // handle nav selection
    function selectNav() {
        $(this)
            .parents('ul:first')
                .find('a')
                    .removeClass('selected')
                .end()
            .end()
            .addClass('selected');
    }

    // go find the navigation link that has this target and select the nav
    function trigger(data) {
        var el = $(start '.navigation').find('a[href$="' + data.id + '"]').get(0);
        selectNav.call(el);
    }

    if (window.location.hash) {
        trigger({ id : window.location.hash.substr(1) });
    } else {
        $('ul.navigation a:first').click();
    }

    // offset is used to move to *exactly* the right place, since I'm using
    // padding on my example, I need to subtract the amount of padding to
    // the offset.  Try removing this to get a good idea of the effect
    var offset = parseInt((horizontal ?
        $container.css('paddingTop') :
        $container.css('paddingLeft'))
        || 0) * -1;


    var scrollOptions = {
        target: $scroll, // the element that has the overflow

        // can be a selector which will be relative to the target
        items: $panels,

        navigation: '.navigation a',

        // selectors are NOT relative to document, i.e. make sure they're unique
        prev: 'img.left',
        next: 'img.right',

        // allow the scroll effect to run both directions
        axis: 'xy',

        onAfter: trigger, // our final callback

        offset: offset,

        // duration of the sliding effect
        duration: 300,

        // easing - can be used with the easing plugin:
        // http://gsgd.co.uk/sandbox/jquery/easing/
        easing: 'swing'
    };

    // apply serialScroll to the slider - we chose this plugin because it
    // supports// the indexed next and previous scroll along with hooking
    // in to our navigation.
    $(start).serialScroll(scrollOptions);

    // now apply localScroll to hook any other arbitrary links to trigger
    // the effect
    $.localScroll(scrollOptions);

    // finally, if the URL has a hash, move the slider in to position,
    // setting the duration to 1 because I don't want it to scroll in the
    // very first page load.  We don't always need this, but it ensures
    // the positioning is absolutely spot on when the pages loads.
    scrollOptions.duration = 1;
    $.localScroll.hash(scrollOptions);
}