Last week, I was doing a little grunt work for Peter Bell; occassionally, he throws me some scraps from the genius buffet on which he dines, and last week, the scrap had to do with encapsulating table display logic (which, of course, I gobbled up with excitement)... OK, enough with the food analogies. When you are looping over a query, an array, or any sort of iterating business object within the context of a table structure, there is a good deal of logic that goes into determining when to open cells or close cells, when to end the current row, when and if to start the next row, and how to fill out a row that doesn't have enough data to display.
I have done a good deal of work with ColdFusion custom tags, and Peter wanted to see if I could somehow encapsulate the display logic into a custom tag in such a way that you could write code along these lines:
Launch code in new window » Download code as text file »
Here, the "random HTML" would be the in-cell content. Notice that there wouldn't be any logic to create tables, rows, or cells - that would all be taken care of by the ColdFusion custom tag.
The proof-of-concept ColdFusion custom tag that I made for Peter worked, but it didn't sit right in my head. It had some display logic in the Start tag and some display logic in the End tag, and that didn't feel right. I disliked the idea of having my display logic in multiple places - but what could I do? With a ColdFusion custom tag, you can't reach into the content itself, you can only control what goes on around it.
That's what I thought at the time, but then after I emailed Pete the code, I remembered my old friend, THISTAG.GeneratedContent. ColdFusion custom tags are special in that they do not write any of the generated content to the response's content buffer until after the entire tag has finished executing. This means that you can reach in and alter the between-tag content that the user writes.
Of course, I have never done this in the context of a LOOPING tag, only with a single Start-End tag. As it turns out, though, it works in exactly the same way; for each iteration of the looping ColdFusion custom tag, THISTAG.GeneratedContent holds the output of the current iteration only. You can then grab this, change it, and output updated content without issue.
To demonstrate both the encapsulation of table displays and the use of THISTAG.GeneratedContent in the context of a looping ColdFusion custom tag, I have put together this little demo. Here, I have created TableLoop.cfm, a ColdFusion custom tag that iterates over the passed in array to display a table layout with a passed-in number of columns:
Launch code in new window » Download code as text file »
Notice that there is no Table HTML anywhere. Like a regular index loop, we just have an Index variable into which the current "value" is stored. We then use that value to output our table cell content but don't busy ourselves with and table display logic. All we have to do is pass in the array and tell it that we want THREE columns of display and this is what we get:
| | | | ||
| | ![]() | | ||
| | | |
Notice that we have three TDs per table row (TR) as specified by the Columns attribute. Also notice that in the third row, even though we don't have enough data to display, the TableLoop.cfm ColdFusion custom tag creates two empty cells to give the Table valid XHTML.
That was super easy to do because the table display logic is encapsulated by the TableLoop.cfm ColdFusion custom tag:
Launch code in new window » Download code as text file »
If you look at the Start execution mode of this tag, you will notice that it has no display logic. It doesn't start the table, row, or cell for the first iteration. The only actions it does is to param the tag attributes and some tag-based variables. It waits until it gets into the End execution mode of the tag to do any display logic. Thanks to our ability to update and completely reset the THISTAG.GeneratedContent value on a per-iteration basis, we can perform display logic after the fact.
Pretty nifty stuff! Of course, to really make this useful, you would also have to provide attributes or nested tags to allow the user to set display styles. But, compared to the display logic, such updates would be quite easy.
Download Code Snippet ZIP File
Comments (0) | Post Comment | Ask Ben | Permalink | Other Searches | Print Page
There are no comments posted for this web log entry.