Web DevCenter
oreilly.comSafari Books Online.Conferences.
MySQL Conference and Expo April 14-17, 2008, Santa Clara, CA

Sponsored Developer Resources

Web Columns
Adobe GoLive
Essential JavaScript

Web Topics
All Articles
Scripting Languages

Atom 1.0 Feed RSS 1.0 Feed RSS 2.0 Feed

Learning Lab

Extending Dreamweaver: Let Dreamweaver Create Your Menus
Pages: 1, 2

  Related Reading:
DreamWeaver 4: The Missing Manual

DreamWeaver 4: The Missing Manual
By Dave McFarland
July 2001 (est.)
0-596-00097-9, Order Number: 0979
420 pages (est.), $24.95 (est.)

Using Recursion

Basically, we're creating a function which scans the content of a folder and calls itself when it encounters another folder. Thus we make sure to get the complete directory structure under a given root folder.

We won't dive into all of recursion's details here. However, just remember one of the most important facts about recursion: every time you make a function call inside of a function, the JavaScript interpreter leaves a reference to the calling function on the so-called stack, which is needed to return to this function after the called function returned. This behavior allows us to easily implement a function which creates a hierarchical menu -- actually, we're only translating one system into another, since a tree-style menu is also a recursive structure.

Step 2: Rebuild the Directory Structure

Instead of directly building the HTML code needed, we create an in-memory representation of the directory structure. I created two small JavaScript classes called File and Folder, which is an extension of File. Starting with a Folder instance, which is created from the selected folder, the list() function rebuilds a complete representation of the directory structure under the root folder selected.

Inside list(), we use the already introduced DWfile.listFolder(). We iterate the list of files, if any, and differ between files and folders. In every case we're instantiating a new object File or Folder and appending it to the current folder's files array; in the case of a folder, we simply call list() and do it again.

One thing you should be aware of are Dreamweaver's files, such as TMP files or _notes folders. The code filters these, so they're not included into the menu. Due to the recursive behavior, list() returns with the root folder again.

If you're wondering why we're not directly creating the HTML code, I'll be covering that in future columns, along with concepts including feeding data like this directly to an graphical application like Fireworks and creating your own site maps with a single click.

Step 3: Create the Menu's Code

Aside from a few caveats, let's look at what we need to do to finish this exercise. First, we must be able to model a hierarchical structure, i.e., use indentation to show relations between items. The next thing is to create a mechanism to open and close folders. Both problems are solved easily with CSS.

Remember the way CSS lays out its contents? It makes a distinction between boxes and inline elements. Basically, the difference is that a box always occupies a rectangular area on the screen and wants to reside on its own line, whereas inline elements flow on the page. So to create an indented tree structure, we simply use boxes with a margin to the left. Both files and folders go into the generic box element DIV and have their own assigned style classes. The boxes are stacked upon each other and create a tree automatically.

In order to make the tree become "live," folders are treated specially. The difference is that a folder, naturally, contains more items. The name of the folder is always visible; the contents may not be. Actually, a folder must be represented by two containers -- the first one takes the folder's name and an icon, the second one holds the contents of the folder.

While the file links directly point to URLs, the folder links point to a small JavaScript function which is called toggleMenu(). This function receives an element's ID and toggles CSS's display property. This property contains all the magic needed to display an element as a box element or to completely hide it, which means it takes no space on screen (in contrast to the effect of thevisibility property).

When you have such a link, the trick is to pass the ID of the element, which serves as the container for the folder's content. So the folder's content becomes visible or invisible, but the name always stays. Additionally, a small plus or minus sign shows the state of the folder. But how do we create a really individual ID?

Once again, recursion is the solution. The code is recursive, already; we only add a few snippets of code. The trick is to create an ID of the current folder's location inside the tree. Consider the root folder having ID "0." The first parent item can be addressed as "0.1." The second one might be a folder; it has ID "0.2." The child items of this folder can be addressed by "0.2.1," "0.2.2," etc. We're passing a initial value of "0" to the first call of traverse() (which is the actual recursive workhorse inside createTree()), and appending a dot (.) and the iteration index. That's almost it. To make the ID even more individual, you could prepend something like "menuitem."

After climbing through the folder structure, the function createTree() returns a string containing the complete menu, which can be easily inserted into an HTML document.


That's it for today. You can find some examples of the menus being created on our examples page. The complete code can, as always, be found in our JavaScript library.

Claus Augusti is O'Reilly Network's JavaScript editor.

Read more Essential JavaScript columns.

Return to the JavaScript and CSS DevCenter.