First commit

This commit is contained in:
MaddoScientisto 2026-04-07 18:02:17 +02:00
commit cc69770608
1468 changed files with 265316 additions and 128 deletions

View file

@ -0,0 +1,396 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>xTree API (WebFX)</title>
<!-- WebFX Layout Include -->
<script type="text/javascript" src="file:///Z|/work/Fotoeventi/webfxlayout.js"></script>
<!-- end WebFX Layout Includes -->
<style type="text/css">
table {
width: 500px;
}
td {
vertical-align: top;
}
</style>
</head>
<body>
<!-- WebFX Layout Include -->
<script type="text/javascript">
var articleMenu= new WebFXMenu;
articleMenu.left = 384;
articleMenu.top = 86;
articleMenu.width = 140;
articleMenu.add(new WebFXMenuItem("History & Introduction", "index.html"));
articleMenu.add(new WebFXMenuItem("Usage", "usage.html"));
articleMenu.add(new WebFXMenuItem("API", "api.html"));
articleMenu.add(new WebFXMenuItem("Implementation", "implementation.html"));
articleMenu.add(new WebFXMenuItem("Demo", "javascript:window.open('demo.html','demo','scrollbars=yes,status=no,width=500,height=400,resizable=yes'); void(0);"));
articleMenu.add(new WebFXMenuSeparator);
articleMenu.add(new WebFXMenuItem("Download", "http://webfx.eae.net/download/xtree117.zip"));
webfxMenuBar.add(new WebFXMenuButton("Article Menu", null, null, articleMenu));
webfxLayout.writeTitle("xTree API");
webfxLayout.writeMenu();
webfxLayout.writeDesignedByEdger();
</script>
<div class="webfx-main-body">
<!-- end WebFX Layout Includes -->
<h2>WebFXTreeAbstractNode</h2>
<p>
Abstract object with common functions and methods shared by WebFXTree and WebFXTreeItem.
The two of those inherites from this object.
</p>
<h3>Constructor</h3>
<p>Abstract object - no instances of it should be created</p>
<h3>Properties</h3>
<table>
<thead><tr>
<td>Name</td>
<td>Type</td>
<td>Description</td>
</tr></thead>
<tbody>
<tr>
<td>id</td>
<td>Number</td>
<td>Read only property that can be used to find the related HTMLElement. It can also be
used the other way around. If you know the id of the HTMLElement you can get the JS
object by looking in the <code>webFXTreeHandler.all</code> collection.</td>
</tr>
<tr>
<td>text</td>
<td>String</td>
<td>The text label for the node.</td>
</tr>
<tr>
<td>action</td>
<td>String</td>
<td>The action (uri) associated with the node.</td>
</tr>
<tr>
<td>open</td>
<td>Boolean</td>
<td>Read only. Boolean property that tells if the node is expanded or collapsed (will always return false if there are no child nodes).</td>
</tr>
<tr>
<td>icon</td>
<td>String</td>
<td>Image file to use as icon. Uses default if not specified.</td>
</tr>
<tr>
<td>openIcon</td>
<td>String</td>
<td>Image file to use as the open icon (if child nodes only). Uses default if not specified.</td>
</tr>
<tr>
<td>parentNode</td>
<td>Reference</td>
<td>A reference to the parent node.</td>
</tr>
<tr>
<td>childNodes</td>
<td>Array</td>
<td>Collection of references to all child nodes.</td>
</tr>
</tbody>
</table>
<h3>Methods</h3>
<table>
<thead><tr>
<td>Name</td>
<td>Returns</td>
<td>Description</td>
</tr></thead>
<tbody>
<tr>
<td>add(oNode, [bNoIdent])</td>
<td>Reference</td>
<td>
Adds a tree item to the current item. This method takes two argument, the first
is the WebFXTreeItem object to add and the second is an optional boolean value,
that if specified and set to true will prevent the tree from executing the indent
method automatically once the node has been added. This parameter has no effect
on calls to the add method before the tree is rendered, but settings this flag
when adding nodes after the tree has been rendered will greatly reduce the time
needed to complete the operation, this can be quite useful while adding more
than one node at a time, but requires that the indent method is manually executed
on the top most node affected by the changes afterwards.
Returns a reference to the added node.</td>
</tr>
<tr>
<td>indent()</td>
<td>Void</td>
<td>Redraws the traces between nodes and makes sure the tree is properly layed out.</td>
</tr>
<tr>
<td>toggle()</td>
<td>Void</td>
<td>Toggles the expand/collapse.</td>
</tr>
<tr>
<td>expand()</td>
<td>Void</td>
<td>Expands the tree item.</td>
</tr>
<tr>
<td>collapse()</td>
<td>Void</td>
<td>Collapses the tree item.</td>
</tr>
<tr>
<td>expandAll()</td>
<td>Void</td>
<td>Expands the tree item and all sub items recursively.</td>
</tr>
<tr>
<td>collapseAll()</td>
<td>Void</td>
<td>Collapses the tree root and all sub items recursively.</td>
</tr>
<tr>
<td>expandChildren()</td>
<td>Void</td>
<td>Expands all sub items recursively (same as executing expandAll and the collapse).</td>
</tr>
<tr>
<td>collapseChildren()</td>
<td>Void</td>
<td>Collapses all sub items recursively (same as executing collapseAll and the expand).</td>
</tr>
<tr>
<td>getNextSibling()</td>
<td>Reference</td>
<td>Returns a reference to the next sibling.</td>
</tr>
<tr>
<td><nobr>getPreviousSibling()</nobr></td>
<td>Reference</td>
<td>Returns a reference to the previous sibling.</td>
</tr>
<tr>
<td>toString()</td>
<td>String</td>
<td>Genereates the HTML string needed to render the tree item.</td>
</tr>
</tbody>
</table>
<h2>WebFXTree</h2>
<p>
The WebFXTree object is used to create the actual tree root that can later be populated with tree items.
All properties and methods from the WebFXTreeAbstractNode are inherited.
</p>
<h3>Constructor</h3>
<pre>new WebFXTree([text], [action], [behavior])</pre>
<table>
<thead><tr>
<td>Name</td>
<td>Type</td>
<td>Description</td>
</tr></thead>
<tbody>
<tr>
<td>text</td>
<td>String</td>
<td>Optional. The text label for the tree root.</td>
</tr>
<tr>
<td>action</td>
<td>String</td>
<td>Optional. The action (uri) associated with the tree root.</td>
</tr>
<tr>
<td>behavior</td>
<td>String</td>
<td>Optional. Name of the behavior to use, check the setBehavior() method for details.</td>
</tr>
<tr>
<td>icon</td>
<td>String</td>
<td>Optional. Image to use as the icon.</td>
</tr>
<tr>
<td>openIcon</td>
<td>String</td>
<td>Optional. Image to use as the open icon.</td>
</tr>
</tbody>
</table>
<h3>Properties</h3>
<table>
<thead><tr>
<td>Name</td>
<td>Type</td>
<td>Description</td>
</tr></thead>
<tbody>
<tr>
<td>rendered</td>
<td>Boolean</td>
<td>Flag that indicates whatever or no the tree has been generated and rendered.</td>
</tr>
</tbody>
</table>
<h3>Methods</h3>
<table>
<thead><tr>
<td>Name</td>
<td>Returns</td>
<td>Description</td>
</tr></thead>
<tbody>
<tr>
<tr>
<td>getSelected()</td>
<td>Reference</td>
<td>Returns the id of the selected object, if any.</td>
</tr>
<tr>
<td><nobr>setBehavior(sBehavior)</nobr></td>
<td>Void</td>
<td>
Has to be specified before the tree is created and can be used to change the way the tree behaves,
possible values are <i>classic</i> (default) and <i>explorer</i>. Check the usage page for more
information about this.
</td>
</tr>
<tr>
<td>getBehavior()</td>
<td>String</td>
<td>Returns the name of the behavior used.</td>
</tr>
</tbody>
</table>
<h2>WebFXTreeItem</h2>
<p>
Used to create tree items, can be added (uisng the add method) to a WebFXTree or to another
WebFXTreeItem object.
All properties and methods from the WebFXTreeAbstractNode are inherited.
</p>
<h3>Constructor</h3>
<pre>new WebFXTreeItem([text], [action], [parent], [icon], [openIcon])</pre>
<table>
<thead><tr>
<td>Name</td>
<td>Type</td>
<td>Description</td>
</tr></thead>
<tbody>
<tr>
<td>text</td>
<td>String</td>
<td>Optional. The text label for the tree item.</td>
</tr>
<tr>
<td>action</td>
<td>String</td>
<td>Optional. The action (uri) associated with the tree item.</td>
</tr>
<tr>
<td>parent</td>
<td>Reference</td>
<td>Optional. Reference to an object to witch the node should be added.</td>
</tr>
<tr>
<td>icon</td>
<td>String</td>
<td>Optional. Image to use as the icon.</td>
</tr>
<tr>
<td>openIcon</td>
<td>String</td>
<td>Optional. Image to use as the open icon.</td>
</tr>
</tbody>
</table>
<h3>Properties</h3>
<table>
<thead><tr>
<td>Name</td>
<td>Type</td>
<td>Description</td>
</tr></thead>
<tbody>
<tr>
<tr>
<td colspan="3">None but the inherited ones</td>
</tr>
</tbody>
</table>
<h3>Methods</h3>
<table>
<thead><tr>
<td>Name</td>
<td>Returns</td>
<td>Description</td>
</tr></thead>
<tbody>
<tr>
<td>getFirst()</td>
<td>Reference</td>
<td>Returns a reference to the first child node, if any.</td>
</tr>
<tr>
<td>getLast()</td>
<td>Reference</td>
<td>Returns a reference to the last child node, if any.</td>
</tr>
</tr>
</tbody>
</table>
<p>
<a href="index.html">History & Introduction</a><br />
<a href="usage.html">Usage</a><br />
<a href="api.html">API</a><br />
<a href="implementation.html">Implementation</a><br />
<a href="javascript:window.open('demo.html','demo','scrollbars=yes,status=no,width=500,height=400,resizable=yes'); void(0);">Demo</a><br />
<a href="http://webfx.eae.net/download/xtree117.zip">Download</a>
</p>
<!-- end webfx-main-body -->
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 540 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 871 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 799 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,94 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title></title>
<!-- The xtree script file -->
<script src="xtree.js"></script>
<!-- Modify this file to change the way the tree looks -->
<link type="text/css" rel="stylesheet" href="xtree.css">
<style>
body { background: white; color: black; }
input { width: 120px; }
</style>
</head>
<body>
<div style="position: absolute; width: 200px; top: 0px; left: 0px; height: 100%; padding: 5px; overflow: auto;">
<!-- js file containing the tree content, edit this file to alter the menu,
the menu will be inserted where this tag is located in the document -->
<script src="tree.js"></script>
</div>
<div style="position: absolute; left: 205px; top: 10px;">
<p>
This tree works just as the one found in the Microsoft Windows Explorer,
expand/collapse a tree item by double click on the icon or by single click
on the plus/minus symbol.<br/>Buttons below bound to the tree root.
</p>
<p>
This is the method thats called when you click on a tree item.<br/>
<input type="button" value="toggle()" onclick="tree.toggle();">
</p>
<p>
Pretty self explaining, expands or collapses the current item.<br/>
<input type="button" value="expand()" onclick="tree.expand();">
<input type="button" value="collapse()" onclick="tree.collapse();">
</p>
<p>
Expands or collapses the current item and all child items (recursive).<br/>
<input type="button" value="expandAll()" onclick="tree.expandAll();">
<input type="button" value="collapseAll()" onclick="tree.collapseAll();">
</p>
<p>
Expands or collapses all child items (recursive) but not the item itself.<br/>
<input type="button" value="expandChildren()" onclick="tree.expandChildren();">
<input type="button" value="collapseChildren()" onclick="tree.collapseChildren();">
</p>
<p>
Returns the id of the selected item (if any)<br/>
<input type="button" value="alert(tree.getSelected().id);" onclick="if (tree.getSelected()) { alert(tree.getSelected().id); }" style="width: 245px;">
</p>
<p>
Add node(s) below selected, or remove the selected node.<br/>
<input type="button" onclick="addNode();" style="width: 80px;" value="Add one" />
<input type="button" onclick="addNodes();" style="width: 80px;" value="Add multiple" />
<input type="button" onclick="delNode();" style="width: 80px;" value="Remove" />
</p>
</div>
</body>
<script>
function addNode() {
if (tree.getSelected()) {
tree.getSelected().add(new WebFXTreeItem('New'));
}
}
function addNodes() {
if (tree.getSelected()) {
var foo = tree.getSelected().add(new WebFXTreeItem('New'));
var bar = foo.add(new WebFXTreeItem('Sub 1'));
var fbr = foo.add(new WebFXTreeItem('Sub 2'));
}
}
function delNode() {
if (tree.getSelected()) {
tree.getSelected().remove();
}
}
</script>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 763 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 795 B

