If this is your first time visiting, be sure to subscribe to my RSS Feed, and don't forget to follow me on Twitter! If it isn't your first time here and you're sick and tired of this message, get rid of it.

May 29
2009

Filed Away: Javascript, Web

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.


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: , , , , ,

12 comments so far on this post:

  1. Chase Swindler |

    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.

  2. Dan B. Lee |

    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.

  3. Nick |

    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

  4. Brian Cray |

    Nice post David! Glad to see you’re tackling this issue!

  5. Oscar Godson |

    @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 :)

  6. Patrick |

    Why not use css for this? For example see: http://www.pastebin.ca/1456506

  7. cache $$ click(); |

    What is the purpose of the non standard attribute?? Looking at the code it does nothing.

  8. David Link |

    @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.

  9. David Link |

    @cache:
    What attribute are you referring to?

  10. Doug Greathouse |

    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.

  11. ddools |

    i love it. short sweet & most importantly it works!

  12. Jonathan |

    great work man… very helpful… thanks

A penny for your thoughts?