Splitcol: Split a list in two with jQuery
The Problem
Recently, I was giving a bit of help to a friend of mine with a site redesign he was implementing. He came to me with a problem he was having with the dropdown navigation. The design required the dropdown to have two columns of links, but the back-end was spitting them out in a single list.
My first thought was just to float the list items next to each other, but since some list items would be two lines long, it caused some nasty vertical spacing issues. The solution was to turn the one list into two.
Before you continue reading, check out the demo so you can see what it actually does.
How to Fix It
Step 1: The Library
If you don’t already have jQuery running on the site, download it here and drop it on your server. Or if you’d like you can use the version from jQuery’s Google Code project (Which is what we’ll be doing for this demo).
To include jQuery, insert the following code somewhere between the <head> tags of your document:
<script type="text/javascript" charset="utf-8" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"></script>
or if you’re using a version from your own server:
<script type="text/javascript" charset="utf-8" src="http://[Your Domain]/jquery-1.3.2.min.js"></script>
Step 2a: The Markup
Since we don’t necessarily want to split every list on the site, we’re going to use classes as a special marker for which lists we’ll be splitting. We’ll use the class “splitcol”.
Example:
<ul class="splitcol">
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
</ul>
Step 2b: The Styling
This step is optional. If we’d like the two lists to appear next to one another, we’re going to have to use a bit of CSS. Add the following to your stylesheet:
.splitcol {
float: left;
}
Step 3: The Script
Finally, we’ll need to add the keystone. Either in the <head> of the document, or in a separate external JS file, drop in the following code:
$(document).ready(function() {
$('.splitcol').each(function() {
if($(this).is("ol")) { var ordered = true; }
var colsize = Math.round($(this).find("li").size() / 2);
$(this).find("li").each(function(i) {
if (i>=colsize) {
$(this).addClass('right_col');
}
});
if(ordered) {
$(this).find('.right_col').insertAfter(this).wrapAll("<ol class='splitcol' start='" + (colsize+1) + "'></ol>").removeClass("right_col");
} else {
$(this).find('.right_col').insertAfter(this).wrapAll("<ul class='splitcol'></ul>").removeClass("right_col");
}
});
});
Problem Solved
And that’s it! For an explanation of the code, check out the next page.
Warning: file_get_contents() [function.file-get-contents]: URL file-access is disabled in the server configuration in /homepages/20/d210624833/htdocs/upsidestudio/wp-content/themes/upsidestudio/single.php on line 54
Warning: file_get_contents(http://tinyurl.com/api-create.php?url=http%3A%2F%2Fupsidestudio.com%2Fweb%2Fsplitcol%2F) [function.file-get-contents]: failed to open stream: no suitable wrapper could be found in /homepages/20/d210624833/htdocs/upsidestudio/wp-content/themes/upsidestudio/single.php on line 54
Tweet This
Tagged: Chase Swindler, Code, David Link, Javascript, jQuery, Lists











Chase Swindler | May 29th, 2009 at 10:04 am
I, sir, am the man who you helped with this glorious concoction of code. And I must say without it, that navigation would’ve been impossible.
Dan B. Lee | May 29th, 2009 at 10:33 am
This would be such a great tutorial if I could rely on everyone to have JS enbled! I WILL find a place to use this, though. I can guarantee it. Thanks a heap.
Nick | May 29th, 2009 at 10:56 am
Nice tutorial, I really liked it. I one lined it if you’d like to take a look. Efficiency should be approximately the same, but I haven’t profiled it or anything. Link - http://www.pastebin.ca/1439713
Brian Cray | June 10th, 2009 at 1:00 pm
Nice post David! Glad to see you’re tackling this issue!
Oscar Godson | June 11th, 2009 at 1:10 am
@Dan B. Lee
99% of people have it enabled, and the 1% are search engines really. The people who turn it off KNOW that they are going to break numerous, if not most, sites. Personally, I think to spend any amount of time trying to make a JS enabled site work without it is just for shits and giggles more than for true accessibility. As long as the stuff you need is indexable by search engines, which this IS, then it really does not matter.
At the author, nice job! I will be using this. Nice. I’m going to see if I can port this into making columns by counting words
Patrick | June 11th, 2009 at 6:37 am
Why not use css for this? For example see: http://www.pastebin.ca/1456506
cache $$ click(); | June 23rd, 2009 at 8:32 pm
What is the purpose of the non standard attribute?? Looking at the code it does nothing.
David Link | June 23rd, 2009 at 9:57 pm
@Patrick:
That would certainly work if we had control over the li classes being outputted by the CMS. In this particular case, a CSS-only solution wasn’t enough.
David Link | June 23rd, 2009 at 9:59 pm
@cache:
What attribute are you referring to?
Doug Greathouse | July 18th, 2009 at 10:48 am
Nice. I know I will be able to use this in the future. I have bookmarked this page so that I can find it easily.
ddools | June 27th, 2011 at 6:49 am
i love it. short sweet & most importantly it works!
Jonathan | August 22nd, 2011 at 7:16 am
great work man… very helpful… thanks