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
Megnut

Web Topics
All Articles
Browsers
ColdFusion
CSS
Database
Flash
Graphics
HTML/XHTML/DHTML
Scripting Languages
Tools
Weblogs

Atom 1.0 Feed RSS 1.0 Feed RSS 2.0 Feed

Learning Lab






Working with Object Trees: Part Two
Pages: 1, 2, 3

Deleting a child object

Listing 17 lists the code for deleting an object in an object tree using the deleteElement function. However, use deleteElement with caution. For example, with the Dog family tree, the array index 0 and 1 are reserved for the name and fur color. Deleting the array index 0 or 1 will make your tree lose its structure. However, using deleteElement wisely can result in a safe object deletion, as demonstrated in the code in Listing 17. It deletes boni's third element ("spotty") from the tree.


Listing 17: Deleting a child object




<html>
<head>
<title>Deleting a child object</title>
</head>
<body>
<script language="JavaScript">

function createDog(name, color) {
  var dog = new Array();
  dog[0] = name;
  dog[1] = color;
  return dog;
}

function append(parent, child) {
  parent[parent.length] = child;
}

var bo = createDog("bo", "brown");
var boli = createDog("boli", "black and white");
var boy = createDog("boy", "brown");
var bulbul = createDog("bulbul", "brown");
var boni = createDog("boni", "black and white");
var spotty = createDog("spotty", "black and white");
var mary = createDog("mary", "black and white");
append(bo, boli);
append(bo, boy);
append(boli, bulbul);
append(boli, boni);
append(boni, spotty);
append(boni, mary);

function deleteElement(array, n) {
  //delete the nth element of array
  var length = array.length;
  if (n >= length || n<0)
    return;

  for (var i=n; i<length-1; i++)
    array[i] = array[i+1];
  array.length--;
}

function navigate(dog, generation) {
  var name = dog[0];
  for (var i=1; i<generation; i++)
    document.write("<IMG BORDER=1 SRC=images/blank.gif>");
  document.write(name + "<BR>");
  generation++;
  for (var j=2; j<dog.length; j++ )   // has descendants
    navigate(dog[j], generation);
}

navigate(bo, 1);
deleteElement(boni, 2);
navigate(bo, 1);


</script>
</body>
</html>


Figure 2 shows the object tree before and after the deletion.


Figure 2: The object tree before and after the deletion

Notice that spotty is missing from the second tree.

Event handling in an object tree

You can add an event handler to the tree so your application can respond to a mouseclick or a mouseover on an object. For example, the code in Listing 18 adds a function called handler that responds to a user click on an object. The response is a simple alert window displaying the name of the dog.


Listing 18: Adding event handling to an object tree


<html>
<head>
<title>Event handling in an object tree
</head>
<body>
<script language="JavaScript">

function createDog(name, color) {
  var dog = new Array();
  dog[0] = name;
  dog[1] = color;
  return dog;
}

function append(parent, child) {
  parent[parent.length] = child;
}

var bo = createDog("bo", "brown");
var boli = createDog("boli", "black and white");
var boy = createDog("boy", "brown");
var bulbul = createDog("bulbul", "brown");
var boni = createDog("boni", "black and white");
var spotty = createDog("spotty", "black and white");
var mary = createDog("mary", "black and white");
append(bo, boli);
append(bo, boy);
append(boli, bulbul);
append(boli, boni);
append(boni, spotty);
append(boni, mary);

function handler(name) {
  alert(name);
}

function navigate(dog, generation) {
  var name = dog[0];
  for (var i=1; i<generation; i++)
    document.write("<IMG BORDER=1 SRC=images/blank.gif>");
  document.write("<A HREF=\"javascript:handler('" + name + "')\">" +
    name + "</A><BR>");
  generation++;
  for (var j=2; j<dog.length; j++ )   // has descendants
    navigate(dog[j], generation);
}

navigate(bo, 1);

</script>
</body>
</html>


Now, instead of plain text, each object is represented by a hyperlink that can respond to the user click, as shown in Figure 3.


Figure 3: Demonstration of event handling in an object tree

Sometimes you want to change the look of the object tree when responding to the user event. For example, in a folder tree, you probably want to display an open folder icon for the folder clicked by the user. However, this poses another problem because the tree must be redrawn. The trick is to store your JavaScript code in another page. The example in Listing 19 uses a frame to store the JavaScript code and draws the object tree in a different document.


Listing 19: An example


<html>
<script language="JavaScript">

function createDog(name, color) {
  var dog = new Array();
  dog[0] = name;
  dog[1] = color;
  return dog;
}

function append(parent, child) {
  parent[parent.length] = child;
}

var bo = createDog("bo", "brown");
var boli = createDog("boli", "black and white");
var boy = createDog("boy", "brown");
var bulbul = createDog("bulbul", "brown");
var boni = createDog("boni", "black and white");
var spotty = createDog("spotty", "black and white");
var mary = createDog("mary", "black and white");
append(bo, boli);
append(bo, boy);
append(boli, bulbul);
append(boli, boni);
append(boni, spotty);
append(boni, mary);

var dogClicked="";
function handler(name) {
  dogClicked = name;
  var doc = frames[0].document;
  doc.clear();
  redraw(bo, 1, doc);
  doc.close();
}

function redraw(dog, generation, doc) {
  var name = dog[0];
  for (var i=1; i<generation; i++)
    doc.write("<IMG BORDER=1 SRC=images/blank.gif>");
  doc.write("<A HREF=\"javascript:parent.handler('" +
    name + "')\">"); 
  if (name==dogClicked)
    doc.write("<I><B>" + name + "</B></I>");
  else
    doc.write(name);
  doc.write("</A><BR>");
  generation++;
  for (var j=2; j<dog.length; j++ )   // has descendants
    redraw(dog[j], generation, doc);
}


</script>

<frameset onLoad="redraw(bo, 1, frames[0].document);
 frames[0].document.close()" rows="100%, *">
<frame name=frame1 src=frame1.html>
<frame name=frame2 src=frame2.html>
</frameset>

</html>


Note: A Netscape browser will complain if frame1.html or frame2.html is blank. Therefore, write a blank string to make it happy. Also, you need to close the document at the Frameset's onLoad event, otherwise Internet Explorer will behave unexpectedly, such as refusing to clear the document. The object tree that can change appearance is shown in Figure 4. In this figure, bulbul is printed in italic because it's the selected dog.


Figure 4: An object tree that can change its appearance.

Summary

The Array object is the only data structure available when you need to work with objects in JavaScript. Thanks to the flexibility of the Array object, you can assign an array as an element of another array. This enables you to have a linked list or an object tree.

As you have seen, object trees have many applications. Equipped with functions to create objects, append an object to another object, and delete an object, you can manipulate your object tree easily. Other functions that you need badly when using an object tree are navigate, display, and search, all of which have been demonstrated in this article.

Budi Kurniawan is a senior J2EE architect and author.


Return to the JavaScript and CSS DevCenter.