Here's an object-oriented package designed to be used as a tool for making document tree structures. It consists of an external javascript file and an external css file. I did this for work and received some advice in the Web Programming and Design forum about how to do this. The advice for using DOM really kicked it off ~_~, and looking at other scripts helped also. I got the OO design from the web and it's worked out very nicely, especially the polymorphism!
At first I was trying to use minimal javascript with css hacks. Although it is possible (custom checkbox images), it is pretty fugly, so I took some tutorials on javascript and actually got to appreciate the language. The way that it can easily manipulate DOM is very powerful. DOM is like "smart html editing," it makes objects out of html tags and lets you dynamically modify them through javascript and other client-side languages.
Oh, and you're going to want some images for open and closed folders and for documents. They're currently expected to be named "open.gif", "closed.gif", and "doc.gif"
The stand-alone package consists of two external scripts, one javascript and one css. The way you use it is pretty intuitive. You create a tree object, add branch objects to the tree, add leaf objects to the branches, and tell the tree to write itself.
doctree.js
// if you want to modify the image source, you don't have to painfully search through the whole script
// just change the variable value here
var openImg = new Image();
openImg.src = 'open.gif';
var closedImg = new Image();
closedImg.src = 'closed.gif';
var docImg = new Image();
docImg.src = 'doc.gif';
// constructor for the tree class
function tree() {
this.branches = new Array();
this.add = addBranch; // I'm using polymorphism
this.write = writeTree; // so that I don't have to worry about
} // which kind of node I am adding or writing
// and can handle all nodes the same
// constructor for the branch class
function branch(text) {
this.id = ''; // id is updated later
this.leaves = new Array();
this.text = text;
this.add = addLeaf;
this.write = writeBranch;
}
// constructor for the leaf class
function leaf(text, link) {
this.id = ''; // id is updated later
this.text = text;
this.link = link;
this.write = writeLeaf;
}
// implementation of branch.add
function addBranch(branch) {
branch.id = 'branch-' + this.branches.length;
this.branches[this.branches.length] = branch;
}
// implementation of leaf.add
function addLeaf(leaf) {
leaf.id = this.id + '-leaf-' + this.leaves.length;
this.leaves[this.leaves.length] = leaf;
}
// implementation of tree.write
function writeTree() {
var treestr = '';
treestr += '<h3>Documents</h3>';
treestr += '<form name="subscription" method="post" action="#">';
treestr += '<input type="submit" value="subscribe"><input type="button" value="reset" onClick="resetCheckboxes()"><br /><br />';
treestr += '<span class="tree">';
for (i in this.branches) {
treestr += this.branches[i].write();
}
treestr += '</span>';
treestr += '</form>';
document.write(treestr);
}
// implementation of branch.write
function writeBranch() {
var branchstr = '<span class="branch">';
branchstr += '<span name="reveal" onClick="handleBranch(\'' + this.id + '\')">';
branchstr += '<img src="' + closedImg.src + '" id="img-' + this.id + '" >' + this.text;
branchstr += '</span>';
branchstr += '<input type="checkbox" id="mcb-' + this.id + '" onClick="handleCheckboxes(\'' + this.id + '\')">';
branchstr += '</span>';
branchstr += '<span class="leaf" id="' + this.id + '">';
for (i in this.leaves) {
branchstr += this.leaves[i].write() + '<br>';
}
branchstr += '</span>';
return branchstr;
}
// implementation of leaf.write
function writeLeaf() {
var leafstr = '';
leafstr += '<a href="#">';
leafstr += '<img src="' + docImg.src + '" border="0">';
leafstr += this.text;
leafstr += '</a>';
leafstr += '<input type="checkbox" id="cb-' + this.id + '">';
return leafstr;
}
/* I use DOM to dynamically interface with the html in javascript
* It creates objects out of html elements and allows me to modify them
* It's sort of like "smart html editing"
* It's used in all the methods below
*/
// This method collapses and uncollapses a branch
function handleBranch(branchid) {
var brstyle = document.getElementById(branchid).style;
swapFolder('img-' + branchid);
// collapse
if (brstyle.display == "block")
brstyle.display = "none";
// uncollapse
else
brstyle.display = "block";
// brstyle.display = (brstyle.display == "none") ? "block" : "none";
}
// This method checks and unchecks the checkboxes of all the leaves in a
// given branch
function handleCheckboxes(branchid) {
var branch = document.getElementById(branchid);
var checkboxes = new Array(), e, i = 0;
var branchCheckbox = document.getElementById('mcb-' + branchid);
// get an array of all the checkboxes that are children of this branch
while (e = document.getElementById(branchid).getElementsByTagName('INPUT')[i++]) {
if (e.type == 'checkbox') {
checkboxes.push(e);
}
}
// check/uncheck all the checkboxes in that array
for (i in checkboxes) {
checkboxes[i].checked = branchCheckbox.checked;
}
}
// This method clears all the checkboxes
function resetCheckboxes() {
var checkboxes = document.getElementsByTagName('INPUT');
for (i in checkboxes)
if (checkboxes[i].type == 'checkbox')
checkboxes[i].checked = false;
}
// This method swaps the folder image to open to closed or vice versa depending // on its current state
function swapFolder(imgid) {
var img = document.getElementById(imgid);
if(img.src.indexOf('closed.gif')>-1)
img.src = openImg.src;
else
img.src = closedImg.src;
//img.src = (img.src == openImg) ? closedImg : openImg;
}
doctree.css
body{
font: 10pt Verdana,sans-serif;
color: navy;
}
.tree {
}
.branch{
cursor: pointer;
cursor: hand;
display: block;
}
.leaf{
display: none;
margin-left: 15px;
}
a{
text-decoration: none;
}
a:hover{
text-decoration: underline;
}
test
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
<html>
<head>
<title>draft</title>
</head>
<frameset cols="15%,85%">
<frame src="dcoui.html" />
</frameset>
</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<head>
<link href="dcoui.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="dcoui.js"></script>
</head>
<body>
<script type="text/javascript">
t = new tree();
b0 = new branch('branch 0');
b1 = new branch('branch 1');
b0.add(new leaf('leaf 0', '#'));
b0.add(new leaf('leaf 1', '#'));
b1.add(new leaf('leaf 0', '#'));
b10 = new branch('branch 0');
b1.add(b10);
b10.add(new leaf('leaf 0'));
b10.add(new leaf('leaf 1'));
t.add(b0);
t.add(b1);
t.write();
</script>
</body>
</html>