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