Recursive Custom Tags by Mark Cyzyk
CFDJ 2-10 p10

Listing 1: cf_simpleBuildTree
1  <cfparam name="theID" default="0">
2
3  <cfif IsDefined("attributes.theID")>
4  <cfset theID = attributes.theID>
5  </cfif>
6
7  <cfquery datasource=#application.datasource#
   password=#application.password# name="getCurrentItems">
8  SELECT  *
9  FROM    LOOKUPSUBJECTS
10 WHERE   PARENTID = #THEID#
11 ORDER BY SUBJECT
12 </cfquery>
13
14 <ul>
15
16 <cfloop query="GetCurrentItems">
17
18 <cfoutput>
19 <li>#subject#
20 </cfoutput>
21
22 <cfquery datasource=#application.datasource#      password=#application.password# cachedwithin=#Create-
   TimeSpan(0,0,0,2)# name="checkForChild">
23 SELECT  SUBJECTID
24 FROM    LOOKUPSUBJECTS
25 WHERE   PARENTID = #GETCURRENTITEMS.SUBJECTID#
26 </cfquery>
27
28 <cfif checkForChild.RecordCount gt 0>
29 <cf_simpleBuildTree
30  theID = "#GETCURRENTITEMS.SUBJECTID#"
31  >
32 </cfif>
33
34 </cfloop>
35
36 </ul>

Listing 2: cf_buildTree
1  <cfparam name="theID" default="0">
2  <cfparam name="mode" default="outline">
3
4  <cfif IsDefined("attributes.theID")>
5  <cfset theID = attributes.theID>
6  </cfif>
7
8  <cfif IsDefined("attributes.mode")>
9  <cfset mode = attributes.mode>
10 </cfif>
11
12 <cfquery datasource=#application.datasource#      password=#application.password# name="getCurrentItems">
13 SELECT  *
14 FROM LOOKUPSUBJECTS
15 WHERE   PARENTID = #THEID#
16 ORDER BY SUBJECT
17 </cfquery>
18
19 <cfif mode IS "outline"><ul></cfif>
20
21 <cfloop query="getCurrentItems">
22
23 <cfif mode IS "outline">
24 <cfoutput>
25 <li>#subject#
26 </cfoutput>
27 </cfif>
28
29 <cfquery datasource=#application.datasource#      password=#application.password# cachedwithin=#Create-
   TimeSpan(0,0,0,2)# name="checkForChild">
30 SELECT  SUBJECTID
31 FROM    LOOKUPSUBJECTS
32 WHERE   PARENTID = #GETCURRENTITEMS.SUBJECTID#
33 </cfquery>
34
35 <cfif checkForChild.RecordCount gt 0>
36  <cfif mode IS "string">
37  <cf_reverseTree
38   theID = "#GETCURRENTITEMS.SUBJECTID#"
39   >
40  </cfif>
41 <cf_buildTree
42  theID = "#GETCURRENTITEMS.SUBJECTID#"
43  mode = "#MODE#"
44  >
45 <cfelse>
46  <cfif mode IS "string">
47   <cf_reverseTree
48    theID = "#GETCURRENTITEMS.SUBJECTID#"
49    >
50  </cfif>
51 </cfif>
52
53 </cfloop>
54
55 <cfif mode IS "outline"></ul></cfif>

Listing 3: cf_reverseTree
1  <cfparam name="theList" default="">
2
3  <cfif IsDefined("attributes.theID")>
4  <cfset theID = attributes.theID>
5  </cfif>
6
7  <cfif IsDefined("attributes.theList")>
8  <cfset theList = attributes.theList>
9  </cfif>
10
11 <cfquery datasource=#application.datasource#      password=#application.password# cachedwithin=#Create-
   TimeSpan(0,0,0,2)# name="getCurrentItems">
12 SELECT  *
13 FROM LOOKUPSUBJECTS
14 WHERE   SUBJECTID = #THEID#
15 </cfquery>
16
17 <cfset theItem = #getcurrentitems.subject#>
18 <cfset theList = listPrepend(theList, "#theItem#")>
19
20 <cfif #getcurrentitems.parentID# IS NOT 0>
21 <cf_reverseTree
22  theID = "#GETCURRENTITEMS.PARENTID#"
23  theList = "#theList#"
24  >
25 <cfexit>
26 </cfif>
27
28 <cfset theList = listChangeDelims(theList, " - ")>
29
30 <cfoutput>
31 #theList#<br>
32 </cfoutput>

