I spend a good amount of time in various help forums (be it here or on DALnet?s #coldfusion)?and there?s one question that seems to come up time after time:

?CJ?how to you get your hair so shiny and bouncy??

Another question I hear a lot is:

?How can I have my query output display n columns per row??

I?d like to take a few moments to reflect on the second question. If there?s any time left afterwards, feel free to stick around and we?ll discuss my strict hair regimen.

To see exactly what I mean by outputting n columns per row, see this page:

http://charlie.griefer.com/4cols.cfm ?

which will demonstrate the concept by allowing you to determine the number of columns to display, and rendering the content dynamically.

The key to being able to display a specific number of columns per row within an output is the MOD operator. If you?re new to programming (and many CF?ers are? CF was my first programming language when I began with it), you may not be familiar with this operator.

MOD is short for MODULUS, and is simply the value of the remainder after one number is divided by another.

Recall from 3rd grade math that in division, there is a dividend, a divisor, a quotient, and a remainder:

    Dividend / Divisor = Quotient rRemainder 
    Example: 20 / 6 = 3 r2

In the example above, the dividend is 20, the divisor is 6, the quotient is 3 (6 goes into 20 three times), and the remainder is 2. This is our MOD value.

A few more examples:

Value A (dividend)

 

Value B (divisor)

 

Quotient

Mod

50

/

4

=

12

2

16

/

3

=

5

1

100

/

10

=

10

0

The MOD operator is commonly used to test whether or not a value is odd or even. Since any even number is divisible by 2 with no remainder, the following holds true:

<cfif A MOD 2 EQ 0>
    The number is even!
<cfelse>
    The number is odd!
</cfif>

Hopefully you feel that you now have a good grasp of the MOD operator. Time to move on to the next concept.
The next thing you need to be aware of has to do with the
<cfquery> object. We?re all aware of the fact that <cfquery> returns database values from a database table (we?re assuming a SELECT query). It also returns 4 additional variables:

recordCount ? the number of rows returned in the query
columnList ? a comma delimited list of the columns returned in the query
executionTime ? the amount of time it took to execute the query
currentRow ? during output, indicates the row # that is being displayed.

It?s the last one (currentRow) that we?re interested in. Here?s a short example of how currentRow works:

<cfquery name=?getFoo? datasource=?foo?>
    SELECT foo
    FROM bar
</cfquery>

<table border=?1?>
   
<cfoutput query=?getFoo?>
    <tr>
        <td>
#getFoo.currentRow#</td>
    </tr>

   
</cfoutput>
</table>

Assuming the getFoo query returned 20 rows, our output would show the numbers 1 through 20, each in it?s own table cell in its own row. Each iteration of the query driven
<cfoutput> starts a new table row (note that the <tr></tr> tags are within the <cfoutput></cfoutput> block).

Putting the currentRow variable together with the MOD operator, we can now get to work on displaying our output neatly in a specific number of columns.

Using our same query as above, we?re going to make 2 modifications. The first is:

<cfquery name=?getFoo? datasource=?foo?>
    SELECT foo
    FROM bar
</cfquery>

<table border=?1?>
    <tr>

    <cfoutput query=?getFoo?
        <td>#getFoo.currentRow#</td>
    </cfoutput>
    </tr>
</table>


What?s different? We placed our query-driven
<cfoutput> tags inside of <tr></tr> blocks, as opposed to outside.

Now, instead of 20 table rows, we?re going to get 20 table cells (
<td>s) all in one row.

The final step is going to be how to tell ColdFusion to end the current row and start a new row after 4 <td>s.

This is where we get some mileage out of the MOD operator.

<cfquery name=?getFoo? datasource=?foo?>
    SELECT foo
    FROM bar
</cfquery>

<cfset variables.newrow = false>

<table border=?1?>
    <tr>

   
<cfoutput query=?getFoo?>
    <cfif variables.newrow = true>
        <tr> 
    </cfif>

       
<td>#getFoo.currentRow#</td>
       
<cfif getFoo.currentRow MOD 4 EQ 0>
               
</tr>
                <cfset variables.newrow = true>
        <cfelse>
                <cfset variables.newrow = false>
       
</cfif>
   
</cfoutput>
   
</tr>
</table>

<cfif getFoo.currentRow MOD 4 EQ 0>. That?s the key.

We?re telling ColdFusion that as it loops over the query output, it needs to check to see if the current record being output is evenly divisible by 4.  If it is, we insert a </tr> (since we only want 4 columns per row).  We also ?flip a switch??by setting the local variable newrow to be true.  The next iteration of the output needs to be aware of the fact that a <tr> was just closed, so it knows to open a new <tr>.  The newrow variable handles that.  Originally, we set it to false (before our table).  It will resolve to false for every iteration of the output that is *not* divisible by 4.

Check out the page at http://charlie.griefer.com/4cols.cfm, and as always, contact me with any questions or comments :)

About This Tutorial
Author: Charlie Griefer (CJ)
Skill Level: Beginner 
 
 
 
Platforms Tested: CF5,CFMX
Total Views: 88,231
Submission Date: May 29, 2003
Last Update Date: June 05, 2009
All Tutorials By This Autor: 15
Discuss This Tutorial
  • The reason it's so complicated is to avoid the empty row that your suggestion could create. If the last row in the query is MOD X IS 0, then your code will end the table with: Which, while it will work, is sloppy coding. That is the reason for the if structures. -- Pat

  • I've been using MOD for years and never knew what it meant or how everything worked. The other comment was correct in that there is a shorter way, but his shorter way doesn't explain as much as yours.

  • Why so much code to do something so simple?

    #linkname#

  • please change: to: (sorry) :)

  • I can't get this to work. I keep getting an error on the line with the

Advertisement

Sponsored By...
Powered By...