Loops within Loops: Coding an ASP-based Bulletin BoardBy Zola
Webmaster Note: This article provides an easy way to list nested forums. It does have some drawbacks, though. For starters, there is an upper-bound on the number of nested replies a message can have. In this example, the number is 12, although this is configurable. Furthermore, this approach is not the most efficient approach, and could be streamlined using stored procedures and fewer ADO objects within the code.
That being said, it is still a good article and good code. As a developer, there is often a tradeoff between the ease of programming and the efficiency of the script. Since Zola's Web site is not hammered with hundreds or thousands of messages every day, Zola was able to place ease of programming before efficiency. This messageboard system is good for beginners wanting to learn more about nested forums, and very useful for sites that don't expect hundreds or thousands of daily messages. If you do expect such conditions, you should invest in a commercial messageboard application.
Now, onto the article!
Recently I ran into a programmer's nightmare-due to a server upgrade, those handy cgi bulletin board scripts provided by my host no longer ran, and when I went to generate new ones, I discovered that they were "in development", web-ese for "sometime this century". But what about my 20 or so non-running boards?
I had been puzzling over how to convert my boards to ASP for some time. You see, adding the info to the database was no problem, but formatting the output was the kicker. It turned out the answer was nested loops!
Let's discuss the nature of a bulletin board for a moment. What you have is posts, and then you have responses to those posts, and responses to the responses to the posts.....my former cgi script basically looked at this, created the tree and wrote it to the page. It also had the additional annoyance of creating a new page for each post. On the surface, that sounds like a minor issue...until you have 626 pages in your site of which 400 are posts! And there was no convenient way to archive.
ASP would give me the convenience I wanted. I could store each post in my database and call it as necessary, I could limit the results on the page by date, which would make archiving a breeze, and good-bye to 400 pages worth of posts.
Viewing the posts was simple. I could use the GET method to pass the post ID number, and simply write a single page that displayed whatever post matched the ID. Adding and editing posts was equally basic. But HOW to make the main page display properly? The only board whose code I could access for free only divided posts into main posts and responses. I wanted the same formatting I could get with my cgi script.
The easiest way to determine which posts were responses and which were not was to create a field called
ResponseTo. I liked my old board's feature of having the form to make a post right on the
page you were using, and that solved the problem of filling in the
ResponseTo field. If you
made a post from the main page, the
ResponseTo field was set as a hidden field valued at 0.
If you made a response to a post, the
ResponseTo field was set as a hidden field with a value
equal to the post ID that had already been passed.
So the first part of that display page would have to be to get all the posts where
ResponseTo was equal
to zero. That meant it was a primary post. This was a standard looped query:
Getting the responses would use the same kind of query, as would getting the responses to the responses. But I realized that in order to display the posts in order, from the original post, then the response, then the response to the response and so on, I needed to nest those query loops!
So, I inserted a second query between the display info and the
MoveNext loop. This query was
almost identical to the first, except for a few minor changes. First, I would want to give my variables a
slightly different name. If I have multiple values named
PostID, there is going to be some
confusion as to WHICH variable I meant.
This was easily solved by using
SELECT AS. To keep it simple,
PostID would be
PostID2, and so on. Then I would have a set of variables for the first set of posts,
then the second, and so on. I would also change the criteria of my
SELECT statement. I had
declared the value of
Post, so now I wanted all the posts where
the value of
PostID as declared in the previous loop: