Code: ASP/VBScript, properly nested list from array
Eureka! Finally!
It only took me about 5 days of tinkering but I managed to code a dynamic, multi-nested list from an array.
The project is to expand the number of levels that available to the web sites at work. Currently we only alloted two level. That was a number of years ago. Now some of our devisions are revamping their content and are needing multiple levels.
So I met with our database guys (DBAs) to draft up a cross reference relational table structure and some stored procedures to bring back the hierarchy of pages so I can draw up a properly nested list of links to use as page navigation (wow that was a long sentence). I’ve been banging my head against the wall for the better part of the week – getting close to a solution but then scrapping the code to come at the problem at a different angle. Today I finally made it work and it’s universal (hopefully).
The logic is what tripped me up. I had to think backwards in a way to determine how to close the list items (<li>) and any nested lists.
Here’s what I wrote. Assume we have our recordset returned as a 2d array via GetRows. There’s more to be done as proper tabbing, and other site-based logic but this gets the output I need.
<%
' -------------------------------------
dim numcols, numrows
' cols = 1
' rows = 2
numcols=ubound(alldata,1)
numrows=ubound(alldata,2)
' our fields
dim fld_xref, fld_id, fld_title
dim title, id, xref
fld_title = 0
fld_id = 1
fld_xref = 2
' our formating
dim ul_open, ul_close, li_open, li_close, list_close
ul_open = "<ul>" & nl
ul_close = "</ul>" & nl
li_open = vbTab & "<li>"
li_close = "</li>" & nl
list_close = ul_close & nl & li_close & nl
dim x
dim l
dim levels
dim tempArray
dim parentID
dim lastID
dim lastXref
' response.Write("<p><a href=""#"" id=""expand_all""><strong>[+]</strong> Expand All</a> | <a href=""#"" id=""collapse_all""><strong>[-]</strong> Collapse All</a> </p>" & nl)
Response.Write("<ul id=""list"">" & nl)
For x = 0 to numRows
' --------------------------------------------------
' Set the stage
' --------------------------------------------------
title = Trim(allData(fld_title, x))
id = allData(fld_id, x)
xref = allData(fld_xref, x)
' ignore first pass
if x > 0 then
if xref = lastID then
' LAST ID WAS PARENT TO CURRENT ID
' open a new <ul>
parentID = lastID
levels = levels & " " & lastID
response.Write(nl & ul_open)
elseif xref = lastXref then
' Current ID is a sibling
' we'll just close the previous <li>
response.Write(li_close & nl)
else
' we're not sure what we're dealing with
' more than likely we need to close a nested list
'close the last <li>
response.Write(li_close)
' generate our array of parent IDs
tempArray = Split(levels)
' walk backwards through the array so
' we get the proper count of lists to close
for l = Ubound(tempArray) to 1 Step -1
parentID = CInt(tempArray(l))
if xref <> parentID then
' if xref does not match our parent ID
' close the list
response.Write(list_close)
' remove the previous ID from the list
' so the next walk throug, there will be one less
levels = replace(levels, " " & parentID, "")
else
' we have a match, stop processing the list
exit for
end if
next
end if
end if
' output our record
response.Write(li_open)
response.Write(title & " | id: " & id & " | xref: " & xref & " | levels: " & levels)
lastID = id
lastXref = xref
Next
response.Write(li_close)
Response.Write(nl & ul_close)
%>
