Splitcol: Split a list in two with jQuery
Code Review
Here, again, is the script in its entirety for you to reference:
$(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");
}
});
});
It’s all pretty simple, but for those of you who may not be familiar with jQuery or JavaScript in general, I’ll go through the script line-by-line. Let’s start with the beginning:
$(document).ready(function() {
The first line simply checks to make sure the document is loaded, and when it is, fires the function described below.
$('.splitcol').each(function() {
This tells jQuery to check for any element with the class name splitcol associated with it. Then, for each element it finds, it runs the nested function.
if($(this).is("ol")) { var ordered = true; }
This is just a quick check we make to find out if we’re dealing with an ordered or unordered list. jQuery tests to see if the selected element is an <ol>. If so, it creates a variable called ordered and sets it equal to true.
var colsize = Math.round($(this).find("li").size() / 2);
This line creates a variable called colsize and gives it a value which will determine how many list items to place in each of our newly split lists. It does this by finding how many <li> elements are within the targeted element, then dividing by two. The Math.round() method takes the result and rounds it up, in case we ended up with a fraction.
$(this).find("li").each(function(i) {
if (i>=colsize) {
$(this).addClass('right_col');
}
});
This is starts similarly to one of our previous function calls. It tells jQuery to check for any <li> elements within the selected list. Then, for each <li>, it runs the nested function and passes in the variable i. For the first loop of the function, i is equal to zero. Each time the function is run, i is incremented by one.
The function itself is just a simple conditional loop. It checks to see if i is greater than or equal to colsize. If it is, it adds a class right_col to the current <li>. This will help us distinguish later which list items are to be placed in the new list.
if(ordered) {
$(this).find('.right_col').insertAfter(this).wrapAll("<ol class='splitcol' start='" + (colsize+1) + "'></ol>").removeClass("right_col");
}
The beginning of this conditional loop first checks to see if the current list is ordered. If it is, jQuery finds elements (within the current list) with the class right_col which we had assigned previously. It then places those items outside of the selected <ol>. Now that the <li> elements are not part of the original list, we wrap them in their own new <ol>. We give our new list a class of splitcol for styling purposes, and we set the start attribute equal to colsize + 1 so that our list numbering matches properly. This will not validate with a Strict DOCTYPE. So if that bothers you, feel free to take it out. Then we remove the class right_col from the list items since we won’t be needing it anymore.
else {
$(this).find('.right_col').insertAfter(this).wrapAll("<ul class='splitcol'></ul>").removeClass("right_col");
}
Finally, this section deals with the unordered lists in essentially the same way as the ordered lists.
});
Those little funky guys are just closing out our open functions.











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.