Even though we now have our list in the correct order, it’s not yet pretty. We have a list, but we really don’t have a tree, do we? We need to associate some kind of depth information with each level in the tree. There are a couple of ways we could do this, but the easiest way is to just keep another, parallel, stack with depth information. Going back to our second loop, the one where we figure out which items are the root items and push them onto the stack:
<cfset RootItems=ArrayNew(1)> <cfset Depth=ArrayNew(1)> <cfloop query="Stuff"> <cfif NOT StructKeyExists(RowFromID, ParentID)> <cfset ArrayAppend(RootItems, ItemID)> <cfset ArrayAppend(Depth, 0)> </cfif> </cfloop>
Why use 0 for the initial depth? We know that we’ll be incrementing the depth for each level of children, so the first displayed children will have a depth of 1, et cetera. So, starting at 0 seems pretty logical. Of course, if you want to start at 42 or something else, you are welcome to.
We then just need to keep our depth stack synchronized with the item stack in the third loop:
<cfset ThisID=RootItems> <cfset ArrayDeleteAt(RootItems, 1)> <cfset ThisDepth=Depth> <cfset ArrayDeleteAt(Depth, 1)>
And again later on when we push the children onto the stack:
<cfset ArrayPrepend(RootItems, ChildrenIDs[i])> <cfset ArrayPrepend(Depth, ThisDepth + 1)>
This allows us to do tricks like this back up in the display portion of our loop:
You can add in non-breaking spaces, spacer images, empty table cells, or whatever you want instead of the -- part to make your display come out right. If you want to be really fancy and generate correctly-nested HTML lists with the data … you’re going to have to wait for a later installment in this series. We’ll get there, but it’s trickier.
As for the additional robustness, we’ll work on that next.