Question

I have a list element containing a number of between 20-30 events. I only want to show 5 of those, and have a «More» link I can click to watch the the next five. It doesn't matter if the five next events are appended.

Can't find a jQuery script that actually does this, or am I just blind? I don't want to use carousel plugins or anything like that.

Was it helpful?

Solution

Well, fortunately for us programmers, who write code for food and fame, not every imaginable piece of functionality has been written yet as a plugin :)

But this is quite easy:

var from = 0, step = 5;

function showNext(list) {
  list
    .find('li').hide().end()
    .find('li:lt(' + (from + step) + '):not(li:lt(' + from + '))')
      .show();
  from += step;
}

function showPrevious(list) {
  from -= step;
  list
    .find('li').hide().end()
    .find('li:lt(' + from + '):not(li:lt(' + (from - step) + '))')
      .show();
}

// show initial set
showNext($('ul'));

// clicking on the 'more' link:
$('#more').click(function(e) {
  e.preventDefault();
  showNext($('ul'));
});

Of course this is better extracted into plugin-like function, but I'm gonna leave that as an exercise for a reader ;)

OTHER TIPS

<html>
<head><title>Test</title></head>
<body>
<ul class="more">
  <li>one</li>
  <li>two</li>
  <li>three</li>
  <li>four</li>
  <li>five</li>
  <li>six</li>
  <li>seven</li>
  <li>eight</li>
  <li>nine</li>
  <li>ten</li>
</ul>
<script type="text/javascript" src="jquery-1.3.1.js"></script>
<script type="text/javascript">
$(function() {
  $("ul.more").each(function() {
    $("li:gt(4)", this).hide(); /* :gt() is zero-indexed */
    $("li:nth-child(5)", this).after("<li class='more'><a href='#'>More...</a></li>"); /* :nth-child() is one-indexed */
  });
  $("li.more a").live("click", function() {
    var li = $(this).parents("li:first");
    li.parent().children().show();
    li.remove();
    return false;
  });
});
</script>
</script
</body>
</html>

Basically what this does:

  1. Hides the 6th and subsequent list items;
  2. Inserts a list item after the 5th saying "More...";
  3. Uses live events to add an event handler to the "More..." links so that when they are clicked they show all list items in that list and then remove themselves.

Edit: Fixed up a few little errors. The above is a fully working example now (just make sure the jquery link is correct).

You want to start off with each element in the list hidden (CSS: display: none). Then have your more link undernearth the list element.

$(document).ready(function()
{
    $("a#myMoreLink").click(function()
    {
        var items = $("ul#myList > li:hidden");

        if(items.length > 0)
            items.slice(0, 5).show();
        else
            $(this).html("No more");

        return false;
    });

    $("a#myMoreLink").click();
});

With HTML:

<ul id="myList">
    <li style="display: none"></li>
    <li style="display: none"></li>
</ul>
<a href="http://" id="myMoreLink">More</a>

Something like that. $("a#myMoreLink").click(); is called to show the initial 5 items upon loading the page.

This works but sure you will have to tweak it some what :)

html:

<div style="width:200px;border:3px groove blue;">
   <ul id="list">
    <li>Thai</li>
    <li>Turkish</li>
    <li>Portuguese</li>
    <li>American English</li>
    <li>Arabic</li>
    <li>Canadian French</li>
    <li>Chinese Simplified</li>
    <li>Chinese Traditional</li>
    <li>Czech</li>
    <li>Danish</li>
    <li>Dutch</li>
    <li>English</li>
    <li>Finnish</li>
    <li>French</li>
    <li>German</li>
    <li>Greek</li>
    <li>Hebrew</li>
    <li>Hungarian</li>
    <li>Italian</li>
    <li>Japanese</li>
    <li>Norweigan</li>
    <li>Polish</li>
    <li>Russian</li>
    <li>Spanish</li>
   </ul>    
   <a href="#" id="lnkMore">More</a>
</div>

javascript:

<script type="text/javascript">
    var len = 0;
    var curStart = 0;
    var count = 5;
    var items=new Array();
    function BackupList() {
        var lst = $("ul#list");
        len= $("ul#list li").length;
        if (len <= count)
            return;

        $("ul#list li").each(function() {
            items.push($(this));
            $(this).remove();
        });

        var html="";
        for (curStart; curStart < count && curStart < len; curStart++) {
            html += "<li>" + $(items[curStart]).html() + "</li>";
        }
        $(html).appendTo($(lst));
    }

    function ShowMore() {
        if (curStart >= len) {
            curStart = 0;
        }

        $("ul#list li").each(function() {
            $(this).remove();
        });

        var l = curStart;
        var html = "";
        for (curStart; curStart < (l + count) && curStart < len; curStart++) {
            html += "<li>" + items[curStart].html() + "</li>";
        }
        $(html).appendTo($("ul#list"));
    }
</script>

Wire jquery for event:

<script type="text/javascript">
    $(document).ready(function() {
        BackupList();
        $("a#lnkMore").click(function() { ShowMore(); });
    });
</script>    

I wrote a hideMaxListItems plugin that may be what you were looking for. You can set the maximum number of list items, animation speed for the slide animation, and expand/collapse button HTML. The slide animation is done sequentially per list item, to give a smooth animation.

http://www.joshuawinn.com/maximum-list-items-jquery-hide-after-x-number-bullets/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top