Binary file not shown.

View file

@ -0,0 +1,198 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>xTree API (WebFX)</title>
<!-- WebFX Layout Include -->
<script type="text/javascript" src="file:///Z|/work/Fotoeventi/webfxlayout.js"></script>
<!-- end WebFX Layout Includes -->
<style type="text/css">
table {
width: 500px;
}
td {
vertical-align: top;
}
</style>
</head>
<body>
<!-- WebFX Layout Include -->
<script type="text/javascript">
var articleMenu= new WebFXMenu;
articleMenu.left = 384;
articleMenu.top = 86;
articleMenu.width = 140;
articleMenu.add(new WebFXMenuItem("History & Introduction", "index.html"));
articleMenu.add(new WebFXMenuItem("Usage", "usage.html"));
articleMenu.add(new WebFXMenuItem("API", "api.html"));
articleMenu.add(new WebFXMenuItem("Implementation", "implementation.html"));
articleMenu.add(new WebFXMenuItem("Demo", "javascript:window.open('demo.html','demo','scrollbars=yes,status=no,width=500,height=400,resizable=yes'); void(0);"));
articleMenu.add(new WebFXMenuSeparator);
articleMenu.add(new WebFXMenuItem("Download", "http://webfx.eae.net/download/xtree117.zip"));
webfxMenuBar.add(new WebFXMenuButton("Article Menu", null, null, articleMenu));
webfxLayout.writeTitle("xTree Implementation");
webfxLayout.writeMenu();
webfxLayout.writeDesignedByEdger();
</script>
<div class="webfx-main-body">
<!-- end WebFX Layout Includes -->
<p>
A tree widget is basically a bunch of collapsible containers, when you open a node
all it's child nodes becomes visible, and when you close it they're hidden. The basic
idea is that simple however there are a few things that makes it a bit more complicated.
Below you'll find information about parts of the implementation of this tree widget,
how the generated code looks like and how a few of the methods work. This is not
something you need to read and understand in order to use this widget, however if
you're interested in how this was made and how it works you might find this helpful.
</p>
<h2>Generated Code</h2>
<p>
As described earlier the tree widget uses an object hierarchy implementation to simplify the creation of trees,
however since the browser cannot understand that object hierarchy we are required to convert it into something
that the browser can render, in this case guess what we're using? Yeah you where right, our old buddy html.
Below is the generated html code for a small tree with only three items. Further down this document you'll find
the same code but split up and described.
</p>
<pre>
&lt;div id="webfx-tree-object-0" ondblclick="webFXTreeHandler.toggle(this);" class="webfx-tree-item"&gt;
&lt;img id="webfx-tree-object-0-icon" src="images/openfoldericon.png" onclick="webFXTreeHandler.select(this);"&gt;
&lt;a href="javascript:void(0);" id="webfx-tree-object-0-anchor"&gt;Root&lt;/a&gt;
&lt;/div&gt;
&lt;div id="webfx-tree-object-0-cont" class="webfx-tree-container" style="display: block;"&gt;
&lt;div id="webfx-tree-object-1" class="webfx-tree-item"&gt;
&lt;img id="webfx-tree-object-1-plus" src="images/L.png"&gt;
&lt;img id="webfx-tree-object-1-icon" src="images/new.png" onclick="webFXTreeHandler.select(this);"&gt;
&lt;a href="javascript:void(0);" id="webfx-tree-object-1-anchor"&gt;1&lt;/a&gt;
&lt;/div&gt;
&lt;div id="webfx-tree-object-2" class="webfx-tree-item"&gt;
&lt;img id="webfx-tree-object-2-plus" src="images/L.png"&gt;
&lt;img id="webfx-tree-object-2-icon" src="images/new.png" onclick="webFXTreeHandler.select(this);"&gt;
&lt;a href="javascript:void(0);" id="webfx-tree-object-2-anchor"&gt;2&lt;/a&gt;
&lt;/div&gt;
&lt;div id="webfx-tree-object-3" class="webfx-tree-item"&gt;
&lt;img id="webfx-tree-object-3-plus" src="images/L.png"&gt;
&lt;img id="webfx-tree-object-3-icon" src="images/new.png" onclick="webFXTreeHandler.select(this);"&gt;
&lt;a href="javascript:void(0);" id="webfx-tree-object-3-anchor"&gt;3&lt;/a&gt;
&lt;/div&gt;
&lt;/div&gt;
</pre>
<h3>WebFXTree Object</h3>
<p>
The code below is what is generated from the WebFXTree Object (it will however also contain the code from all tree items
but to increase the readability that code has been removed).
</p>
<pre>
&lt;div id="webfx-tree-object-0" ondblclick="webFXTreeHandler.toggle(this);" class="webfx-tree-item"&gt;
&lt;img id="webfx-tree-object-0-icon" src="images/openfoldericon.png" onclick="webFXTreeHandler.select(this);"&gt;
&lt;a href="javascript:void(0);" id="webfx-tree-object-0-anchor"&gt;Root&lt;/a&gt;
&lt;/div&gt;
&lt;div id="webfx-tree-object-0-cont" class="webfx-tree-container" style="display: block;"&gt;
<font color="teal">&lt;!-- This is where the Tree Item's will be inserted --&gt;</font>
&lt;/div&gt;
</pre>
<p>
The first div contains the top level icon and label while the secund div is the container that will house the tree items.
When the first div is double clicked the display property of the secund one will be toggled.
</p>
<h3>WebFXTreeItem</h3>
<p>
The code below is what is generated from a singel WebFXTreeItem Object.
</p>
<pre>
&lt;div id="webfx-tree-object-1" class="webfx-tree-item"&gt;
&lt;img id="webfx-tree-object-1-plus" src="images/L.png"&gt;
&lt;img id="webfx-tree-object-1-icon" src="images/new.png" onclick="webFXTreeHandler.select(this);"&gt;
&lt;a href="javascript:void(0);" id="webfx-tree-object-1-anchor"&gt;1&lt;/a&gt;
&lt;/div&gt;
</pre>
<p>
As you can see the code generated by each WebFXTreeItem looks pretty much the same as the one for the WebFXTree object, the
main difference is the extra image(s) that the tree items has (the plus/minus and track icons). Also note that the code
shown above is from a tree item without children. If the tree item has children an extra div to contain those will be added
(much like the secund div generated by the WebFXTree Object).
</p>
<h2>Expanding/Collapsing</h2>
<p>
The most important methods for this widget are expand and collapse. Here I'll try to describe how those works. As the html
code above showed <code>webFXTreeHandler.toggle(this);</code> is executed once a tree item is clicked. The tree handler
then uses an internal reference, <code>webFXTreeHandler.all</code> to look up the object for the clicked tree item. Once
the object has been found it executes the <code>toggle()</code> method on that
object.
</p>
<p>
Below is the code for the toggle method and as you can see all it does is to check whatever or not the item is currently
expanded or collapsed, and then calls the appropriated method (expand if it's collapsed or collapse if it's expanded).
</p>
<pre>
WebFXTreeItem.prototype.toggle = function () {
if (this.open) { this.collapse(); }
else { this.expand(); }
}
</pre>
<p>
Since the expand and collapse methods works pretty much the same I'll only describe one of them, the expand method.
</p>
<pre>
WebFXTreeItem.prototype.expand = function () {
if (!this._subItems.length > 0) { return; }
document.getElementById(this.id + '-cont').style.display = 'block';
document.getElementById(this.id + '-icon').src = openFolderIcon;
document.getElementById(this.id + '-plus').src = this.minusIcon;
this.open = true;
setCookie(this.id.substr(18,this.id.length - 18), '1');
}
</pre>
<p>
The first line of code checks to see if there are any children, since it doesn't do any good to expand it unless
there are. The next line is the most important one and does the expanding by changing the display mode of the div
containing all children to block. The next two lines changes the icon and the plus/minus sign, then the <code>open</code>
property is changed to reflect the expanded/collpased state and finally it sets a cookie (used to keep track of what's
expanded or not so that the tree can be restored to it's previous state the next time you visit the site).
</p>
<p>
<a href="index.html">History & Introduction</a><br />
<a href="usage.html">Usage</a><br />
<a href="api.html">API</a><br />
<a href="implementation.html">Implementation</a><br />
<a href="javascript:window.open('demo.html','demo','scrollbars=yes,status=no,width=500,height=400,resizable=yes'); void(0);">Demo</a><br />
<a href="http://webfx.eae.net/download/xtree117.zip">Download</a>
</p>
<!-- end webfx-main-body -->
</div>
</body>
</html>

View file

@ -0,0 +1,129 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>xTree (WebFX)</title>
<!-- WebFX Layout Include -->
<script type="text/javascript" src="file:///Z|/work/Fotoeventi/webfxlayout.js"></script>
<!-- end WebFX Layout Includes -->
<style type="text/css">
table {
width: 500px;
}
td {
vertical-align: top;
}
</style>
</head>
<body>
<!-- WebFX Layout Include -->
<script type="text/javascript">
var articleMenu= new WebFXMenu;
articleMenu.left = 384;
articleMenu.top = 86;
articleMenu.width = 140;
articleMenu.add(new WebFXMenuItem("History & Introduction", "index.html"));
articleMenu.add(new WebFXMenuItem("Usage", "usage.html"));
articleMenu.add(new WebFXMenuItem("API", "api.html"));
articleMenu.add(new WebFXMenuItem("Implementation", "implementation.html"));
articleMenu.add(new WebFXMenuItem("Demo", "javascript:window.open('demo.html','demo','scrollbars=yes,status=no,width=500,height=400,resizable=yes'); void(0);"));
articleMenu.add(new WebFXMenuSeparator);
articleMenu.add(new WebFXMenuItem("Download", "http://webfx.eae.net/download/xtree117.zip"));
webfxMenuBar.add(new WebFXMenuButton("Article Menu", null, null, articleMenu));
webfxLayout.writeTitle("xTree");
webfxLayout.writeMenu();
webfxLayout.writeDesignedByEdger();
</script>
<div class="webfx-main-body">
<!-- end WebFX Layout Includes -->
<p>
<span class="date">(2003-03-16)</span> Version 1.17 - Added target property.<br />
<span class="date">(2003-02-15)</span> Version 1.16 - The selected node can now be distinguished even when the tree control loses focus.<br />
<span class="date">(2002-10-29)</span> Version 1.15 - This version is based on 1.13 and fixes the bugs 1.14 were supposed to fix.<br />
<span class="date">(2002-10-23)</span> Version 1.14 - Minor fix for a case where the plus icon used wrong image.<br />
<span class="date">(2002-08-20)</span> Version 1.13 - Added <code>usePersistence</code> flag to allow disable the usage of cookies.<br />
<span class="date">(2002-06-13)</span> Version 1.12 - Various bug fixes.<br />
<span class="date">(2002-01-27)</span> Version 1.11 - Bug fixes and improved mozilla support.<br />
<span class="date">(2001-09-23)</span> Version 1.1 - New features included keyboard navigation (ie) and the ability to add and remove nodes dynamically and some other small tweaks and fixes.<br />
<span class="date">(2001-03-18)</span> Added getSelected and get/setBehavior that can make it behave more like the windows explorer<br>(check usage for more information about it).<br />
<span class="date">(2001-01-10)</span> Original Version Posted.
</p>
<p>
An object based tree widget with persistence using cookies that works in ie5 and mozilla.
</p>
<h2>History</h2>
<p>
Among the first things I created with DHTML was a tree view, that was over four years ago
(spring 1997), since then a lot has happened in the browser market, and also with my skills in
JavaScript and DHTML. Today I give you the third version of this tree view widget. The idea
behind it is the same as in the first version, to emulate the tree widget found in many modern
graphical operation environments, such as Microsoft Windows, and so is the basic idea of how to
accomplish this, to toggle the display property of elements depending on the expanded state of
their parents. However the similarities stop there. Another thing I can mention from a
historical point of view is that this is the first complex script that I have created that
works under two different browsers without the use of browser detection, the same code is
actually used for ie5 and mozilla. :o)
</p>
<h2>Introduction</h2>
<p>
This new version is based on objects, so you do not create the actual html code for the tree
yourself, you create an object (the tree's root folder) and then you add child items to this.
Once you're done adding items the actual html code is generated and inserted into the page.
This makes it very easy to create and update the content of the tree (or to dynamically
generate it). If you've seen Erik's new xMenu you will notice that it's working in similar
way.
</p>
<h3>Persistence</h3>
<p>
This script also features persistence using per session cookies. So now if you go to a page
using this tree widget, expand a few folders and then leave the page again (by following a
link or by typing a new url manually) it will store the state of each folder in a cookie so
when you go back to the page it will remember what folders you last had opened and open them
for you. This could be very useful if you use this for site navigation etc.
</p>
<h3>Limitations</h3>
<p>
The persistence functionality is using the node creation order to remember the state of each node,
this works fine for static trees, but not for dynamic ones since adding and/or deleting
nodes will change the original order numbering.
</p>
<p>
<a href="index.html">History & Introduction</a><br />
<a href="usage.html">Usage</a><br />
<a href="api.html">API</a><br />
<a href="implementation.html">Implementation</a><br />
<a href="javascript:window.open('demo.html','demo','scrollbars=yes,status=no,width=500,height=400,resizable=yes'); void(0);">Demo</a><br />
<a href="http://webfx.eae.net/download/xtree117.zip">Download</a>
</p>
<p class="author">Author: Emil A Eklund</p>
<!-- end webfx-main-body -->
</div>
</body>
</html>

View file

@ -0,0 +1,35 @@
if (document.getElementById) {
var tree = new WebFXTree('Root');
tree.setBehavior('classic');
var a = new WebFXTreeItem('1');
tree.add(a);
var b = new WebFXTreeItem('1.1');
a.add(b);
b.add(new WebFXTreeItem('1.1.1'));
b.add(new WebFXTreeItem('1.1.2'));
b.add(new WebFXTreeItem('1.1.3'));
var f = new WebFXTreeItem('1.1.4');
b.add(f);
f.add(new WebFXTreeItem('1.1.4.1'));
f.add(new WebFXTreeItem('1.1.4.2'));
f.add(new WebFXTreeItem('1.1.4.3'));
var c = new WebFXTreeItem('1.2');
a.add(c);
c.add(new WebFXTreeItem('1.5.1'));
c.add(new WebFXTreeItem('1.5.2'));
c.add(new WebFXTreeItem('1.5.3'));
a.add(new WebFXTreeItem('1.3'));
a.add(new WebFXTreeItem('1.4'));
a.add(new WebFXTreeItem('1.5'));
var d = new WebFXTreeItem('2');
tree.add(d);
var e = new WebFXTreeItem('2.1');
d.add(e);
e.add(new WebFXTreeItem('2.1.1'));
e.add(new WebFXTreeItem('2.1.2'));
e.add(new WebFXTreeItem('2.1.3'));
d.add(new WebFXTreeItem('2.2'));
d.add(new WebFXTreeItem('2.3'));
d.add(new WebFXTreeItem('2.4'));
document.write(tree);
}

View file

@ -0,0 +1,177 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>xTree Usage (WebFX)</title>
<!-- WebFX Layout Include -->
<script type="text/javascript" src="file:///Z|/work/Fotoeventi/webfxlayout.js"></script>
<!-- end WebFX Layout Includes -->
<style type="text/css">
table {
width: 500px;
}
td {
vertical-align: top;
}
</style>
</head>
<body>
<!-- WebFX Layout Include -->
<script type="text/javascript">
var articleMenu= new WebFXMenu;
articleMenu.left = 384;
articleMenu.top = 86;
articleMenu.width = 140;
articleMenu.add(new WebFXMenuItem("History & Introduction", "index.html"));
articleMenu.add(new WebFXMenuItem("Usage", "usage.html"));
articleMenu.add(new WebFXMenuItem("API", "api.html"));
articleMenu.add(new WebFXMenuItem("Implementation", "implementation.html"));
articleMenu.add(new WebFXMenuItem("Demo", "javascript:window.open('demo.html','demo','scrollbars=yes,status=no,width=500,height=400,resizable=yes'); void(0);"));
articleMenu.add(new WebFXMenuSeparator);
articleMenu.add(new WebFXMenuItem("Download", "http://webfx.eae.net/download/xtree117.zip"));
webfxMenuBar.add(new WebFXMenuButton("Article Menu", null, null, articleMenu));
webfxLayout.writeTitle("xTree Usage");
webfxLayout.writeMenu();
webfxLayout.writeDesignedByEdger();
</script>
<div class="webfx-main-body">
<!-- end WebFX Layout Includes -->
<p>
This tree widget is based on objects and all html code is generated from a js structure. To create a tree
you won't have to write a single line of html however you will have to learn how to to create the tree and
treeItem objects.
</p>
<h2>Usage</h2>
<p>
The tree(s) needs to be create during the initial load phase of the page. This is accomplished by creating a
<code>WebFXTree</code> object and then add <code>WebFXTreeItem</code>s to it. Once all items has been added
<code>document.write</code> is used to generate the html code and insert it into the page.
</p>
<img src="article-images/tree1.png" align="left">
<pre style="margin-left: 82px;">
var tree = new WebFXTree('Root');
tree.add(new WebFXTreeItem('Tree Item 1'));
tree.add(new WebFXTreeItem('Tree Item 2'));
tree.add(new WebFXTreeItem('Tree Item 3'));
document.write(tree);
</pre>
<h3>Folders</h3>
<p>
A folder is created by adding a new tree item to a already created tree item. However since we need to keep
a reference to this tree item object (so that we can add tree items to it, and make it a folder) we cannot
create the new object inside the add method. So instead we first create the new tree item object and then
we add it to the tree.
</p>
<img src="article-images/tree2.png" align="left">
<pre style="margin-left: 82px;">
var tree = new WebFXTree('Root');
<font color="teal">/* Add tree item to tree */</font>
tree.add(new WebFXTreeItem('1'));
<font color="teal">/* Create a new folder and add it to tree */</font>
var folder = new WebFXTreeItem('2')
tree.add(folder);
<font color="teal">/* Add tree items to folder */</font>
folder.add(new WebFXTreeItem('2.1'));
folder.add(new WebFXTreeItem('2.2'));
folder.add(new WebFXTreeItem('2.3'));
<font color="teal">/* Add another tree item to tree */</font>
tree.add(new WebFXTreeItem('3'));
document.write(tree);
</pre>
<h3>Explorer behavior</h3>
<p>
Since I first published this tree control I've been getting a lot of requesters about making it contain
only folders. So I added a setBehavior method to it. The example below is an exact copy of the one above,
with the one exception that this uses <code>tree.setBehavior('explorer');</code>
</p>
<img src="article-images/tree3.png" align="left">
<pre style="margin-left: 82px;">
var tree = new WebFXTree('Root');
<font color="teal">/* Change the behavior of the tree */</font>
tree.setBehavior('explorer');
<font color="teal">/* Add tree item to tree */</font>
tree.add(new WebFXTreeItem('1'));
<font color="teal">/* Create a new folder and add it to tree */</font>
var folder = new WebFXTreeItem('2')
tree.add(folder);
<font color="teal">/* Add tree items to folder */</font>
folder.add(new WebFXTreeItem('2.1'));
folder.add(new WebFXTreeItem('2.2'));
folder.add(new WebFXTreeItem('2.3'));
<font color="teal">/* Add another tree item to tree */</font>
tree.add(new WebFXTreeItem('3'));
document.write(tree);
</pre>
<h3>Custom Icons</h3>
<p>
Some times you might want to combine the two styles, or make some of the folders/items have a different
icon than the default. To achieve that set the <code>object.icon</code> property to an uri, or to a javascript
variable containing one. To change the open icons for folders use <code>object.openIcon</code>.
</p>
<img src="article-images/tree4.png" align="left">
<pre style="margin-left: 82px;">
var tree = new WebFXTree('Root');
tree.setBehavior('explorer');
tree.icon = 'http://webfx.eae.net/images/notepad.gif';
tree.add(new WebFXTreeItem('1'));
var folder = new WebFXTreeItem('2')
tree.add(folder);
var t21 = new WebFXTreeItem('2.1');
<font color="teal">/* Change the icon */</font>
t21.icon = webFXTreeConfig.fileIcon;
folder.add(t21);
var t22 = new WebFXTreeItem('2.2');
<font color="teal">/* Change the icon */</font>
t22.icon = webFXTreeConfig.fileIcon;
folder.add(t22);
var t23 = new WebFXTreeItem('2.3');
<font color="teal">/* Change the icon */</font>
t23.icon = webFXTreeConfig.fileIcon;
folder.add(t23);
tree.add(new WebFXTreeItem('3'));
document.write(tree);
</pre>
<p>
<a href="index.html">History & Introduction</a><br />
<a href="usage.html">Usage</a><br />
<a href="api.html">API</a><br />
<a href="implementation.html">Implementation</a><br />
<a href="javascript:window.open('demo.html','demo','scrollbars=yes,status=no,width=500,height=400,resizable=yes'); void(0);">Demo</a><br />
<a href="http://webfx.eae.net/download/xtree117.zip">Download</a>
</p>
<!-- end webfx-main-body -->
</div>
</body>
</html>

View file

@ -0,0 +1,90 @@
/*
* Sub class that adds a check box in front of the tree item icon
*
* Created by Erik Arvidsson (http://webfx.eae.net/contact.html#erik)
*
* Disclaimer: This is not any official WebFX component. It was created due to
* demand and is just a quick and dirty implementation. If you are
* interested in this functionality the contact us
* http://webfx.eae.net/contact.html
*
* Notice that you'll need to add a css rule the sets the size of the input box.
* Something like this will do fairly good in both Moz and IE
*
* input.tree-check-box {
* width: auto;
* margin: 0;
* padding: 0;
* height: 14px;
* vertical-align: middle;
* }
*
*/
function WebFXCheckBoxTreeItem(sText, sAction, bChecked, eParent, sIcon, sOpenIcon) {
this.base = WebFXTreeItem;
this.base(sText, sAction, eParent, sIcon, sOpenIcon);
this._checked = bChecked;
}
WebFXCheckBoxTreeItem.prototype = new WebFXTreeItem;
WebFXCheckBoxTreeItem.prototype.toString = function (nItem, nItemCount) {
var foo = this.parentNode;
var indent = '';
if (nItem + 1 == nItemCount) { this.parentNode._last = true; }
var i = 0;
while (foo.parentNode) {
foo = foo.parentNode;
indent = "<img id=\"" + this.id + "-indent-" + i + "\" src=\"" + ((foo._last)?webFXTreeConfig.blankIcon:webFXTreeConfig.iIcon) + "\">" + indent;
i++;
}
this._level = i;
if (this.childNodes.length) { this.folder = 1; }
else { this.open = false; }
if ((this.folder) || (webFXTreeHandler.behavior != 'classic')) {
if (!this.icon) { this.icon = webFXTreeConfig.folderIcon; }
if (!this.openIcon) { this.openIcon = webFXTreeConfig.openFolderIcon; }
}
else if (!this.icon) { this.icon = webFXTreeConfig.fileIcon; }
var label = this.text.replace(/</g, '&lt;').replace(/>/g, '&gt;');
var str = "<div id=\"" + this.id + "\" ondblclick=\"webFXTreeHandler.toggle(this);\" class=\"webfx-tree-item\" onkeydown=\"return webFXTreeHandler.keydown(this, event)\">";
str += indent;
str += "<img id=\"" + this.id + "-plus\" src=\"" + ((this.folder)?((this.open)?((this.parentNode._last)?webFXTreeConfig.lMinusIcon:webFXTreeConfig.tMinusIcon):((this.parentNode._last)?webFXTreeConfig.lPlusIcon:webFXTreeConfig.tPlusIcon)):((this.parentNode._last)?webFXTreeConfig.lIcon:webFXTreeConfig.tIcon)) + "\" onclick=\"webFXTreeHandler.toggle(this);\">"
// insert check box
str += "<input type=\"checkbox\"" +
" class=\"tree-check-box\"" +
(this._checked ? " checked=\"checked\"" : "") +
" onclick=\"webFXTreeHandler.all[this.parentNode.id].setChecked(this.checked)\"" +
" />";
// end insert checkbox
str += "<img id=\"" + this.id + "-icon\" class=\"webfx-tree-icon\" src=\"" + ((webFXTreeHandler.behavior == 'classic' && this.open)?this.openIcon:this.icon) + "\" onclick=\"webFXTreeHandler.select(this);\"><a href=\"" + this.action + "\" id=\"" + this.id + "-anchor\" onfocus=\"webFXTreeHandler.focus(this);\" onblur=\"webFXTreeHandler.blur(this);\">" + label + "</a></div>";
str += "<div id=\"" + this.id + "-cont\" class=\"webfx-tree-container\" style=\"display: " + ((this.open)?'block':'none') + ";\">";
for (var i = 0; i < this.childNodes.length; i++) {
str += this.childNodes[i].toString(i,this.childNodes.length);
}
str += "</div>";
this.plusIcon = ((this.parentNode._last)?webFXTreeConfig.lPlusIcon:webFXTreeConfig.tPlusIcon);
this.minusIcon = ((this.parentNode._last)?webFXTreeConfig.lMinusIcon:webFXTreeConfig.tMinusIcon);
return str;
}
WebFXCheckBoxTreeItem.prototype.getChecked = function () {
var divEl = document.getElementById(this.id);
var inputEl = divEl.getElementsByTagName("INPUT")[0];
return this._checked = inputEl.checked;
};
WebFXCheckBoxTreeItem.prototype.setChecked = function (bChecked) {
if (bChecked != this.getChecked()) {
var divEl = document.getElementById(this.id);
var inputEl = divEl.getElementsByTagName("INPUT")[0];
this._checked = inputEl.checked = bChecked;
if (typeof this.onchange == "function")
this.onchange();
}
};

View file

@ -0,0 +1,59 @@
.webfx-tree-container {
margin: 0px;
padding: 0px;
font: icon;
white-space: nowrap;
}
.webfx-tree-item {
padding: 0px;
margin: -4px;
color: #FFFFFF;
white-space: nowrap;
font-family: icon;
}
.webfx-tree-item a, .webfx-tree-item a:active, .webfx-tree-item a:hover {
margin-left: 3px;
padding: 0 2px 2px 2px;
}
.webfx-tree-item a {
color: #FFFF00;
text-decoration: none;
}
.webfx-tree-item a:hover {
color: #FFFF33;
}
.webfx-tree-item a:active {
background: highlight;
color: #FFFF00;
text-decoration: none;
}
.webfx-tree-item img {
vertical-align: middle;
border: 0px;
}
.webfx-tree-icon {
width: 16px;
height: 16px;
}
.webfx-tree-item a.selected {
color: selectedtext;
background: selected;
}
.webfx-tree-item a.selected-inactive {
color: windowtext;
background: buttonface;
}

View file

@ -0,0 +1,541 @@
/*----------------------------------------------------------------------------\
| Cross Browser Tree Widget 1.17 |
|-----------------------------------------------------------------------------|
| Created by Emil A Eklund |
| (http://webfx.eae.net/contact.html#emil) |
| For WebFX (http://webfx.eae.net/) |
|-----------------------------------------------------------------------------|
| An object based tree widget, emulating the one found in microsoft windows, |
| with persistence using cookies. Works in IE 5+, Mozilla and konqueror 3. |
|-----------------------------------------------------------------------------|
| Copyright (c) 1999 - 2002 Emil A Eklund |
|-----------------------------------------------------------------------------|
| This software is provided "as is", without warranty of any kind, express or |
| implied, including but not limited to the warranties of merchantability, |
| fitness for a particular purpose and noninfringement. In no event shall the |
| authors or copyright holders be liable for any claim, damages or other |
| liability, whether in an action of contract, tort or otherwise, arising |
| from, out of or in connection with the software or the use or other |
| dealings in the software. |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| This software is available under the three different licenses mentioned |
| below. To use this software you must chose, and qualify, for one of those. |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| The WebFX Non-Commercial License http://webfx.eae.net/license.html |
| Permits anyone the right to use the software in a non-commercial context |
| free of charge. |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| The WebFX Commercial license http://webfx.eae.net/commercial.html |
| Permits the license holder the right to use the software in a commercial |
| context. Such license must be specifically obtained, however it's valid for |
| any number of implementations of the licensed software. |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| GPL - The GNU General Public License http://www.gnu.org/licenses/gpl.txt |
| Permits anyone the right to use and modify the software without limitations |
| as long as proper credits are given and the original and modified source |
| code are included. Requires that the final product, software derivate from |
| the original source or any software utilizing a GPL component, such as |
| this, is also licensed under the GPL license. |
|-----------------------------------------------------------------------------|
| Dependencies: xtree.css (To set up the CSS of the tree classes) |
|-----------------------------------------------------------------------------|
| 2001-01-10 | Original Version Posted. |
| 2001-03-18 | Added getSelected and get/setBehavior that can make it behave |
| | more like windows explorer, check usage for more information. |
| 2001-09-23 | Version 1.1 - New features included keyboard navigation (ie) |
| | and the ability to add and remove nodes dynamically and some |
| | other small tweaks and fixes. |
| 2002-01-27 | Version 1.11 - Bug fixes and improved mozilla support. |
| 2002-06-11 | Version 1.12 - Fixed a bug that prevented the indentation line |
| | from updating correctly under some circumstances. This bug |
| | happened when removing the last item in a subtree and items in |
| | siblings to the remove subtree where not correctly updated. |
| 2002-06-13 | Fixed a few minor bugs cased by the 1.12 bug-fix. |
| 2002-08-20 | Added usePersistence flag to allow disable of cookies. |
| 2002-10-23 | (1.14) Fixed a plus icon issue |
| 2002-10-29 | (1.15) Last changes broke more than they fixed. This version |
| | is based on 1.13 and fixes the bugs 1.14 fixed withou breaking |
| | lots of other things. |
| 2003-02-15 | The selected node can now be made visible even when the tree |
| | control loses focus. It uses a new class declaration in the |
| | css file '.webfx-tree-item a.selected-inactive', by default it |
| | puts a light-gray rectangle around the selected node. |
| 2003-03-16 | Adding target support after lots of lobbying... |
|-----------------------------------------------------------------------------|
| Created 2000-12-11 | All changes are in the log above. | Updated 2003-03-16 |
\----------------------------------------------------------------------------*/
var webFXTreeConfig = {
rootIcon : '../xtree/images/foldericon.png',
openRootIcon : '../xtree/images/openfoldericon.png',
folderIcon : '../xtree/images/foldericon.png',
openFolderIcon : '../xtree/images/openfoldericon.png',
fileIcon : '../xtree/images/list.gif',
iIcon : '../xtree/images/I.png',
lIcon : '../xtree/images/L.png',
lMinusIcon : '../xtree/images/Lminus.png',
lPlusIcon : '../xtree/images/Lplus.png',
tIcon : '../xtree/images/T.png',
tMinusIcon : '../xtree/images/Tminus.png',
tPlusIcon : '../xtree/images/Tplus.png',
blankIcon : '../xtree/images/blank.png',
defaultText : 'Tree Item',
defaultAction : 'javascript:void(0);',
defaultBehavior : 'classic',
usePersistence : true
};
var webFXTreeHandler = {
idCounter : 0,
idPrefix : "webfx-tree-object-",
all : {},
behavior : null,
selected : null,
onSelect : null, /* should be part of tree, not handler */
getId : function() { return this.idPrefix + this.idCounter++; },
toggle : function (oItem) { this.all[oItem.id.replace('-plus','')].toggle(); },
select : function (oItem) { this.all[oItem.id.replace('-icon','')].select(); },
focus : function (oItem) { this.all[oItem.id.replace('-anchor','')].focus(); },
blur : function (oItem) { this.all[oItem.id.replace('-anchor','')].blur(); },
keydown : function (oItem, e) { return this.all[oItem.id].keydown(e.keyCode); },
cookies : new WebFXCookie(),
insertHTMLBeforeEnd : function (oElement, sHTML) {
if (oElement.insertAdjacentHTML != null) {
oElement.insertAdjacentHTML("BeforeEnd", sHTML)
return;
}
var df; // DocumentFragment
var r = oElement.ownerDocument.createRange();
r.selectNodeContents(oElement);
r.collapse(false);
df = r.createContextualFragment(sHTML);
oElement.appendChild(df);
}
};
/*
* WebFXCookie class
*/
function WebFXCookie() {
if (document.cookie.length) { this.cookies = ' ' + document.cookie; }
}
WebFXCookie.prototype.setCookie = function (key, value) {
document.cookie = key + "=" + escape(value);
}
WebFXCookie.prototype.getCookie = function (key) {
if (this.cookies) {
var start = this.cookies.indexOf(' ' + key + '=');
if (start == -1) { return null; }
var end = this.cookies.indexOf(";", start);
if (end == -1) { end = this.cookies.length; }
end -= start;
var cookie = this.cookies.substr(start,end);
return unescape(cookie.substr(cookie.indexOf('=') + 1, cookie.length - cookie.indexOf('=') + 1));
}
else { return null; }
}
/*
* WebFXTreeAbstractNode class
*/
function WebFXTreeAbstractNode(sText, sAction) {
this.childNodes = [];
this.id = webFXTreeHandler.getId();
this.text = sText || webFXTreeConfig.defaultText;
this.action = sAction || webFXTreeConfig.defaultAction;
this._last = false;
webFXTreeHandler.all[this.id] = this;
}
/*
* To speed thing up if you're adding multiple nodes at once (after load)
* use the bNoIdent parameter to prevent automatic re-indentation and call
* the obj.ident() method manually once all nodes has been added.
*/
WebFXTreeAbstractNode.prototype.add = function (node, bNoIdent) {
node.parentNode = this;
this.childNodes[this.childNodes.length] = node;
var root = this;
if (this.childNodes.length >= 2) {
this.childNodes[this.childNodes.length - 2]._last = false;
}
while (root.parentNode) { root = root.parentNode; }
if (root.rendered) {
if (this.childNodes.length >= 2) {
document.getElementById(this.childNodes[this.childNodes.length - 2].id + '-plus').src = ((this.childNodes[this.childNodes.length -2].folder)?((this.childNodes[this.childNodes.length -2].open)?webFXTreeConfig.tMinusIcon:webFXTreeConfig.tPlusIcon):webFXTreeConfig.tIcon);
this.childNodes[this.childNodes.length - 2].plusIcon = webFXTreeConfig.tPlusIcon;
this.childNodes[this.childNodes.length - 2].minusIcon = webFXTreeConfig.tMinusIcon;
this.childNodes[this.childNodes.length - 2]._last = false;
}
this._last = true;
var foo = this;
while (foo.parentNode) {
for (var i = 0; i < foo.parentNode.childNodes.length; i++) {
if (foo.id == foo.parentNode.childNodes[i].id) { break; }
}
if (i == foo.parentNode.childNodes.length - 1) { foo.parentNode._last = true; }
else { foo.parentNode._last = false; }
foo = foo.parentNode;
}
webFXTreeHandler.insertHTMLBeforeEnd(document.getElementById(this.id + '-cont'), node.toString());
if ((!this.folder) && (!this.openIcon)) {
this.icon = webFXTreeConfig.folderIcon;
this.openIcon = webFXTreeConfig.openFolderIcon;
}
if (!this.folder) { this.folder = true; this.collapse(true); }
if (!bNoIdent) { this.indent(); }
}
return node;
}
WebFXTreeAbstractNode.prototype.toggle = function() {
if (this.folder) {
if (this.open) { this.collapse(); }
else { this.expand(); }
} }
WebFXTreeAbstractNode.prototype.select = function() {
document.getElementById(this.id + '-anchor').focus();
}
WebFXTreeAbstractNode.prototype.deSelect = function() {
document.getElementById(this.id + '-anchor').className = '';
webFXTreeHandler.selected = null;
}
WebFXTreeAbstractNode.prototype.focus = function() {
if ((webFXTreeHandler.selected) && (webFXTreeHandler.selected != this)) { webFXTreeHandler.selected.deSelect(); }
webFXTreeHandler.selected = this;
if ((this.openIcon) && (webFXTreeHandler.behavior != 'classic')) { document.getElementById(this.id + '-icon').src = this.openIcon; }
document.getElementById(this.id + '-anchor').className = 'selected';
document.getElementById(this.id + '-anchor').focus();
if (webFXTreeHandler.onSelect) { webFXTreeHandler.onSelect(this); }
}
WebFXTreeAbstractNode.prototype.blur = function() {
if ((this.openIcon) && (webFXTreeHandler.behavior != 'classic')) { document.getElementById(this.id + '-icon').src = this.icon; }
document.getElementById(this.id + '-anchor').className = 'selected-inactive';
}
WebFXTreeAbstractNode.prototype.doExpand = function() {
if (webFXTreeHandler.behavior == 'classic') { document.getElementById(this.id + '-icon').src = this.openIcon; }
if (this.childNodes.length) { document.getElementById(this.id + '-cont').style.display = 'block'; }
this.open = true;
if (webFXTreeConfig.usePersistence) {
webFXTreeHandler.cookies.setCookie(this.id.substr(18,this.id.length - 18), '1');
} }
WebFXTreeAbstractNode.prototype.doCollapse = function() {
if (webFXTreeHandler.behavior == 'classic') { document.getElementById(this.id + '-icon').src = this.icon; }
if (this.childNodes.length) { document.getElementById(this.id + '-cont').style.display = 'none'; }
this.open = false;
if (webFXTreeConfig.usePersistence) {
webFXTreeHandler.cookies.setCookie(this.id.substr(18,this.id.length - 18), '0');
} }
WebFXTreeAbstractNode.prototype.expandAll = function() {
this.expandChildren();
if ((this.folder) && (!this.open)) { this.expand(); }
}
WebFXTreeAbstractNode.prototype.expandChildren = function() {
for (var i = 0; i < this.childNodes.length; i++) {
this.childNodes[i].expandAll();
} }
WebFXTreeAbstractNode.prototype.collapseAll = function() {
this.collapseChildren();
if ((this.folder) && (this.open)) { this.collapse(true); }
}
WebFXTreeAbstractNode.prototype.collapseChildren = function() {
for (var i = 0; i < this.childNodes.length; i++) {
this.childNodes[i].collapseAll();
} }
WebFXTreeAbstractNode.prototype.indent = function(lvl, del, last, level, nodesLeft) {
/*
* Since we only want to modify items one level below ourself,
* and since the rightmost indentation position is occupied by
* the plus icon we set this to -2
*/
if (lvl == null) { lvl = -2; }
var state = 0;
for (var i = this.childNodes.length - 1; i >= 0 ; i--) {
state = this.childNodes[i].indent(lvl + 1, del, last, level);
if (state) { return; }
}
if (del) {
if ((level >= this._level) && (document.getElementById(this.id + '-plus'))) {
if (this.folder) {
document.getElementById(this.id + '-plus').src = (this.open)?webFXTreeConfig.lMinusIcon:webFXTreeConfig.lPlusIcon;
this.plusIcon = webFXTreeConfig.lPlusIcon;
this.minusIcon = webFXTreeConfig.lMinusIcon;
}
else if (nodesLeft) { document.getElementById(this.id + '-plus').src = webFXTreeConfig.lIcon; }
return 1;
} }
var foo = document.getElementById(this.id + '-indent-' + lvl);
if (foo) {
if ((foo._last) || ((del) && (last))) { foo.src = webFXTreeConfig.blankIcon; }
else { foo.src = webFXTreeConfig.iIcon; }
}
return 0;
}
/*
* WebFXTree class
*/
function WebFXTree(sText, sAction, sBehavior, sIcon, sOpenIcon) {
this.base = WebFXTreeAbstractNode;
this.base(sText, sAction);
this.icon = sIcon || webFXTreeConfig.rootIcon;
this.openIcon = sOpenIcon || webFXTreeConfig.openRootIcon;
/* Defaults to open */
if (webFXTreeConfig.usePersistence) {
this.open = (webFXTreeHandler.cookies.getCookie(this.id.substr(18,this.id.length - 18)) == '0')?false:true;
} else { this.open = true; }
this.folder = true;
this.rendered = false;
this.onSelect = null;
if (!webFXTreeHandler.behavior) { webFXTreeHandler.behavior = sBehavior || webFXTreeConfig.defaultBehavior; }
}
WebFXTree.prototype = new WebFXTreeAbstractNode;
WebFXTree.prototype.setBehavior = function (sBehavior) {
webFXTreeHandler.behavior = sBehavior;
};
WebFXTree.prototype.getBehavior = function (sBehavior) {
return webFXTreeHandler.behavior;
};
WebFXTree.prototype.getSelected = function() {
if (webFXTreeHandler.selected) { return webFXTreeHandler.selected; }
else { return null; }
}
WebFXTree.prototype.remove = function() { }
WebFXTree.prototype.expand = function() {
this.doExpand();
}
WebFXTree.prototype.collapse = function(b) {
if (!b) { this.focus(); }
this.doCollapse();
}
WebFXTree.prototype.getFirst = function() {
return null;
}
WebFXTree.prototype.getLast = function() {
return null;
}
WebFXTree.prototype.getNextSibling = function() {
return null;
}
WebFXTree.prototype.getPreviousSibling = function() {
return null;
}
WebFXTree.prototype.keydown = function(key) {
if (key == 39) {
if (!this.open) { this.expand(); }
else if (this.childNodes.length) { this.childNodes[0].select(); }
return false;
}
if (key == 37) { this.collapse(); return false; }
if ((key == 40) && (this.open) && (this.childNodes.length)) { this.childNodes[0].select(); return false; }
return true;
}
WebFXTree.prototype.toString = function() {
var str = "<div id=\"" + this.id + "\" ondblclick=\"webFXTreeHandler.toggle(this);\" class=\"webfx-tree-item\" onkeydown=\"return webFXTreeHandler.keydown(this, event)\">" +
"<img id=\"" + this.id + "-icon\" class=\"webfx-tree-icon\" src=\"" + ((webFXTreeHandler.behavior == 'classic' && this.open)?this.openIcon:this.icon) + "\" onclick=\"webFXTreeHandler.select(this);\">" +
"<a href=\"" + this.action + "\" id=\"" + this.id + "-anchor\" onfocus=\"webFXTreeHandler.focus(this);\" onblur=\"webFXTreeHandler.blur(this);\"" +
(this.target ? " target=\"" + this.target + "\"" : "") +
">" + this.text + "</a></div>" +
"<div id=\"" + this.id + "-cont\" class=\"webfx-tree-container\" style=\"display: " + ((this.open)?'block':'none') + ";\">";
var sb = [];
for (var i = 0; i < this.childNodes.length; i++) {
sb[i] = this.childNodes[i].toString(i, this.childNodes.length);
}
this.rendered = true;
return str + sb.join("") + "</div>";
};
/*
* WebFXTreeItem class
*/
function WebFXTreeItem(sText, sAction, eParent, sIcon, sOpenIcon) {
this.base = WebFXTreeAbstractNode;
this.base(sText, sAction);
/* Defaults to close */
if (webFXTreeConfig.usePersistence) {
this.open = (webFXTreeHandler.cookies.getCookie(this.id.substr(18,this.id.length - 18)) == '1')?true:false;
} else { this.open = false; }
if (sIcon) { this.icon = sIcon; }
if (sOpenIcon) { this.openIcon = sOpenIcon; }
if (eParent) { eParent.add(this); }
}
WebFXTreeItem.prototype = new WebFXTreeAbstractNode;
WebFXTreeItem.prototype.remove = function() {
var iconSrc = document.getElementById(this.id + '-plus').src;
var parentNode = this.parentNode;
var prevSibling = this.getPreviousSibling(true);
var nextSibling = this.getNextSibling(true);
var folder = this.parentNode.folder;
var last = ((nextSibling) && (nextSibling.parentNode) && (nextSibling.parentNode.id == parentNode.id))?false:true;
this.getPreviousSibling().focus();
this._remove();
if (parentNode.childNodes.length == 0) {
document.getElementById(parentNode.id + '-cont').style.display = 'none';
parentNode.doCollapse();
parentNode.folder = false;
parentNode.open = false;
}
if (!nextSibling || last) { parentNode.indent(null, true, last, this._level, parentNode.childNodes.length); }
if ((prevSibling == parentNode) && !(parentNode.childNodes.length)) {
prevSibling.folder = false;
prevSibling.open = false;
iconSrc = document.getElementById(prevSibling.id + '-plus').src;
iconSrc = iconSrc.replace('minus', '').replace('plus', '');
document.getElementById(prevSibling.id + '-plus').src = iconSrc;
document.getElementById(prevSibling.id + '-icon').src = webFXTreeConfig.fileIcon;
}
if (document.getElementById(prevSibling.id + '-plus')) {
if (parentNode == prevSibling.parentNode) {
iconSrc = iconSrc.replace('minus', '').replace('plus', '');
document.getElementById(prevSibling.id + '-plus').src = iconSrc;
} } }
WebFXTreeItem.prototype._remove = function() {
for (var i = this.childNodes.length - 1; i >= 0; i--) {
this.childNodes[i]._remove();
}
for (var i = 0; i < this.parentNode.childNodes.length; i++) {
if (this == this.parentNode.childNodes[i]) {
for (var j = i; j < this.parentNode.childNodes.length; j++) {
this.parentNode.childNodes[j] = this.parentNode.childNodes[j+1];
}
this.parentNode.childNodes.length -= 1;
if (i + 1 == this.parentNode.childNodes.length) { this.parentNode._last = true; }
break;
} }
webFXTreeHandler.all[this.id] = null;
var tmp = document.getElementById(this.id);
if (tmp) { tmp.parentNode.removeChild(tmp); }
tmp = document.getElementById(this.id + '-cont');
if (tmp) { tmp.parentNode.removeChild(tmp); }
}
WebFXTreeItem.prototype.expand = function() {
this.doExpand();
document.getElementById(this.id + '-plus').src = this.minusIcon;
}
WebFXTreeItem.prototype.collapse = function(b) {
if (!b) { this.focus(); }
this.doCollapse();
document.getElementById(this.id + '-plus').src = this.plusIcon;
}
WebFXTreeItem.prototype.getFirst = function() {
return this.childNodes[0];
}
WebFXTreeItem.prototype.getLast = function() {
if (this.childNodes[this.childNodes.length - 1].open) { return this.childNodes[this.childNodes.length - 1].getLast(); }
else { return this.childNodes[this.childNodes.length - 1]; }
}
WebFXTreeItem.prototype.getNextSibling = function() {
for (var i = 0; i < this.parentNode.childNodes.length; i++) {
if (this == this.parentNode.childNodes[i]) { break; }
}
if (++i == this.parentNode.childNodes.length) { return this.parentNode.getNextSibling(); }
else { return this.parentNode.childNodes[i]; }
}
WebFXTreeItem.prototype.getPreviousSibling = function(b) {
for (var i = 0; i < this.parentNode.childNodes.length; i++) {
if (this == this.parentNode.childNodes[i]) { break; }
}
if (i == 0) { return this.parentNode; }
else {
if ((this.parentNode.childNodes[--i].open) || (b && this.parentNode.childNodes[i].folder)) { return this.parentNode.childNodes[i].getLast(); }
else { return this.parentNode.childNodes[i]; }
} }
WebFXTreeItem.prototype.keydown = function(key) {
if ((key == 39) && (this.folder)) {
if (!this.open) { this.expand(); }
else { this.getFirst().select(); }
return false;
}
else if (key == 37) {
if (this.open) { this.collapse(); }
else { this.parentNode.select(); }
return false;
}
else if (key == 40) {
if (this.open) { this.getFirst().select(); }
else {
var sib = this.getNextSibling();
if (sib) { sib.select(); }
}
return false;
}
else if (key == 38) { this.getPreviousSibling().select(); return false; }
return true;
}
WebFXTreeItem.prototype.toString = function (nItem, nItemCount) {
var foo = this.parentNode;
var indent = '';
if (nItem + 1 == nItemCount) { this.parentNode._last = true; }
var i = 0;
while (foo.parentNode) {
foo = foo.parentNode;
indent = "<img id=\"" + this.id + "-indent-" + i + "\" src=\"" + ((foo._last)?webFXTreeConfig.blankIcon:webFXTreeConfig.iIcon) + "\">" + indent;
i++;
}
this._level = i;
if (this.childNodes.length) { this.folder = 1; }
else { this.open = false; }
if ((this.folder) || (webFXTreeHandler.behavior != 'classic')) {
if (!this.icon) { this.icon = webFXTreeConfig.folderIcon; }
if (!this.openIcon) { this.openIcon = webFXTreeConfig.openFolderIcon; }
}
else if (!this.icon) { this.icon = webFXTreeConfig.fileIcon; }
var label = this.text.replace(/</g, '&lt;').replace(/>/g, '&gt;');
var str = "<div id=\"" + this.id + "\" ondblclick=\"webFXTreeHandler.toggle(this);\" class=\"webfx-tree-item\" onkeydown=\"return webFXTreeHandler.keydown(this, event)\">" +
indent +
"<img id=\"" + this.id + "-plus\" src=\"" + ((this.folder)?((this.open)?((this.parentNode._last)?webFXTreeConfig.lMinusIcon:webFXTreeConfig.tMinusIcon):((this.parentNode._last)?webFXTreeConfig.lPlusIcon:webFXTreeConfig.tPlusIcon)):((this.parentNode._last)?webFXTreeConfig.lIcon:webFXTreeConfig.tIcon)) + "\" onclick=\"webFXTreeHandler.toggle(this);\">" +
"<img id=\"" + this.id + "-icon\" class=\"webfx-tree-icon\" src=\"" + ((webFXTreeHandler.behavior == 'classic' && this.open)?this.openIcon:this.icon) + "\" onclick=\"webFXTreeHandler.select(this);\">" +
"<a href=\"" + this.action + "\" id=\"" + this.id + "-anchor\" onfocus=\"webFXTreeHandler.focus(this);\" onblur=\"webFXTreeHandler.blur(this);\"" +
(this.target ? " target=\"" + this.target + "\"" : "") +
">" + label + "</a></div>" +
"<div id=\"" + this.id + "-cont\" class=\"webfx-tree-container\" style=\"display: " + ((this.open)?'block':'none') + ";\">";
var sb = [];
for (var i = 0; i < this.childNodes.length; i++) {
sb[i] = this.childNodes[i].toString(i,this.childNodes.length);
}
this.plusIcon = ((this.parentNode._last)?webFXTreeConfig.lPlusIcon:webFXTreeConfig.tPlusIcon);
this.minusIcon = ((this.parentNode._last)?webFXTreeConfig.lMinusIcon:webFXTreeConfig.tMinusIcon);
return str + sb.join("") + "</div>";
}

View file

@ -0,0 +1,54 @@
.webfx-tree-container {
margin: 0px;
padding: 0px;
font: icon;
white-space: nowrap;
}
.webfx-tree-item {
padding: 0px;
margin: 0px;
font: icon;
color: black;
white-space: nowrap;
}
.webfx-tree-item a, .webfx-tree-item a:active, .webfx-tree-item a:hover {
margin-left: 3px;
padding: 1px 2px 1px 2px;
}
.webfx-tree-item a {
color: black;
text-decoration: none;
}
.webfx-tree-item a:hover {
color: blue;
text-decoration: underline;
}
.webfx-tree-item a:active {
background: highlight;
color: highlighttext;
text-decoration: none;
}
.webfx-tree-item img {
vertical-align: middle;
border: 0px;
}
.webfx-tree-icon {
width: 16px;
height: 16px;
}
.webfx-tree-item a.selected {
color: selectedtext;
background: selected;
}
.webfx-tree-item a.selected-inactive {
color: windowtext;
background: buttonface;
}