jQuery vertical news ticker, slide one element at a time

JonTEC
JonTEC used Ask the Experts™
on
I am attempting to modify a jQuery vertical news ticker for a customer and cannot see a simple way to do it in the code.  

The following webpage is my testing area for this:
http://www.tecuity.com/sosweb/

The "More Quick Links" section on the right hand side of the page scrolls its elements vertically in groups of three.  I need it to scroll one element at a time both automatically on the timer and manually when a user clicks on the up and down arrows.

I realize that the code implementing the animation is driven off of the number of displayed items and not the total number of items.  If anyone understands this better and can let me know if there is a fairly simple method to adjust the sliding interval to one at a time, I would appreciate it very much.  Or if anyone knows of a different code snippet I can use, that is an option.  Must be auto and manual though.  

Thanks.

The jquery function I am using is as follows:
(function($) {
    $.fn.extend({
        jsCarousel: function(options) {
            var settings = $.extend({
                scrollspeed: 1500,
                delay: 6000,
                itemstodisplay: 5,
                autoscroll: false,
                circular: true,
                masked: true,
                onthumbnailclick: null,
                orientation: 'v'
            }, options);
            return this.each(function() {
                var oclass = 'horizontal';
                if (settings.orientation == 'v')
                    oclass = 'vertical';
                var slidercontents = $(this).addClass('jscarousal-contents-' + oclass + '');
                var slider = $('<div/>').addClass('jscarousal-' + oclass + '').attr('id', slidercontents.attr('id'));
                var backbutton = $('<div/>').addClass('jscarousal-' + oclass + '-back');
                var forwardbutton = $('<div/>').addClass('jscarousal-' + oclass + '-forward');
                
                slidercontents.removeAttr('id');
                slidercontents.before(slider);
                slider.append(backbutton);
                slider.append(slidercontents);
                slider.append(forwardbutton);
                
                var total = $('> div', slidercontents).css('display', 'none').length;
                var index = 0;
                var start = 0;
                var current = $('<div/>');
                var noOfBlocks;
                var interval;
                var display = settings.itemstodisplay;
                var speed = settings.scrollspeed;
                var top;
                var left;
                var height;
                var containerHeight;
                var containerWidth;
                var direction = "forward";
                var scrolling = true;
                
                function initialize() {
                    index = -1;
                    noOfBlocks = parseInt(total / display);
                    if (total % display > 0) noOfBlocks++;
                    index = noOfBlocks - 1;
                    var startIndex = 0;
                    var endIndex = display;
                    var copy = false;
                    var allElements = $('> div', slidercontents);
                    $('> div', slidercontents).remove();
                    
                    if (settings.masked)
                        allElements.addClass('thumbnail-inactive').hover(function() { $(this).removeClass('thumbnail-inactive').addClass('thumbnail-active'); }, function() { $(this).removeClass('thumbnail-active').addClass('thumbnail-inactive'); })
                        
                    for (var i = 0; i < noOfBlocks; i++) {
                        if (total > display) {
                            startIndex = i * display;
                            endIndex = startIndex + display;
                            if (endIndex > total) {
                                startIndex -= (endIndex - total);
                                endIndex = startIndex + display;
                                copy = true;
                            }
                        }
                        else {
                            startIndex = 0;
                            endIndex = total;
                        }
                    
                        var wrapper = $('<div/>')
                    
                        allElements.slice(startIndex, endIndex).each(function(index, el) {
                            if (!copy)
                                wrapper.append(el);
                            else wrapper.append($(el).clone(true));
                        });
                        
                        wrapper.find("img").click(
                            function() {
                                if (settings.onthumbnailclick != null) {
                                    settings.onthumbnailclick($(this).attr('src'));
                                }
                            });
                            slidercontents.append(wrapper);
                    }
                    
                    if (settings.onthumbnailclick != null)
                        $('> div > div', slidercontents).css('cursor', 'pointer');
                    
                    $('> div', slidercontents).addClass('hidden');
                    $('> div > div', slidercontents).css('display', '');
                    
                    /*vertical*/
                    if (settings.orientation == 'v') {
                        top = $('> div:eq(' + index + ')', slidercontents).css('top');
                        if (top == 'auto') top = "0px";
                        containerHeight = slidercontents.height();
                        height = slidercontents.get(0).offsetHeight;
                        $('> div', slidercontents).css('top', '-' + containerHeight + 'px');
                        $('> div:eq(' + index + ')', slidercontents).stop(false, true).animate({ 'top': top }, speed, function() { scrolling = false; });
                    }
                    
                    /*horizontal*/
                    if (settings.orientation == 'h') {
                        left = $('> div:eq(' + index + ')', slidercontents).css('left');
                        containerWidth = slidercontents.width();
                        height = slidercontents.get(0).offsetHeight;
                        $('> div', slidercontents).css('left', '-' + containerWidth + 'px');
                        $('> div:eq(' + index + ')', slidercontents).stop(false, true).animate({ left: 0 }, speed, function() { scrolling = false; });
                    }
                    
                    $('> div:eq(' + index + ')', slidercontents).addClass('visible').removeClass('hidden');
                    
                    slider.mouseenter(function() { if (settings.autoscroll) stopAnimate(); }).mouseleave(function() { if (settings.autoscroll) animate(); });
                    
                    if (settings.autoscroll)
                        animate();
                        
                    forwardbutton.click(function() {
                        if (!scrolling) {
                            direction = "forward";
                            if (settings.circular)
                                if (index <= 0) index = noOfBlocks;
                            showThumbs();
                        }
                    });
                    
                    backbutton.click(function() {
                        if (!scrolling) {
                            direction = "backward";
                            if (settings.circular)
                                if (index >= noOfBlocks - 1) index = -1;
                            showThumbs();
                        }
                    });
                }
                
                initialize();
                
                function stopAnimate() {
                    scrolling = false;
                    clearTimeout(interval);
                    slider.children().clearQueue();
                    slider.children().stop(false, true);
                }
                
                function animate() {
                    clearTimeout(interval);
                    if (settings.autoscroll)
                        interval = setTimeout(changeSlide, settings.delay);
                }
                
                function changeSlide() {
                    if (direction == "forward") {
                        if (index <= 0) index = noOfBlocks;
                    } else {
                        if (index >= noOfBlocks - 1) { index = -1; }
                    }
                    showThumbs();
                    interval = setTimeout(changeSlide, settings.delay);
                }
                
                function getDimensions(value) {
                    return value + 'px';
                }
                
                function showThumbs() {
                    scrolling = true;
                    var current = $('.visible', slidercontents);
                    var scrollSpeed = speed;
                
                    if (direction == "forward") {
                        index--;
                        if (index >= 0) {
                            if (settings.orientation == 'v') {
                                $('>div:eq(' + index + ')', slidercontents).css('top', getDimensions(containerHeight)).removeClass('hidden').addClass('visible').stop(false, true).animate({ 'top': top }, scrollSpeed, function() { scrolling = false; });
                                current.stop(false, true).animate({ 'top': '-=' + getDimensions(containerHeight) }, scrollSpeed, function() {
                                    $(this).removeClass('visible').addClass('hidden');
                                    $(this).css('top', top);
                                    scrolling = false;
                                });
                            }
                            else {
                                $('>div:eq(' + index + ')', slidercontents).css('left', getDimensions(containerWidth)).removeClass('hidden').addClass('visible').stop(false, true).animate({ 'left': '-=' + getDimensions(containerWidth) }, scrollSpeed, function() { scrolling = false; });
                                current.stop(false, true).animate({ 'left': '-=' + getDimensions(containerWidth) }, scrollSpeed, function() {
                                    $(this).removeClass('visible').addClass('hidden');
                                    $(this).css('left', left);
                                    scrolling = false;
                                });
                            }
                        }
                        else 
                            index = 0;
                    }
                    else if (direction == "backward") {
                        index++;
                        if (index < noOfBlocks) {
                            if (settings.orientation == 'v') {
                                $('>div:eq(' + index + ')', slidercontents).removeClass('hidden').addClass('visible').css({
                                    'top': getDimensions(-containerHeight)
                                }).stop(false, true).animate({ 'top': top }, scrollSpeed, function() { scrolling = false; });
                        
                                current.stop(false, true).animate({ 'top': '+=' + getDimensions(containerHeight) }, scrollSpeed,
                        
                            function() {
                                $(this).removeClass('visible').addClass('hidden');
                                $(this).css('top', getDimensions(-containerHeight));
                                scrolling = false;
                            });
                        }
                    else {
                        $('>div:eq(' + index + ')', slidercontents).removeClass('hidden').addClass('visible').css({
                            'left': getDimensions(-containerWidth)
                        }).stop(false, true).animate({ 'left': '+=' + getDimensions(containerWidth) }, scrollSpeed, function() { scrolling = false; });
                
                        current.stop(false, true).animate({ 'left': '+=' + getDimensions(containerWidth) }, scrollSpeed,
                
                            function() {
                                $(this).removeClass('visible').addClass('hidden');
                                $(this).css('left', getDimensions(-containerWidth));
                                scrolling = false;
                        });
                        }
                        } else index = noOfBlocks - 1;
                    }
                }
            });
        }
    });
})(jQuery); 

