ColdFusion Quickie: Splitting data into columns

This post is more than 2 years old.

This is something I've done many times in the past, but I thought I'd whip up a quick example and share it. Imagine you have a set of data you need to display in columns. With a table it's trivial. You loop and simply begin a new TR every two cells. But what if you aren't using tables? Imagine a CSS based layout with two columns side by side. The contents of the left column need to be every other item, starting with the first one. The contents of the right column need to be every other item, starting with the second one. Here is a quick snippet of code that demonstrates this.

<cfset data = [1,2,3,4,5,6,7,8,9]>

<cfset col1 = []> <cfset col2 = []>

<cfloop index="x" from="1" to="#arrayLen(data)#"> <cfset item = data[x]> <cfif x mod 2 is 1> <cfset arrayAppend(col1, item)> <cfelse> <cfset arrayAppend(col2, item)> </cfif> </cfloop>

I create an initial set of data with 9 items. I then create two arrays - one for each column. Finally I loop over the data set and if odd, add it to column 1, and if even, add it to column two. So to render this I just output my HTML/CSS and loop over each column.

<style> #left { float: left; width: 200px; } #right { float: left; width: 200px; } </style>

<div id="left"> <b>col1</b><br/> <cfloop index="i" array="#col1#"> <cfoutput> #i#<br/> </cfoutput> </cfloop> </div> <div id="right"> <b>col2</b><br/> <cfloop index="i" array="#col2#"> <cfoutput> #i#<br/> </cfoutput> </cfloop> </div>

Here is how it looks - fancy, eh?

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Ed Tabara posted on 4/23/2011 at 7:30 PM

one of other ways to do teh same thing would be so:

<cfset data = [1,2,3,4,5,6,7,8,9]>
<style>
#left {
float: left;
width: 200px;
}
#right {
float: left;
width: 200px;
}
</style>

<div id="left">
<b>col1</b><br/>
<cfloop index="x" from="1" to="#arrayLen(data)#">
<cfif x mod 2 eq 1>
<cfoutput>
#data[x]#<br/>
</cfoutput>
</cfif>
</cfloop>
</div>
<div id="right">
<b>col2</b><br/>
<cfloop index="x" from="1" to="#arrayLen(data)#">
<cfif x mod 2 eq 0>
<cfoutput>
#data[x]#<br/>
</cfoutput>
</cfif>
</cfloop>
</div>

Comment 2 by spills posted on 4/23/2011 at 8:14 PM

Don't forget about the handy dandy "step" option in cfloops.

<cfset data = [1,2,3,4,5,6,7,8,9]>
<style>
#left {
float: left;
width: 200px;
}
#right {
float: left;
width: 200px;
}
</style>

<div id="left">
<b>col1</b><br/>
<cfloop index="x" from="1" to="#arrayLen(data)#" step="2">
<cfoutput>
#data[x]#<br/>
</cfoutput>
</cfloop>
</div>
<div id="right">
<b>col2</b><br/>
<cfloop index="x" from="2" to="#arrayLen(data)#" step="2">
<cfoutput>
#data[x]#<br/>
</cfoutput>
</cfloop>
</div>
#right {
float: left;
width: 200px;
}
</style>

<div id="left">
<b>col1</b><br/>
<cfloop index="x" from="1" to="#arrayLen(data)# step="2">
<cfoutput>
#data[x]#<br/>
</cfoutput>
</cfloop>
</div>
<div id="right">
<b>col2</b><br/>
<cfloop index="2" from="1" to="#arrayLen(data)#" step="2">
<cfoutput>
#data[x]#<br/>
</cfoutput>
</cfloop>
</div>

Comment 3 by Raymond Camden posted on 4/23/2011 at 8:16 PM

Good alternatives guys.

Comment 4 by spills posted on 4/23/2011 at 8:17 PM

I am not sure how the code posted twice but, I will try it again.

Don't forget about the handy dandy "step" option for cfloops we can simplify code further.

<cfset data = [1,2,3,4,5,6,7,8,9]>
<style>
#left {
float: left;
width: 200px;
}
#right {
float: left;
width: 200px;
}
</style>

<div id="left">
<b>col1</b><br/>
<cfloop index="x" from="1" to="#arrayLen(data)#" step="2">
<cfoutput>
#data[x]#<br/>
</cfoutput>
</cfloop>
</div>
<div id="right">
<b>col2</b><br/>
<cfloop index="x" from="2" to="#arrayLen(data)#" step="2">
<cfoutput>
#data[x]#<br/>
</cfoutput>
</cfloop>
</div>

Comment 5 by Paul posted on 4/24/2011 at 2:11 PM

A float-left is enough if you want more than 2 columns:

<cfset data = [1,2,3,4,5,6,7,8,9]>
<cfset nrOfColumns=3>

<style>
#left {
float: left;
width: 200px;
}
</style>

<cfoutput>
<cfloop index="x" from="1" to="#arrayLen(data)#">
<div id="left">
#data[x]#
<cfif x MOD nrOfColumns EQ 0>
<hr>
</cfif>
</div>
</cfloop>
</cfoutput>

Comment 6 by sooraj posted on 4/25/2011 at 12:12 PM

here is another alternative, all in one loop

<style>
#left {
float: left;
width: 200px;
}
#right {
float: left;
width: 200px;
}
</style>

<cfparam name="left_content" default="">
<cfparam name="right_content" default="">

<cfset data = [1,2,3,4,5,6,7,8,9,10]>

<cfloop index="x" from="1" to="#arrayLen(data)#">
<cfset item = data[x]>
<cfif x mod 2 is 1>
<cfset left_content=left_content&"#item#<br/>">
<cfelse>
<cfset right_content=right_content&"#item#<br/>">
</cfif>

</cfloop>
<div id="left">
<b>col1</b><br/>
<cfoutput>#left_content#</cfoutput>
</div>
<b>col2</b><br/>
<cfoutput>#right_content#</cfoutput>
</div>

Comment 7 by Susan Hansen posted on 8/3/2011 at 1:55 AM

Thank you for sharing this code. It does what I need ( I think) except I can't get it to pull my data from a list of subjects in my database. Can the data array be anything other than numbers? I have a database with field sub_name. Items in this list change so I don't want to have to manually make an array with this list of subjects, so I'd like the array to pull this list of sub_names and then display them in two columns (and of course I want the impossible--for the list to be alphabetical left column and flow up to the right column) Any insights appreciated and most welcome as I'm not a programmer. Thank you!

Comment 8 by Raymond Camden posted on 8/3/2011 at 2:18 AM

The data can be anything. If you did a db query, then line 6 in the first snippet would change to a cfloop query="'.

Comment 9 by Dave Seavey posted on 12/4/2013 at 1:19 AM

Exactly what I needed. Perfect, as usual.

Thanks Ray!

Comment 10 by Douglas Benoit posted on 9/10/2014 at 12:12 PM

While this is very cool, most recordsets come from a database table or saved query (Access), right? So the <CFSET data="query_name_or_table"> seems like it may be worth looking into, shouldn't it?

'Just a thought....

Comment 11 by Raymond Camden posted on 9/10/2014 at 3:12 PM

I'm not quite sure I understand you. Whether or not it comes from a db table my solution still applies. Your comment, cfset data="somequery", doesn't make any sense. I just used an array to make it quicker. You could easily switch it to a query.