|
TreeNavigator - Navigation in a tree structure |
TreeNavigator - Navigation in a tree structure
<head>
<script src="prototype.js"></script>
<script src="Keymap.js"></script>
<script src="Navigator.js"></script>
<link href="Navigator.css" rel="stylesheet" type="text/css">
</head>
<body onload="new GvaScript.TreeNavigator('TN_tree')">
<div id="TN_tree">
<div class="TN_node">
<span class="TN_label">Label 1</span>
<div class="TN_content">
<div class="TN_node">
<span class="TN_label">Label 1.1</span>
<div class="TN_content">
...Content of node 1.1
</div>
</div>
<div class="TN_leaf">
<span class="TN_label">Label 1.2 for leaf</span>
</div>
</div>
</div>
</div>
</body>
Handles navigation in a data tree. The tree description is usual HTML, with some special classes to identify nodes. Nodes can be browsed, closed or opened. All operations take place directly within the tree, not in a separate panel.
To read further chapters of this documentation, use
the arrow keys or the TAB
key. To see the whole page at once (for example for
printing), press the Ctrl-keypad * key.
A tree is a collection of nodes. Each node must have a label element and can have a content element. A node may be either open (its content is visible) or closed (its content is invisible). The label of the node is always visible, if the node itself is visible. Some nodes can be declared as leaves : in that case they have no content and have no open/close operations.
The content of a node may include other nodes, so a whole subtree may become invisible if the parent node is closed. Opening or closing nodes may be controlled by the mouse, by the keyboard, or through the programming interface.
A node's content may also by dynamic, by
specifying TN:contentURL with the URL as value:
<div class="TN_node TN_closed" TN:contentURL="/my/url.html">
<div class="TN_label">Label for dynamic node</div>
</div>
If the user opens that node, the content of the URL will by
dynamically fetched and inserted into the tree. The content then
stays there, but can be forcibly reloaded by hitting the
Ctrl-R key.
The tree can be any HTML block element. It should contain one or
several block elements declared with class TN_node or class
TN_leaf -- usually these are DIV elements. Other HTML elements
may be freely interspersed with nodes, although this usually does not
make much sense for navigability.
Every node must in turn contain an inline element
declared with class TN_label -- usually this is
a SPAN element. If the node is not a leaf, it may
then contain a block element declared
with class TN_content -- usually this is
another DIV element. Both the label and the content
should be direct children of the node element.
At initialisation time, a new SPAN element is automatically inserted before each label, in order to add the +/- navigation buttons.
By default, the navigation buttons inserted on the
left of labels are small icons representing +/- signs.
To show other icons, change the CSS rules about the
TN_button class:
.TN_button {
background-image: url(myIconForOpenNodes.gif);
}
.TN_closed .TN_button {
background-image: url(myIconForClosedNodes.gif);
}
In addition, if you want another icon for illustrating the node's content (like for example an open or closed folder), you can proceed as follows:
span element within the
labels that should have the icon
<span class="TN_label"><span class="specialNode"></span>some label</span>
.specialNode and .TN_closed .specialNode,
as in the example above
Navigation in the tree is either with the mouse or with the keyboard. At any point in time, at most one node is selected : this is the one that receives keyboard events. Hence if the tree has no selected node, no keyboard events are interpreted.
Mousing over a node label adds the class
TN_mouse to that node; the default style for
that class is just to underline the label.
Clicking on a node label selects that node and
fires the Ping event.
Clicking on the square +/- icon on the left of the
label toggles the open/closed status of the node.
keypad +keypad -keypad *keypad /Ctrl-keypad *Ctrl-keypad /TABHOMEENDCtrl-PAGE_UPCtrl-PAGE_DOWNCtrl-RRETURNPing event
Ctrl-1..Ctrl-9
var treeNavigator = new GvaScript.TreeNavigator(
elem,
{opt1:"val1", opt2:"val2", ...}
);
Creates the object that controls navigation in the tree. Arguments are
elemoptionsThe tree navigation object is returned, which may be useful if you later want to act on the tree programmatically (opening or closing nodes).
Unless otherwise specified, the method adds a tab
index to each label (so that the user can jump to the
next label through the TAB key).
The method also registers onfocus,
onblur, onmouseover, onmouseout
and onclick handlers for label elements.
Finally, as already mentioned, a new SPAN element is
automatically inserted before each label.
Available options are:
Which tabIndex will be assigned to node labels. If labels should not participate in tabbing, specify a value of -1 (this is the default).
Setting tabIndex >= 0 is especially useful for structuring
forms in treeNavigator sections : then
the user will be able to smoothly tab from section headers
(i.e. treeNavigator labels) to form fields within these sections.
When tabIndex >= 0, the keymap created for
capturing keyboard events is bound to the
tree element; otherwise it is bound globally to the
document element. So another reason for
using tabbing is when there are several trees on the
same page : otherwise a single keypress would
navigate in all trees simultaneously!
Duration (in milliseconds) of ``flashing'', i.e. visual feedback when a key is pressed in a wrong context, like for example trying to open a node which is already open; default is 200 ms.
Color for ``flashing'', expressed as standard CSS color; default is red.
If true, clicking on a ``+/-'' button next to a label will not only open or close the node, but will also select that node; default is false.
If true, creates the ``+/-'' buttons next to labels; default is true.
Makes sure that the selected is visible in the central area of its offset parent; if not, the parent is scrolled. The percentage is the ratio between the parent height and the margin at which scrolling must occur (default is 20%);
If true (the default), the first node is selected just after constructing the tree navigator.
A keymap object (see Keymap.js). If that option is given, keyboard
handlers are pushed into that keymap; otherwise a new keymap is
created.
If you supply your own keymap, make sure that:
tabIndex
defined and positive).
preventDefault:false and
stopPropagation:false (because when the tree has no selected node,
the tree navigation handlers do not consume events and try to
propagate them further).
Class names for various parts of the tree structure. This should be an inline object, with keys corresponding to the names below, and with values specified either as a single class name or as an array of class names.
Class(es) for node elements (default is TN_node).
A node should contain a label element and a
content element, and should have style
display:block.
Class(es) for leaf elements (default is TN_leaf).
A leaf should contain just a label element.
Class(es) for label elements (default is TN_label).
A label should have style display:inline.
Class(es) for content elements (default is TN_content).
Class(es) for marking closed nodes (default is TN_closed).
Class(es) for marking the selected node (default is TN_selected).
Class(es) added when the mouse hovers over a node
(default is TN_mouse).
Class(es) for buttons added automatically by the tree navigator
(default is TN_button).
Class(es) for the special mode in which closed nodes are nevertheless
displayed
(default is TN_showall).
All methods below take a node element as argument, i.e. are called according to pattern:
treeNavigator.method(node);
open(node)close(node)openAtLevel(elem, level)elem until level
level; closes nodes underneath
openEnclosingNodes(elem)elem (which might by any element on
the page), and opens all nodes found on the way
select(node)null, in which case the tree no longer
has any selected node.
flash(node, duration, color)treeNavigator constructor).
isClosed(node)isVisible(node)display:none).
nextSibling(node)TN_node; this is not equivalent to
node.nextSibling).
previousSibling(node)parentNode(node)firstSubNode(node)lastSubNode(node)lastVisibleSubNode(node)label(node)TN_label.
content(node)TN_content.
nextDisplayedNode(node)previousDisplayedNode(node)enclosingNode(elem)
Manipulations to the tree generate events for which clients can register some handlers, exactly like ordinary HTML events.
Select / Deselecttriggered when a node is marked / unmarked as the
currently selected node. Both events are not
triggered immediately, but only after
selectDelay milliseconds have elapsed :
this is an optimization to avoid too many calls
while the user is navigating quickly through the
nodes; in other words, intermediate nodes
crossed while navigating the tree will not
receive any trigger.
If label selection is associated with
focus (i.e. if tabIndex was not set
to -1), then selection/deselection events
are also triggered when the user switches
to another desktop window.
Open / Closetriggered when a node is opened or closed
BeforeLoadContent / AfterLoadContenttriggered before/after a node's content
is loaded from an URL (throug opening the node,
or hitting the Ctrl-R key) -- see
the section below about dynamic tree
updates).
inspecttriggered when a user calls the inspector for a node (either by hitting the RETURN key or by double-clicking the node's label)
Handlers can access an event structure,
similar to what is passed to ordinary HTML events;
the entries are:
typeSelect, Deselect, Open, etc.)
targetsrcElementtarget
treeNavigator
Event handlers can be registered in several ways:
<div class="TN_node" TN:onOpen="handleOpen(this, treeNavigator)">
The additional attribute is the event name,
prefixed by the constant TN:on; so in
the example above, a hander is registered for
event Open.
The string containing handler code is evaluated in a context where some special variables are predefined:
targetNodethistargetNode)
treeNavigatoreventIf the string just contains the name of a handler function (i.e. without the parentheses), then that function will be called with a single argument, namely the event structure described above. Therefore
<div class="TN_node" TN:onOpen="handleOpen">
is equivalent to
<div class="TN_node" TN:onOpen="handleOpen(event)">
<div id="theTree" TN:onOpen="handleOpen(targetNode, this)">
Handlers can be registered on the tree element,
exactly like for node elements. The only
difference is that this is then bound to
the tree element instead of the target node.
var treeNavigator = new Tree.Navigator('myTree', {onOpen: myOpenHandler});
treeNavigator.onClose = function(event){doSomethingWith(event.target)};
Handlers can be inserted as properties on the
tree navigator object, either through options to
the constructor, or later on through ordinary
property assignments. These properties start
with the constant on followed by the
event name, but without the TN: prefix.
Handlers are called with a single argument,
namely the event structure described above.
treeNavigator.initSubTree(subtree);
Whenever a subtree was added programmatically into the
tree, this method should be called in order to install the
navigation buttons, mouse event handlers and tabbing
behaviour. The initSubTree method expects to find
at least one TN_label element within the
subtree.
This method is called automatically when a subtree
is dynamically fetched through the
TN:contentURL property.
|
TreeNavigator - Navigation in a tree structure |