Open in new window


The html is as follows:
<script type="text/javascript">
    $(document).ready(function() {
        $('#carouselv').jsCarousel({ 
            autoscroll: true, 
            itemstodisplay: 3,
            scrollspeed: 1500,
            delay: 6000
        });
    });      
</script>

<style type="text/css">
    #qlink a
    {
	    font-weight:bold;
    }
    
    .ql-img
    {
	    padding-right: 10px;
	    float: left;
	    width: 50px;
        height: 50px;		
    }

    .ql-innertext
    {
        padding:10px 0;
	    border-bottom: 1px solid #517da6;
	    min-height:112px;
    }
        
    .jscarousal-vertical
    {
        margin: 0;
        padding: 0;
        position: relative;
        overflow: hidden;
    }
    .jscarousal-vertical-back, .jscarousal-vertical-forward
    {
        width: 100%;
        height: 14px;
        color: black;
        position: relative;
        cursor: pointer;
        z-index:100;
    }
    .jscarousal-vertical-back
    {
        background-image: url(images/qlink_up.jpg);
        background-repeat: no-repeat;
        background-position: bottom;
    }
    .jscarousal-vertical-forward
    {
        background-image: url(images/qlink_down.jpg);
        background-repeat: no-repeat;
        background-position: top;
    }
    .jscarousal-contents-vertical
    {
        overflow: hidden;
        height: 410px;
    }
    .jscarousal-contents-vertical > div
    {
        position: absolute;
        top: 22px;
        width: 100%;
        height: 820px;
        overflow: hidden;
    }
    .hidden
    {
        display: none;
    }
    .visible
    {
        display: block;
    }     