Listing 4: cf_selectboxBuildTree
1  <cfparam name="theID" default="0">
2  <cfparam name="mode" default="outline">
3
4  <cfif IsDefined("attributes.theID")>
5  <cfset theID = attributes.theID>
6  </cfif>
7
8  <cfif IsDefined("attributes.mode")>
9  <cfset mode = attributes.mode>
10 </cfif>
11
12 <cfquery datasource=#application.datasource#
   password=#application.password# name="getCurrentItems">
13 SELECT  *
14 FROM LOOKUPSUBJECTS
15 WHERE   PARENTID = #THEID#
16 ORDER BY SUBJECT
17 </cfquery>
18
19 <cfif mode IS "outline"><ul></cfif>
20
21 <cfloop query="GetCurrentItems">
22
23 <cfif mode IS "outline">
24 <cfoutput>
25 <li>#subject#
26 </cfoutput>
27 </cfif>
28
29 <cfquery datasource=#application.datasource#
   password=#application.password# cachedwithin=#Create-
   TimeSpan(0,0,0,2)# name="checkForChild">
30 SELECT  SUBJECTID
31 FROM    LOOKUPSUBJECTS
32 WHERE   PARENTID = #GETCURRENTITEMS.SUBJECTID#
33 </cfquery>
34
35 <cfif CheckForChild.RecordCount IS NOT 0>
36  <cfif (mode IS "string") OR (mode IS "selectbox")>
37  <cf_selectboxReverseTree
38   theID = "#GETCURRENTITEMS.SUBJECTID#"
39   mode = "#MODE#"
40   initialID = "#GETCURRENTITEMS.SUBJECTID#"
41   >
42  </cfif>
43 <cf_selectboxBuildTree
44  theID = "#GETCURRENTITEMS.SUBJECTID#"
45  mode = "#MODE#"
46  >
47 <cfelse>
48  <cfif (mode IS "string") OR (mode IS "selectbox")>
49   <cf_selectboxReverseTree
50    theID = "#GETCURRENTITEMS.SUBJECTID#"
51    mode = "#MODE#"
52    initialID = "#GETCURRENTITEMS.SUBJECTID#"
53    >
54  </cfif>
55 </cfif>
56
57 </cfloop>
58
59 <cfif mode IS "outline"></ul></cfif>

Listing 5: cf_selectboxReverseTree
1  <cfparam name="theList" default="">
2
3  <cfif IsDefined("attributes.theID")>
4  <cfset theID = attributes.theID>
5  </cfif>
6
7  <cfif IsDefined("attributes.theList")>
8  <cfset theList = attributes.theList>
9  </cfif>
10
11 <cfif IsDefined("attributes.mode")>
12 <cfset mode = attributes.mode>
13 </cfif>
14
15 <cfif IsDefined("attributes.initialID")>
16 <cfset initialID = attributes.initialID>
17 </cfif>
18
19 <cfquery datasource=#application.datasource#
   password=#application.password# cachedwithin=#Create
   TimeSpan(0,0,0,2)# name="getCurrentItems">
20 SELECT  *
21 FROM LOOKUPSUBJECTS
22 WHERE   SUBJECTID = #THEID#
23 </cfquery>
24
25 <cfset theItem = #getcurrentitems.subject#>
26
27 <cfset theList = listPrepend(theList, "#theItem#")>
28
29 <cfif #getcurrentitems.parentID# IS NOT 0>
30 <cf_selectboxReverseTree
31  theID = "#GETCURRENTITEMS.PARENTID#"
32  theList = "#THELIST#"
33  mode = "#MODE#"
34  initialID = "#INITIALID#"
35  >
36 <cfexit>
37 </cfif>
38
39 <cfset theList = listChangeDelims(theList, " - ")>
40
41 <cfoutput>
42 <cfif mode IS "selectbox">
43 <option value=#INITIALID#>
44 </cfif>
45 #theList#
46 </cfoutput>
47 <cfif mode IS NOT "selectbox">
48 <br>
49 </cfif>

Listing 6: A form calling cf_selectboxBuildTree
1  <fieldset>
2  <legend><b>Subject Terms - cf_selectboxBuildTree - Select
   box Mode</b></legend>
3  <p>
4  <cfform action="action.cfm">
5  <dl>
6  <dt>New subject:
7  <dd><cfinput name="subject" size=25 required message="You
   must include a subject!">
8  <dt>New subject is the child of:
9  <dd><select name="parentID" size=5">
10 <option value=0 selected>New subject is at top of tree
   (not a child of any parent subject)
11 <cf_selectboxBuildTree
12  mode="selectbox"
13  >
14 </select>
15 <p>
16 <input type="submit" value="Submit">
17 </cfform>
18 <p>
19 </fieldset>