Simple jQuery experiment - automatically shortening a long list

Earlier today I was looking at some HTML that was generated by ColdFusion. The HTML was simply a list of months and years where content existed in the database. Because the database was a bit old, the list was quite long. I wondered if I could use jQuery to create an automatic shortening of the list as well as creating a way to expand the list based on some user interface. Here is what I came up with.

First, let's create a long list from ColdFusion:

<ul id="list"> <cfloop index="x" from="1" to="25"> <cfoutput> <li>Item #x#</li> </cfoutput> </cfloop> </ul>

And the result display is - as you expect - quite large:

Ok, so next I loaded up jQuery and added a document.ready block:

<script type="text/javascript" src=""></script> <script> $(document).ready(function() {


I began by selecting my UL:

//get the item var item = $("#list");

Next I got the kids and checked to see if there were more than 10:

//get the children var kids = item.children();

if(kids.length > 10) {

At this point we need to do 3 things. First, hide kids 11 through - whatever. Secondly add a link to let the user see the rest of the list. Finally - listen for a click on that link so we can actually show the items. Here is the first block:

for(var i=10; i<kids.length; i++) { $(kids[i]).hide(); }

I could do that on one line, but I don't really see much benefit in that. I could also write this other ways. jQuery has a nice each() function that will iterate over stuff. But since I only want to go from 11-N, this seemed better to me.

item.append("<a href='' class='showMoreLink'>Show More</a>");

This - obviously - adds the link. Note the use of append. This will actually put the text in the same 'tab' as the rest of the list. I could have used after() but I kinda like how 'Show More' lined up.

$(".showMoreLink", item).click(function(e) { item.children().show() $(this).hide(); e.preventDefault(); });

And that is the final block. Note the use of item within the jQuery selector. This means that if I repeated this code multiple times then the event listener will only respond to the one of this particular list. I end up showing all the children which is a bit wasteful, but that syntax was too easy to pass up. I then hide the link. That means the list can be opened, but not closed. That seemed ok to me as I can't imagine wanting to toggle it back and forth - but I may come back to that. Finally I prevent the default click action. So how does it work? Here is the display:

And it works! You can click the big ole Demo button below to see. It also works fine with other types of parent/child relationships:

<div id="list2"> <cfloop index="x" from="1" to="25"> <cfoutput> <div>Item #x#</div> </cfoutput> </cfloop> </div>

But it did not work well with tables at all. Again, I'll come back to it. So - this works - but is pretty simplistic. In the next blog entry I'll convert this to a plugin so I can simply do: $("#list").autoShorten() while allowing for optional values for the number of items to show and what to use for the link text.

<script type="text/javascript" src=""></script> <script> $(document).ready(function() {

//get the item
var item = $("#list");

//get the children
var kids = item.children();
if(kids.length &gt; 10) {

    for(var i=10; i&lt;kids.length; i++) {

    item.append("&lt;a href='' class='showMoreLink'&gt;Show More&lt;/a&gt;");

    $(".showMoreLink", item).click(function(e) {


}) </script>

<ul id="list"> <cfloop index="x" from="1" to="25"> <cfoutput> <li>Item #x#</li> </cfoutput> </cfloop> </ul>

Like This?

If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can also subscribe to the email feed to get notified of new posts.