</style>

<h3 class="toplong">More Quick Links</h3>
<div id="qlink">
    <div id="vWrapper">
        <div id="carouselv">

            /*Element 1*/
            <div class="ql-innertext">
                <img  />
                <span></span>
            </div>

            /*Element 2*/
            <div class="ql-innertext">
                <img  />
                <span></span>
            </div>

            /*Element 3*/
            <div class="ql-innertext">
                <img  />
                <span></span>
            </div>

            /*Element 4*/
            <div class="ql-innertext">
                <img  />
                <span></span>
            </div>

            /*Element 5*/
            <div class="ql-innertext">
                <img  />
                <span></span>
            </div>

        </div>
    </div>
</div>

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Jon NormanInformation Systems Manager
Top Expert 2012

Commented:
have you tried bxSlider - http://bxslider.com

this has options to make it a vertical slideshow - http://bxslider.com/examples/vertical-slideshow
it loops infinitely by default, which I think would be better for you
you can show multiple slides at the same time - http://bxslider.com/examples/display-move-multiple-slides-once-example-one (you want to display 3 and move only one)
you can turn off their controls and create your own- http://bxslider.com/examples/display-move-multiple-slides-once-example-one
Jon NormanInformation Systems Manager
Top Expert 2012

Commented:
I think that the code you would need is:
$(document).ready(function(){
  var slider=$("#qlink-carousel").bxSlider({
    auto:true,
    mode: 'vertical',
    displaySlideQty: 3,
    moveSlideQty: 1,
    speed:1500,
    controls: false
  });
  $('.go-prev').click(function(){
    slider.goToPreviousSlide();
    return false;
  });
  $('#go-next').click(function(){
    slider.goToNextSlide();
    return false;
  });
});

Open in new window

You would also need to add the two divs for the up and down:
<div class="go-prev" style="display: block;" disabled="false"></div>
<div class="go-next" style="display: block;" disabled="false"></div>
<style>
.go-prev {
    background: url("../images/qlink_up.gif") no-repeat scroll 0 0 transparent;
    cursor: pointer;
    height: 14px;
    left: 0;
    position: absolute;
    top: 5px;
    width: 240px;
}
.go-next {
    background: url("../images/qlink_down.gif") no-repeat scroll 0 0 transparent;
    bottom: 5px;
    cursor: pointer;
    height: 14px;
    left: 0;
    position: absolute;
    width: 240px;
}
</style>

Open in new window


...edited above to add speed
Information Systems Manager
Top Expert 2012
Commented:
ahhh I can see you have fixed it using jCarousel, have you tried - wrap:"circular" ?

Author

Commented:
Thank you JonNorman for the responses.  Your response with the jquery code pieces helps me see how to implement this so much better.  I did go with the jCarousel library and have found it to be very easy to use.  Thanks for the "circular" suggestion.  I have implemented that as well as you can see on my test site.

For those looking for the jCarousel library, find it here at github: http://github.com/jsor/jcarousel

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial