|
work's fine in internet explorer 8.
thank you.
|
|
|
|
|
|
Thanks, great code, here is in php. Just copy and paste into the two code files. The database named test was exported as sql from phpMyadmin. It's dump is down.
FIRST demo.php:
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft FrontPage 4.0">
<META HTTP-EQUIV="Content-Type" content="text/html; charset=iso-8859-1">
<TITLE>Easy DHTML TreeView dynamic sample</TITLE>
</HEAD>
<BODY>
<?php include("DHTML_TreeView.inc"); ?>
<HR>
<?php
// Init the treeview
InitTreeView();
// Get the topics from the database and draw the treeview
TopicsInTree();
?>
<BR><BR><HR>
<SCRIPT LANGUAGE="JavaScript">
//execute once page has loadded
var aTags = document.getElementsByTagName('A');
for(var n = 0; n < aTags.length; n++)
{
if(aTags[n].onclick.toString().indexOf('Toggle(this)') > 0)
{
Toggle(aTags[n]);
}
}
</SCRIPT>
</BODY>
</HTML>
AND LAST DHTML_TreeView.inc
<?php
function InitTreeView(){
?>
<SCRIPT LANGUAGE="JavaScript">
// ---------------------------------------------
// --- Name: Easy DHTML Treeview --
// --- Author: D.D. de Kerf --
// --- Version: 0.1 Date: 6-6-2001 --
// ---------------------------------------------
function Toggle(node)
{
// Unfold the branch if it isn't visible
if (node.nextSibling.style.display == 'none')
{
// Change the image (if there is an image)
if (node.childNodes.length > 0)
{
if (node.childNodes.item(0).nodeName == "IMG")
{
node.childNodes.item(0).src = "minus.gif";
}
}
node.nextSibling.style.display = 'block';
}
// Collapse the branch if it IS visible
else
{
// Change the image (if there is an image)
if (node.childNodes.length > 0)
{
if (node.childNodes.item(0).nodeName == "IMG")
{
node.childNodes.item(0).src = "plus.gif";
}
}
node.nextSibling.style.display = 'none';
}
}
</SCRIPT>
<?php
} ////////////////
// Helper function for TopicsInTree. This function will be called recursively to load the whole tree from
// the database
function SubTopicsInTree($DBconnection, $topicID, $topic, $depth){
// Query the database for all the direct subtopics of topic topicID
$query = "SELECT topicID, name FROM topic WHERE topicID IN (SELECT subtopicID FROM subtopic WHERE topicID = ".$topicID.") ORDER BY name ASC";
$rsSubtopics = mysql_query($query, $DBconnection);
$la="<FONT FACE='arial' SIZE='".(6-$depth)."'>";
$lc= "</FONT>";
echo "<TABLE BORDER=0><TR>";
// This value (now 10) represents the hoziontal spacing between the branches
//if ($depth > 1)
echo "<TD WIDTH=20></TD>";
// We have another branch. Solve the branch recursively
if(mysql_num_rows($rsSubtopics) > 0){
echo "<TD><A onClick='Toggle(this)'><IMG SRC='minus.gif'> ".$la.$topic.$lc."</A><DIV>";
while ($row = mysql_fetch_array($rsSubtopics)) {
$subtopicID = $row[0];
$subtopic = $row[1];
SubTopicsInTree($DBconnection, $subtopicID, $subtopic, ($depth + 1));
}
// We have a leaf. Simply print the leaf
}else{
echo "<TD><IMG SRC='leaf.gif'> ".$la.$topic.$lc."<DIV>";
}
echo "</DIV></TD></TR></TABLE>";
mysql_free_result($rsSubtopics);
}
// The function that loads the treeview from the database and draws it in HTML
// Connect to the database
function TopicsInTree()
{
$db_host = "localhost";
$db_user = "root";
$db_pass = "";
$db_name = "test";
$connection = mysql_connect($db_host, $db_user, $db_pass) or die ("Unable to connect to DB");
mysql_select_db($db_name, $connection);
// Query the database for topics that are no subtopic (so we'll get only the main topics)
$query = "SELECT topicID, name FROM topic WHERE topicID NOT IN (SELECT subtopicID FROM subtopic) ORDER BY name ASC";
$result = mysql_query($query, $connection);
echo "<TABLE BORDER=0>";
while ($row = mysql_fetch_array($result)) {
echo "<TR><TD>";
$onderwerpID = $row[0];
$onderwerp = $row[1];
// Every main topic is a branch of it's own, so they have to be solved
// recursively
SubTopicsInTree($connection, $onderwerpID, $onderwerp, 1);
echo "</TR></TD>";
}
echo "</TABLE>";
mysql_free_result($result);
mysql_close($connection);
}
?>
database test dump
-- phpMyAdmin SQL Dump
-- version 3.2.1
-- http://www.phpmyadmin.net
--
-- Servidor: localhost
-- Tiempo de generación: 27-01-1980 a las 01:56:53
-- Versión del servidor: 5.1.37
-- Versión de PHP: 5.3.0
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
--
-- Base de datos: `test`
--
CREATE DATABASE `test` DEFAULT CHARACTER SET utf8 COLLATE utf8_spanish_ci;
USE `test`;
-- --------------------------------------------------------
--
-- Estructura de tabla para la tabla `subtopic`
--
CREATE TABLE IF NOT EXISTS `subtopic` (
`topicID` int(11) NOT NULL,
`subtopicID` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci;
--
-- Volcar la base de datos para la tabla `subtopic`
--
INSERT INTO `subtopic` (`topicID`, `subtopicID`) VALUES
(1, 4),
(1, 5),
(1, 6),
(3, 16),
(3, 17),
(3, 18),
(3, 19),
(4, 7),
(4, 8),
(5, 9),
(6, 10),
(6, 11),
(6, 12),
(11, 13),
(11, 14),
(11, 15);
-- --------------------------------------------------------
--
-- Estructura de tabla para la tabla `topic`
--
CREATE TABLE IF NOT EXISTS `topic` (
`topicID` int(11) NOT NULL AUTO_INCREMENT,
`name` text COLLATE utf8_spanish_ci NOT NULL,
`description` longtext COLLATE utf8_spanish_ci NOT NULL,
PRIMARY KEY (`topicID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci AUTO_INCREMENT=20 ;
--
-- Volcar la base de datos para la tabla `topic`
--
INSERT INTO `topic` (`topicID`, `name`, `description`) VALUES
(1, 'Animals', ''),
(2, 'Humans', ''),
(3, 'Plants', ''),
(4, 'Cats', ''),
(5, 'Dogs', ''),
(6, 'Fish', ''),
(7, 'Siamese cat', ''),
(8, 'Street cat', ''),
(9, 'Dalmatian', ''),
(10, 'Goldfish', ''),
(11, 'Killer fish', ''),
(12, 'Salmon', ''),
(13, 'Shark', ''),
(14, 'Piranha', ''),
(15, 'Killer penguin', ''),
(16, 'Apple', ''),
(17, 'Pear', ''),
(18, 'Apricot', ''),
(19, 'Banana', '');
|
|
|
|
|
This is a great treeview!
Has anyone tried to add links (href) to the branches?
I have successfully added HREF to the leafs, but not the branches as there seems to be conflict between href and toggle() as both respond to the onClick event.
Thanks,
Neil
|
|
|
|
|
Hi guys,
The tree is definitely a great control
I have tried using a similar approach to building a tree view in my web site. I'm using it to generate a tree of about 150 nodes. Unfortunately, it takes about 90 seconds (@100% processor usage) to generate the tree. I migrated the database from Access to SQL Server Express and noted an improvement in performance (around 60 - 70 seconds).I would suggest that this is because of the number of database calls that need to be made using the recursive approach.
At the moment, I'm starting to freak, as I don't think that my clients would be happy at waiting a minute for a page to load. I'm guessing that when I move this to a shared hosting environment, that this would slow down even further.
Can anyone else think of a way to populate this tree using (maybe ) a single database call?
Cheers.
|
|
|
|
|
It is not too difficult to request a whole tree of structure in either XML or JSON format (take a look at an example from google: http://code.google.com/webtoolkit/document/examples/jsonrpc/demo.html)
However note that once you get into a lot of nodes in your tree, you may still have performance problems, not from SQL query time, but instead from the time taken for your browser to parse and render a complex DOM.
|
|
|
|
|
we have used this treeview in my project & it's excellent, but i need some help in modifying it. what i need for my project that the user can expand one node at a time. if he moves to another root tree node, the first one expanded will collapse & the second one will expand.
any help please?
Lina Naser
http://www.dotnet-guru.com
|
|
|
|
|
|
Great Work! Apologies for this newbie question, but how can I make Expand All/Collapse All work if the links are in a different frame than the tree itself?
I've learned a lot from looking over your example, but can't seem to get the technique down for multi-frame pages with js to work with it. It's likely I'm missing something simple.
|
|
|
|
|
In the Toggle function replace "children" with "childNodes", as it is on the demo site.
You forgot to modify the zip file to reflect these changes.
|
|
|
|
|
I am trying to setup a mouse following popup box.
The following is the code I am using.
function setDateGetterVis(newStyle) {
var mydiv;
mydiv = eval('document.all.dateGetter.style');
if (newStyle=='block')
{
//set the location at the point of mouse click.
mydiv.left=event.clientX;
mydiv.top=event.clientY;
}
mydiv.display=newStyle;
}
I have found that once the user scrolls the expanded page, the event.clientX coordinates stop where the old bottom of the page was.
Ideally, I would like the floating box to be able to track along with the grow and shrink of the treeview.
Any help would be EXTREMELY appreciated!
Thanks!
atomicfroman
-- coding my way to the next blue screen --
|
|
|
|
|
|
Thanks, really clever coding and lightweight as well.
|
|
|
|
|
Hi
I just wanted to know the performance of the tree,
how much time will it take to construct the tree of 100K nodes?
has anyone tried this?
Regards
Bala
|
|
|
|
|
Yes the performance is really slow. I am constructing around 270 sets on page load which is taking around 23-24 secs of time to load the page. Dont know if we can improve the performance of the Tree formation. But great post. Helped me a lot. Thanks
|
|
|
|
|
Using the treeview, if I invoke a screen, when I navigate back to the treeview, is there a way to bring the navigation path back to where it was just before entering the screen.
Example: When I come back from screen show the treeview something like this.
root
|
|-Node
|-Node
|-Node
|_Node
|_ Screen
|
|
|
|
|
Try using a little javascript to store the ID of the last node expanded in a cookie. Make sure the tree generates each node with the same unique ID value each time it is generated. Then, when the page loads, have a function that checks that cookie value to see if a node should be expanded. Then expand that node and all its parent nodes working up the tree to the top.
That won't get you the entire tree restored, but at least the last point you were looking at.
|
|
|
|
|
I really thank you for this article which, combined with an article about "how to store a tree in a database"[^], saved my life ... well not really my life but almost
It's clear, it's good and it works !!!
Thanks again for your good job
|
|
|
|
|
I admit - I didnt read the article - I see code I go for it.
I also am not one of the insane noise that thinks tables are the devils work - but in this case - they might just have a point
Great code - How do I know? Cause I just modified it in about five minutes - and I never read the article, and never looked at the two functions that do whatever in the original code -
http://sportsforum.ws/tree
|
|
|
|
|
Just a suggestion... Please clean up the HTML code on the sample and repost the files. Although the technique is really neat and great, the code is horrible at best.
|
|
|
|
|
Just want to express thanks for posting such a good article! The coding was clean and simple and it is sufficient for a simple tree view without having to use complex controls or components
Just a note: please put the tags on the next (fresh) line to indicate the end of the tag. Else, somehow, the Javascript will not be able to detect the end of the tag and thus next sibling of the current node!...strange as it is, it's true!
|
|
|
|
|
|
I would like to populate a treeview with the contents of another treeview on which a selection is made. If I could get some help I'd be greatful.
Rachel
|
|
|
|
|
Dear All,
Could someone please tell me how to enable whatever needs enabling in Mozilla 1.6 and Netscape 7.1 to ensure that this treeview sample code actually works?
I checked the following in Netscape 7.1: Edit->Preferences->Advanced->Scripts and Pluggins-> and enabled all javascript. However, nothing happens when I try to toggle a node. I am not familiar with Netscape or Mozilla but from the threads below it seems this treeview should work in Mozilla 1.6.
Thank you very much for your help.
Eva
|
|
|
|
|
I've coded a function that expands and collapses the entire tree. It took a while get it to work, but I thought I'd share it.
First, the top of my page will look like so:
_________________________________________
EXPLORER [+] Expand All
[+] Analysis
[-] Implementation
[-] Visual C++
[ ] Memory Leak Problems
[ ] Database Problems
[+] Design
_________________________________________
The "Explorer [+] Expand All" is created with this code:
<p>
<b>Explorer </b>
<small onclick=Toggle_All()>
<img src="plus.gif">Expand All
</small>
</p>
And the function "Toggle_All()" is as follows:
function Toggle_All() {
var strDisplay = "none";
var strSrc = heading.firstChild.src;
var strText = heading.lastChild.data;
if (strText == "Expand All") {
strDisplay = "";
strSrc = "minus.gif";
strText = "Collapse All";
} else {
strDisplay = "none";
strSrc = "plus.gif";
strText = "Expand All"; }
//------------------------------------------------------//
// Now that we know what to toggle, set the header //
//------------------------------------------------------//
heading.firstChild.src = strSrc;
heading.lastChild.data = strText;
var objTable = heading.parentNode;
while (objTable.tagName != "TABLE") {
var objTable = objTable.nextSibling; }
//------------------------------------------------------//
// Go through every IMG and DIV, and set. //
//------------------------------------------------------//
var objA = objTable.getElementsByTagName('a');
var i=objA.length;
while (i-- > 0) {
var objItem = objA(i);
var objDIV = objItem.nextSibling;
for (j = 0; j < objItem.childNodes.length; j++) {
if (objItem.childNodes[j].tagName == "IMG" ) {
var objIMG = objItem.childNodes[j];
break; }
}
var pos = objIMG.src.lastIndexOf("/") + 1;
var oldSrc = objIMG.src.substring(pos, 99);
if (oldSrc == "plus.gif" || oldSrc == "minus.gif") {
objIMG.src = strSrc;
objDIV.style.display = strDisplay;
}
}
}
You may notice that I loop backwards (from bottom to top) through each "A" tag, setting the IMG and DIV nodes accordingly. You'll find this doesn't work well if you go forwards (from top to bottom).
I also var some variables so as to see their values in Script Debugger. That came in handy.
Hope someone finds this useful.
|
|
|
|
|