When you think ASP, think...
Recent Articles
All Articles
ASP.NET Articles [1.x] [2.0]
ASPFAQs.com
Message Board
Related Web Technologies
User Tips!
Coding Tips
Search

Sections:
Book Reviews
Sample Chapters
Commonly Asked Message Board Questions
Headlines from ASPWire.com
JavaScript Tutorials
MSDN Communities Hub
Official Docs
Security
Stump the SQL Guru!
Web Hosts
XML Info
Information:
Advertise
Feedback
Author an Article
Technology Jobs

















internet.com
IT
Developer
Internet News
Small Business
Personal Technology
International

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers
ASP ASP.NET ASP FAQs Message Board Feedback ASP Jobs
Print this page.

Windows Systems Administrator
Jupitermedia
US-CT-Darien

Justtechjobs.com Post A Job | Post A Resume

Published: Tuesday, March 07, 2000

Loops within Loops: Coding an ASP-based Bulletin Board
By 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.

- continued -

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:

<%
  Set rsPosts = Server.CreateObject("ADODB.Recordset")
  sql = "SELECT BulletinBoard.PostID AS Post, BulletinBoard.BBName, " & _
        "BulletinBoard.BBEmail, BulletinBoard.Subject, " & _
        "BulletinBoard.ResponseTo, BulletinBoard.BBDate, " & _
        "BulletinBoard.BBTime  " & _
        "FROM BulletinBoard " & _
        "WHERE ResponseTo = 0 AND BBDate >(Date()-90) ORDER BY BBDate DESC"

  rsPosts.open sql, conn, 3, 3
  If rsPosts.eof = false then 
%>

<!-- In an Access database, you get the current date by the simple command Date(). 
   Other databases use different syntaxes, so this code may have to be tweaked a 
   bit. I am limiting the date so that we don't get 3000 posts on the same page. 
   If your bulletin board was very active, you could limit the date further. 
   If you averaged a post a day, you could make it longer. -->

<!-- The extra "if eof" looks redundant but avoids the server going to the next 
   command unless it is necessary -->

<%
  On Error Resume Next
  rsPosts.MoveFirst

  do while Not rsPosts.eof
    'I explicitly declare the value of "post" here for later use
    Post = rsPosts("Post")
    BBDate = rsPosts("BBDate")

    'I have chosen to use images rather than <ul> so that I can 
    'use a different image depending on the "freshness" of the post

    If BBDate = Date() then %> 
       <img src="../../images/anibutton.gif" align="absmiddle"
           width="15" height="14">
<%  ElseIf BBDate = (Date() -1 ) then %> 
       <img src="../../images/button.gif" align="absmiddle" 
           width="15" height="14">
<%  ElseIf BBDate = (Date() -2 ) then %> 
       <img src="../../images/button2.gif" align="absmiddle" 
            width="15" height="14">
<%  Else %>
       <img src="../../images/button4.gif" align="absmiddle" 
            width="15" height="14">
<%  End If

    'Display info about post here

    rsPosts.MoveNext
  loop
%> 

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 selected as 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 ResponseTo equaled the value of PostID as declared in the previous loop:

<%
  Set rsPosts2 = Server.CreateObject("ADODB.Recordset")
  sql = "SELECT BulletinBoard.PostID AS Post2, " & _
        "BulletinBoard.BBName AS BBName2, " & _
        "BulletinBoard.BBEmail AS BBEmail2, " & _
        "BulletinBoard.Subject AS Subject2, " & _
        "BulletinBoard.Message AS Message2, " & _
        "BulletinBoard.ResponseTo AS ResponseTo2, " & _
        "BulletinBoard.BBHomepageName AS BBHomepageName2, " & _
        "BulletinBoard.BBHomepageURL AS BBHomepageURL2, " & _
        "BulletinBoard.ImageURL AS ImageURL2, " & _
        "BulletinBoard.BBDate AS BBDate2, " & _
        "BulletinBoard.BBTime AS BBTime2 " & _
        "FROM BulletinBoard " & _
        "WHERE ResponseTo = " & Post & " ORDER BY BBDate DESC"

  rsPosts2.open sql, conn, 3, 3

  If rsPosts2.eof = false then

    'This section is a repeat of the section in the first loop, except 
    'all our variables are now VariableName2, and an extra blank image 
    'is added just before the button gif to mimic the spacing we would
    'have gotten using <ul>

  else
    'if eof is TRUE, jump right here to the end!
  end if

  rsPosts2.close
  set rsPosts2 = nothing
%>

  • Read Part 2


    Windows Internet Technology | ASP.NET [1.x] [2.0] | ASPMessageboard.com | ASPFAQs.com | Advertise | Feedback | Author an Article



  • JupiterOnlineMedia

    internet.comearthweb.comDevx.commediabistro.comGraphics.com

    Search:

    Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

    Jupitermedia Corporate Info


    Legal Notices, Licensing, Reprints, & Permissions, Privacy Policy.

    Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers

    Solutions
    Whitepapers and eBooks
    Microsoft Article: HyperV-The Killer Feature in WinServer ‘08
    Avaya Article: How to Feed Data into the Avaya Event Processor
    Microsoft Article: Install What You Need with Win Server ‘08
    HP eBook: Putting the Green into IT
    Whitepaper: HP Integrated Citrix XenServer for HP ProLiant Servers
    Intel Go Parallel Portal: Interview with C++ Guru Herb Sutter, Part 1
    Intel Go Parallel Portal: Interview with C++ Guru Herb Sutter, Part 2--The Future of Concurrency
    Avaya Article: Setting Up a SIP A/S Development Environment
    IBM Article: How Cool Is Your Data Center?
    Microsoft Article: Managing Virtual Machines with Microsoft System Center
    HP eBook: Storage Networking , Part 1
    Microsoft Article: Solving Data Center Complexity with Microsoft System Center Configuration Manager 2007
    MORE WHITEPAPERS, EBOOKS, AND ARTICLES
    Webcasts
    Intel Video: Are Multi-core Processors Here to Stay?
    On-Demand Webcast: Five Virtualization Trends to Watch
    HP Video: Page Cost Calculator
    Intel Video: APIs for Parallel Programming
    HP Webcast: Storage Is Changing Fast - Be Ready or Be Left Behind
    Microsoft Silverlight Video: Creating Fading Controls with Expression Design and Expression Blend 2
    MORE WEBCASTS, PODCASTS, AND VIDEOS
    Downloads and eKits
    Sun Download: Solaris 8 Migration Assistant
    Sybase Download: SQL Anywhere Developer Edition
    Red Gate Download: SQL Backup Pro and free DBA Best Practices eBook
    Red Gate Download: SQL Compare Pro 6
    Iron Speed Designer Application Generator
    MORE DOWNLOADS, EKITS, AND FREE TRIALS
    Tutorials and Demos
    How-to-Article: Preparing for Hyper-Threading Technology and Dual Core Technology
    eTouch PDF: Conquering the Tyranny of E-Mail and Word Processors
    IBM Article: Collaborating in the High-Performance Workplace
    HP Demo: StorageWorks EVA4400
    Intel Featured Algorhythm: Intel Threading Building Blocks--The Pipeline Class
    Microsoft How-to Article: Get Going with Silverlight and Windows Live
    MORE TUTORIALS, DEMOS AND STEP-BY-STEP GUIDES