When you think ASP, think...
Recent Articles
All Articles
ASP.NET Articles
Message Board
Related Web Technologies
User Tips!
Coding Tips

Sample Chapters
Commonly Asked Message Board Questions
JavaScript Tutorials
MSDN Communities Hub
Official Docs
Stump the SQL Guru!
XML Info
Author an Article
ASP ASP.NET ASP FAQs Message Board Feedback
Print this page.
Published: Wednesday, February 20, 2002

Enhancing the Dynamic Tree Menu System, Part 2

By Sam M. Reynoso

  • Read Part 1

  • In Part 1 we examined the changes tothe Dynamic Tree Menu System to allow for browser compatibility (in the 6.x browser versions, at least). In this part we'll look at some UI features that were added, as well as the added feature to allow for loading data from a database table (as opposed to just from an XML file).

    - continued -

    Hover Highlights
    One of the simplest enhancements added to the sample was what I call a "Hover Highlight". This handy feature changes the color of menu items as the mouse moves over them. Not only does this look cool, but it also helps users stay focused as they decide which item to click. Unfortunately, this feature does not work in non-IE browsers, but I'd love to hear if anyone finds a work-around.

    To achieve the hover effect, simply add this single line to the "node" class in the Cascading Style Sheet definition:

    .node A:hover { color: #0000ff; text-decoration: none; }

    Selected Menu Item
    In the Windows Explorer you will notice that clicking a folder causes the folder's text to change to white and take on a bold background color. I liked this feature and decided to mimic it in the tree menu. The effect provides a visual clue that helps the user remember which item they last clicked. Unfortunately, like the Hover Highlights described above, this is also an IE-specific feature.

    This feature is a little more complicated to implement than the Hover Highlights feature because we need to use a combination of Javascript code and a CSS style class. Each hyperlink in the menu has an onClick event that calls the fnSelectItem() function:


    When this event fires, it causes the following three things to happen:

    1. Removes selection indicator from the previously selected menu item
    2. Applies dark blue background and white text to the currently selected menu item
    3. Returns an object reference to the item that was clicked and stores it in objPreviousLink

    To make these things happen, the fnSelectItem() Javascript function uses a while loop to traverse the structure of the menu's HTML code, storing a reference to the current object and stopping when the first <TD> tag is found. It is this tag that we need to alter in order to achieve a selected effect. When the while loop finds the <TD> tag, it applies a new style class to the tag:

    objTD.className = "selected";

    The selected style is defined in the Cascading Style Sheet.

    The function fnSelectItem() calls fnDeselectItem() to return the style of the previously selected menu item to normal. These two functions generally work in the same way, except that they apply different styles.

    Data Load from DB
    Many developers wrote in requesting a way to load the tree dynamically with data pulled from a database instead of from an XML file. It turns out this is relatively simple, requiring the use of a few methods provided by the MSXML parser. To put an XML tree together manually instead of from an existing XML file, we start like we did before by creating an instance of the MSXML parser with the following line:

    Set objDocument = Server.CreateObject("MSXML2.FreeThreadedDOMDocument.3.0")

    Once we have our XML document object, we create a root node using the createElement() method like this:

    set objRootNode = objDocument.createElement("country")

    Attributes are added to the new node with the setAttribute() method. In our example, we add three attributes to the root node:

    objRootNode.setAttribute("value") = "United States of America"
    objRootNode.setAttribute("type") = "root"
    objRootNode.setAttribute("url") = "content.asp?page=usa"

    The root node is now complete, but it is lacking child nodes. Child nodes are created using the same technique we used for the root node. In this example, we create a child node called objStatesNode using createElement() and setAttribute() methods. When the child node is complete, we attach it to its parent by calling the appendChild() method like this:

    objRootNode.appendChild objStatesNode

    If we were to print out the contents of the XML document object at this point, it would resemble the following:

    <country value="United States of America" type="root" url="content.asp?page=usa">
       <states value="States" type="folder" url="content.asp?page=states"/>

    Additional child nodes can be added by repeating this process. Once you are comfortable with the use of these methods, it becomes easy to imagine how they could be used in conjunction with ADO recordsets and a simple loop. The following chunk of code shows how we can populate our new States node with a list of state names pulled from a database table:

      sql = "SELECT StateName, url, Type FROM tblStates ORDER BY StateName"
      set rs_states = conn.execute(sql)
      if not rs_states.eof then
        'Create a node in the XML document object for each subitem
        do while not rs_states.eof
          set objStateNode = objDocument.createElement("state")
          objStateNode.setAttribute("value") = rs_states(0)
          objStateNode.setAttribute("url") = rs_states(1)
          objStateNode.setAttribute("type") = rs_states(2)
          objStatesNode.appendChild objStateNode 'Attach the new node to its parent
      end if
      set rs_states = nothing
      objRootNode.appendChild objStatesNode

    Using code like this, the navigation tree can be rebuilt dynamically using data pulled from a database instead of a static XML file. This would enable the content of the tree to be changed based on user actions.

    Now that we've examined how to load data into the tree menu system, you may be wanting to conditionally load the data. That is, you don't want to load the data for a node in the tree until the user clicks on it. In Part 3 we'll examine how to accomplish this.

  • Read Part 3!

  • ASP.NET [1.x] [2.0] | ASPFAQs.com | Advertise | Feedback | Author an Article