Subject: [Pkg-cacti-maint] Bug#702690: cacti: Multilevel tree doesn't work with jstree in 0.8.8a+dfsg-3

From: Stephan Seitz <[email-masked]>
Date: Wed, 27 Mar 2013 10:56:23 +0100

Package: cacti
Version: 0.8.8a+dfsg-3
Followup-For: Bug #702690

Dear Maintainer,

the patch from Jan Zalesak is working for me as well.

Besides that the recommended package libjs-jquery-cookie is not installed 
by the upgrade process, so my tree view was completely broken (the tree 
links didn’t work). Maybe a depends would be better?

Shade and sweet water!

	Stephan

-- System Information:
Debian Release: 7.0
   APT prefers stable-updates
   APT policy: (500, 'stable-updates'), (500, 'testing'), (500, 'stable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 3.8.4-Dom0 (SMP w/2 CPU cores)
Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages cacti depends on:
ii  dbconfig-common                          1.8.47+nmu1
ii  debconf [debconf-2.0]                    1.5.49
ii  libapache2-mod-php5                      5.4.4-14
ii  libphp-adodb                             5.15-1
ii  mysql-client-5.5 [virtual-mysql-client]  5.5.28+dfsg-1
ii  perl                                     5.14.2-20
ii  php5-cli                                 5.4.4-14
ii  php5-mysql                               5.4.4-14
ii  php5-snmp                                5.4.4-14
ii  rrdtool                                  1.4.7-2
ii  snmp                                     5.4.3~dfsg-2.7
ii  ucf                                      3.0025+nmu3

Versions of packages cacti recommends:
ii  apache2                      2.2.22-13
ii  apache2-mpm-prefork [httpd]  2.2.22-13
ii  iputils-ping                 3:20101006-1+b1
ii  libjs-jquery                 1.7.2+dfsg-1
pn  libjs-jquery-cookie          <none>
ii  logrotate                    3.8.1-4
ii  mysql-server                 5.5.28+dfsg-1

Versions of packages cacti suggests:
ii  moreutils  0.47
pn  php5-ldap  <none>

-- debconf information excluded

-- 
| Stephan Seitz          E-Mail: [email-masked] |
| Public Keys: http://fsing.rootsland.net/~stse/keys.html |

---

From: Paul Gevers <[email-masked]>
Date: Wed, 27 Mar 2013 20:45:33 +0100

tags 702690 pending
thanks

> the patch from Jan Zalesak is working for me as well.

Good to hear. I am working on integrating this patch, but it is
completely missing the export functionality, so I have to fix that too.
I finally managed to get a setup where I can reproduce the wrong
behavior, so I can actually check what I am doing. I actually seems I
missed a Debian specific change in the export part for the whole jquery
thing anyway.

> Besides that the recommended package libjs-jquery-cookie is not
> installed by the upgrade process, so my tree view was completely broken
> (the tree links didn’t work). Maybe a depends would be better?

Normally, you should file a seperate bug for such comments, but as I
disagree with your statement it is not needed, see Policy 7.2 [1]:
Recommends
    This declares a strong, but not absolute, dependency.
    The Recommends field should list packages that would be found
    together with this one in all but unusual installations.

Which is exactly the case here. Recommends should be installed on normal
systems. And Cacti still works without the jquery, so recommends in
stead of depends.

Paul

[1]
http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps

---

From: [email-masked] (Debian Bug Tracking System)
Date: Wed, 27 Mar 2013 19:45:19 +0000

> tags 702690 pending
Bug #702690 [cacti] cacti: Multilevel tree doesn't work with jstree in 0.8.8a+dfsg-3
Added tag(s) pending.
> thanks
Stopping processing here.

Please contact me if you need assistance.
-- 
702690: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=702690
Debian Bug Tracking System
Contact [email-masked] with problems

---

From: Paul Gevers <[email-masked]>
Date: Sun, 31 Mar 2013 13:08:19 +0200

For the records.

> completely missing the export functionality, so I have to fix that too.

I created an improved patch (against the tree in the SOURCE) which is
attached to this e-mail. It would be great if people could test with
their setup if it works correctly (if needed I can provide the full
lib/html_tree.php file privately). I changed the patch of Jan slightly
to be more in line with the layout of the rest of the patch and applied
it to lib/graph_export.php.

To have the Debian package working with the system jquery, you also need
the second patch (use_jquery_for_debian.patch).

I will probably upload a fixed cacti somewhere tomorrow, no time anymore
today.

Paul
Description: treeview has a license issue, cacti upstream is going to replace it
 with functionality from jquery.jstree.
 .
 This patch implements the changes needed for an upstream layout where the
 necessary code is in cacti/include/js/jquery/ but the code in that path is
 not included in this patch.
 .
 The necessary jquery scripts and theme info can come from cacti upstream and from
 debian packages (libjs-jquery and libjs-jquery-cookie) The version used when
 creating this patch can be found here:
 http://svn.cacti.net/viewvc/cacti/branches/0.8.9/include/js/jquery/jquery.js?pathrev=7324
 http://svn.cacti.net/viewvc/cacti/branches/0.8.9/include/js/jquery/jquery.jstree.js?pathrev=7324
 http://svn.cacti.net/viewvc/cacti/branches/main/include/js/jquery/themes/default/?pathrev=7324
 http://anonscm.debian.org/gitweb/?p=pkg-javascript/jquery-goodies.git;a=blob;f=cookie/jquery.cookie.js;hb=c50e1a2d599cb48893e8d77470e71e83e44dfdb5
 .
 This patch does NOT implement the changes needed for the Debian package of
 cacti.
 .
 This patch was updated with the patch from Jan Zalesak <[email-masked]> in
 http://bugs.debian.org/702690 which was further improved to also cover
 lib/graph_export.php and to keep tag alignment consistent. 
Bug: http://bugs.cacti.net/view.php?id=2228
Bug-Debian: http://bugs.debian.org/679980
Author: Paul Gevers <[email-masked]>
Date: Sun, 31 Mar 2013 11:59:05 +0200

--- a/include/top_graph_header.php
+++ b/include/top_graph_header.php
@@ -84,8 +84,9 @@
 	<link href="<?php echo $config['url_path']; ?>include/main.css" type="text/css" rel="stylesheet">
 	<link href="<?php echo $config['url_path']; ?>images/favicon.ico" rel="shortcut icon"/>
 	<script type="text/javascript" src="<?php echo $config['url_path']; ?>include/layout.js"></script>
-	<script type="text/javascript" src="<?php echo $config['url_path']; ?>include/treeview/ua.js"></script>
-	<script type="text/javascript" src="<?php echo $config['url_path']; ?>include/treeview/ftiens4.js"></script>
+	<script type="text/javascript" src="<?php echo $config['url_path']; ?>include/js/jquery/jquery.js" language="javascript"></script>
+	<script type="text/javascript" src="<?php echo $config['url_path']; ?>include/js/jquery/jquery.cookie.js" language="javascript"></script>
+	<script type="text/javascript" src="<?php echo $config['url_path']; ?>include/js/jquery/jquery.jstree.js"></script>
 	<script type="text/javascript" src="<?php echo $config['url_path']; ?>include/jscalendar/calendar.js"></script>
 	<script type="text/javascript" src="<?php echo $config['url_path']; ?>include/jscalendar/lang/calendar-en.js"></script>
 	<script type="text/javascript" src="<?php echo $config['url_path']; ?>include/jscalendar/calendar-setup.js"></script>
@@ -178,7 +179,6 @@
 		<td valign="top" style="padding: 5px; border-right: #aaaaaa 1px solid;background-repeat:repeat-y;background-color:#efefef;" bgcolor='#efefef' width='<?php print htmlspecialchars(read_graph_config_option("default_dual_pane_width"));?>' class='noprint'>
 			<table border=0 cellpadding=0 cellspacing=0><tr><td><a style="font-size:7pt;text-decoration:none;color:silver" href="http://www.treemenu.net/" target=_blank></a></td></tr></table>
 			<?php grow_dhtml_trees(); ?>
-			<script type="text/javascript">initializeDocument();</script>
 
 			<?php if (isset($_GET["select_first"])) { ?>
 			<script type="text/javascript">
--- a/lib/graph_export.php
+++ b/lib/graph_export.php
@@ -1365,15 +1365,6 @@
 	/* create the treeview representation for the html data */
 	grow_dhtml_trees_export($fp,$tree_id);
 
-	fwrite($fp,"<script type='text/javascript'>initializeDocument();</script>\n");
-	fwrite($fp,"<script type='text/javascript'>\n");
-	fwrite($fp,"var obj;\n");
-	fwrite($fp,"obj = findObj(1);\n");
-	fwrite($fp,"if (!obj.isOpen) {\n");
-	fwrite($fp,"clickOnNode(1);\n");
-	fwrite($fp,"}\n");
-	fwrite($fp,"clickOnLink(2,'','main');\n");
-	fwrite($fp,"</script>\n");
 	fwrite($fp,"</td>\n");
 	fwrite($fp,"<td valign='top'>\n");
 }
@@ -1383,16 +1374,7 @@
 	include_once($config["library_path"] . "/tree.php");
 	include_once($config["library_path"] . "/data_query.php");
 
-	fwrite($fp, "<script type='text/javascript'>\n");
-	fwrite($fp, "<!--
-			USETEXTLINKS = 1
-			STARTALLOPEN = 0
-			USEFRAMES = 0
-			USEICONS = 0
-			WRAPTEXT = 1
-			ICONPATH = 'treeview/'
-			PERSERVESTATE = 1
-			HIGHLIGHT = 1\n");
+	fwrite($fp, "<div id=\"jtree\">\n");
 
 	if (read_config_option("export_tree_isolation") == "off") {
 		$dhtml_tree_base = 0;
@@ -1413,9 +1395,34 @@
 		}
 	}
 
-	fwrite($fp,"foldersTree.treeID = \"t2\"
-			//-->\n
-			</script>\n");
+	fwrite($fp, "</div>\n");
+	fwrite($fp, "<script type=\"text/javascript\">\n");
+	fwrite($fp, "$(function () {
+	$(\"#jtree\")
+		.jstree({
+                        \"plugins\" : [\"ui\",\"themes\",\"html_data\",\"cookies\"],
+        	        \"themes\" : {\"icons\" : false,
+				\"url\" : \"./js/style.css\"},
+			\"cookies\" : {
+				\"save_opened\" : \"Cacti_jstree_open\",
+				\"save_selected\" : \"Cacti_jstree_select\"
+				}
+
+                })
+
+                // Make sure that the nodes are actually used as links
+                // We need reselect to prevent endless loops
+                // https://groups.google.com/d/topic/jstree/j6XNq9hQdeA/discussion
+                .bind(\"reselect.jstree\", function (e, data) {
+                      data.inst.get_container().bind(\"select_node.jstree\", function (e, data) {
+                           // data.rstl.obj is the object that was selected.
+                           document.location.href = data.rslt.obj.children(\"a\").attr(\"href\");
+                       });
+                });
+
+});\n");
+	fwrite($fp, "</script>\n");
+
 }
 
 /* get_graph_tree_array_export - returns a list of graph trees taking permissions into account if
@@ -1478,8 +1485,7 @@
 	$dhtml_tree = array();
 	$dhtml_tree[0] = $start;
 	$dhtml_tree[1] = read_graph_config_option("expand_hosts");
-	$dhtml_tree[2] = "foldersTree = gFld(\"\", \"\")\n";
-	$i = 2;
+	$i = 1;
 
 	$tree_list = get_graph_tree_array_export();
 
@@ -1499,7 +1505,6 @@
 		if (((read_config_option("export_tree_isolation") == "on") && ($tree_id == $tree["id"])) ||
 			(read_config_option("export_tree_isolation") == "off")) {
 
-			$i++;
 
 			$hier_sql = "SELECT DISTINCT
 					graph_tree_items.id,
@@ -1522,19 +1527,53 @@
 			$dhtml_tree_id = 0;
 
 			if (sizeof($hierarchy) > 0) {
+				$last_tier = 1;
+				$openli = false;
+				$lasthost = false;
+				$opentree = false;
 				foreach ($hierarchy as $leaf) {
 					if ($dhtml_tree_id <> $tree["id"]) {
-						$dhtml_tree[$i] = "ou0 = insFld(foldersTree, gFld(\"" . get_tree_name($tree["id"]) . "\", \"" . clean_up_export_name(get_tree_name($tree["id"])) . "_leaf.html\"))\n";
+						if ($opentree) {
+							$i++;
+							$dhtml_tree[$i] = "\t\t\t</ul>\n\t\t</li>\n\t</ul>\n";
+						}
+						$i++;
+						$clean_id = clean_up_export_name(get_tree_name($tree["id"]));
+						$dhtml_tree[$i] = "\t<ul>\n\t\t<li id=\"" . $clean_id . "\"><a href=\"" . $clean_id . "_leaf.html\">" . get_tree_name($tree["id"]) . "</a>\n\t\t\t<ul>\n";
+						$opentree = true;
 					}
 					$dhtml_tree_id = $tree["id"];
 
-					$i++;
 					$tier = tree_tier($leaf["order_key"]);
 
 					if ($leaf["host_id"] > 0) {  //It's a host
-						$dhtml_tree[$i] = "ou" . ($tier) . " = insFld(ou" . ($tier-1) . ", gFld(\"Host: " . $leaf["hostname"] . "\", \"" . clean_up_export_name($leaf["hostname"] . "_" . $leaf["id"]) . ".html\"))\n";
+						if ($tier > $last_tier) {
+							$i++;
+							$dhtml_tree[$i] = "\t\t\t<ul>\n";
+						} elseif ($tier < $last_tier) {
+							if (!$lasthost) {
+								$i++;
+								$dhtml_tree[$i] = "\t\t\t\t</li>\n";
+							}
+							for ($x = $tier; $x < $last_tier; $x++) {
+								$i++;
+								$dhtml_tree[$i] = "\t\t\t</ul>\n\t\t\t\t</li>\n";
+								$openli = false;
+							}
+						} elseif ($openli && !$lasthost) {
+							$i++;
+							$dhtml_tree[$i] = "\t\t\t\t</li>\n";
+							$openli = false;
+						}
+						$last_tier = $tier;
+						$lasthost = true;
+						$i++;
+						$clean_id = clean_up_export_name($leaf["hostname"] . "_" . $leaf["id"]);
+						$dhtml_tree[$i] = "\t\t\t\t<li id=\"" . $clean_id . "\"><a href=\"" . $clean_id . ".html\">Host: " . htmlspecialchars($leaf["hostname"]) . "</a>\n";
 
 						if (read_config_option("export_tree_expand_hosts") == "on") {
+							$i++;
+							$dhtml_tree[$i] = "\t\t\t\t\t<ul>\n";
 							if ($leaf["host_grouping_type"] == HOST_GROUPING_GRAPH_TEMPLATE) {
 								$graph_templates = db_fetch_assoc("SELECT
 									graph_templates.id,
@@ -1552,7 +1591,8 @@
 							 	if (sizeof($graph_templates) > 0) {
 									foreach ($graph_templates as $graph_template) {
 										$i++;
-										$dhtml_tree[$i] = "ou" . ($tier+1) . " = insFld(ou" . ($tier) . ", gFld(\" " . $graph_template["name"] . "\", \"" . clean_up_export_name($leaf["hostname"] . "_gt_" . $leaf["id"]) . "_" . $graph_template["id"] . ".html\"))\n";
+										$clean_id = clean_up_export_name($leaf["hostname"] . "_gt_" . $leaf["id"] . "_" . $graph_template["id"]);
+										$dhtml_tree[$i] = "\t\t\t\t\t\t<li id=\"" . $clean_id . "\"><a href=\"" . $clean_id . ".html\">" . htmlspecialchars($graph_template["name"]) . "</a></li>\n";
 									}
 								}
 							}else if ($leaf["host_grouping_type"] == HOST_GROUPING_DATA_QUERY_INDEX) {
@@ -1567,36 +1607,77 @@
 
 								array_push($data_queries, array(
 									"id" => "0",
-									"name" => "Graph Template Based"
+									"name" => "Non Query Based"
 									));
 
 								if (sizeof($data_queries) > 0) {
-								foreach ($data_queries as $data_query) {
-									$i++;
-
-									$dhtml_tree[$i] = "ou" . ($tier+1) . " = insFld(ou" . ($tier) . ", gFld(\" " . $data_query["name"] . "\", \"" . clean_up_export_name($leaf["hostname"] . "_dq_" . $leaf["title"] . "_" . $leaf["id"]) . "_" . $data_query["id"] . ".html\"))\n";
+									foreach ($data_queries as $data_query) {
+										$i++;
+										$clean_id = clean_up_export_name($leaf["hostname"] . "_dq_" . $leaf["title"] . "_" . $leaf["id"] . "_" . $data_query["id"]);
+										$dhtml_tree[$i] = "\t\t\t\t\t\t<li id=\"" . $clean_id . "\"><a href=\"" . $clean_id . ".html\">" . htmlspecialchars($data_query["name"]) . "</a>\n";
 
-									/* fetch a list of field names that are sorted by the preferred sort field */
-									$sort_field_data = get_formatted_data_query_indexes($leaf["host_id"], $data_query["id"]);
+										/* fetch a list of field names that are sorted by the preferred sort field */
+										$sort_field_data = get_formatted_data_query_indexes($leaf["host_id"], $data_query["id"]);
 
-									if ($data_query["id"] > 0) {
-										while (list($snmp_index, $sort_field_value) = each($sort_field_data)) {
+										if ($data_query["id"] > 0) {
+											$i++;
+											$dhtml_tree[$i] = "\t\t\t\t\t\t\t<ul>\n";
+											while (list($snmp_index, $sort_field_value) = each($sort_field_data)) {
+												$i++;
+												$clean_id = clean_up_export_name($leaf["hostname"] . "_dqi_" . $leaf["id"] . "_" . $data_query["id"] . "_" . $snmp_index);
+												$dhtml_tree[$i] = "\t\t\t\t\t\t\t\t<li id=\"" . $clean_id . "\"><a href=\"" . $clean_id . ".html\">" . htmlspecialchars($sort_field_value) . "</a></li>\n";
+											}
 											$i++;
-											$dhtml_tree[$i] = "ou" . ($tier+2) . " = insFld(ou" . ($tier+1) . ", gFld(\" " . $sort_field_value . "\", \"" . clean_up_export_name($leaf["hostname"] . "_dqi_" . $leaf["title"] . "_" . $leaf["id"]) . "_" . $data_query["id"] . "_" . $snmp_index . ".html\"))\n";
+											$dhtml_tree[$i] = "\t\t\t\t\t\t\t</ul>\n";
 										}
+										$i++;
+										$dhtml_tree[$i] = "\t\t\t\t\t\t</li>\n";
 									}
 								}
-								}
 							}
+							$i++;
+							$dhtml_tree[$i] = "\t\t\t\t\t</ul>\n";
 						}
-					}else {
-						$dhtml_tree[$i] = "ou" . ($tier) . " = insFld(ou" . ($tier-1) . ", gFld(\"" . $leaf["title"] . "\", \"" . clean_up_export_name(get_tree_name($tree["id"]) . "_" . $leaf["title"] . "_" . $leaf["id"]) . "_leaf.html\"))\n";
+						$i++;
+						$dhtml_tree[$i] = "\t\t\t\t</li>\n";
+					}else { //It's not a host
+						if ($tier > $last_tier) {
+							$i++;
+							$dhtml_tree[$i] = "\t\t\t<ul>\n";
+						} elseif ($tier < $last_tier) {
+							if (!$lasthost) {
+								$i++;
+								$dhtml_tree[$i] = "</li>\n";
+							}
+							for ($x = $tier; $x < $last_tier; $x++) {
+								$i++;
+								$dhtml_tree[$i] = "\t\t\t\t</ul>\n\t\t\t\t</li>\n";
+								$openli = false;
+							}
+						} elseif ($openli && !$lasthost) {
+							$i++;
+							$dhtml_tree[$i] = "</li>\n";
+							$openli = false;
+						}
+						$last_tier = $tier;
+						$i++;
+						$clean_id = clean_up_export_name(get_tree_name($tree["id"]) . "_" . $leaf["title"] . "_" . $leaf["id"]);
+						$dhtml_tree[$i] = "\t\t\t\t<li id=\"" . $clean_id . "\"><a href=\"" . $clean_id . "_leaf.html\">" . htmlspecialchars($leaf["title"]) . "</a>\n";
+						$openli = true;
+						$lasthost = false;
 					}
 				}
+				for ($x = $last_tier; $x > 1; $x--) {
+					$i++;
+					$dhtml_tree[$i] = "\t\t\t\t\t</ul>\n\t\t\t\t</li>\n";
+				}
+				$i++;
+				$dhtml_tree[$i] = "\t\t\t</ul>\n\t\t</li>\n\t</ul>\n";
 			}else{
 				if ($dhtml_tree_id <> $tree["id"]) {
-					$dhtml_tree[$i] = "ou0 = insFld(foldersTree, gFld(\"" . get_tree_name($tree["id"]) . "\", \"" . clean_up_export_name(get_tree_name($tree["id"])) . "_leaf.html\"))\n";
 					$i++;
+					$clean_id = clean_up_export_name(get_tree_name($tree["id"]));
+					$dhtml_tree[$i] = "\t<ul>\n\t\t<li id=\"" . $clean_id . "_leaf\"><a href=\"" . $clean_id . "_leaf.html\">" . get_tree_name($tree["id"]) . "</a></li>\n\t</ul>";
 				}
 			}
 		}
@@ -1612,10 +1693,10 @@
         $dir - the export directory where graphs will either be staged or located.
 */
 function create_export_directory_structure($cacti_root_path, $dir) {
-	/* create the treeview sub-directory */
-	if (!is_dir("$dir/treeview")) {
-		if (!mkdir("$dir/treeview", 0755)) {
-			export_fatal("Create directory '" . $dir . "/treeview' failed.  Can not continue");
+	/* create the jquery sub-directory */
+	if (!is_dir("$dir/js")) {
+		if (!mkdir("$dir/js", 0755)) {
+			export_fatal("Create directory '" . $dir . "/js' failed.  Can not continue");
 		}
 	}
 
@@ -1626,8 +1707,6 @@
 		}
 	}
 
-	$treeview_dir = $dir . "/treeview";
-
 	/* css */
 	copy("$cacti_root_path/include/main.css", "$dir/main.css");
 
@@ -1639,18 +1718,15 @@
 	copy("$cacti_root_path/images/shadow_gray.gif", "$dir/shadow_gray.gif");
 
 	/* java scripts for the tree */
-	copy("$cacti_root_path/include/treeview/ftiens4_export.js", "$treeview_dir/ftiens4.js");
-	copy("$cacti_root_path/include/treeview/ua.js", "$treeview_dir/ua.js");
-
-	/* images for the tree */
-	copy("$cacti_root_path/include/treeview/ftv2blank.gif", "$treeview_dir/ftv2blank.gif");
-	copy("$cacti_root_path/include/treeview/ftv2lastnode.gif", "$treeview_dir/ftv2lastnode.gif");
-	copy("$cacti_root_path/include/treeview/ftv2mlastnode.gif", "$treeview_dir/ftv2mlastnode.gif");
-	copy("$cacti_root_path/include/treeview/ftv2mnode.gif", "$treeview_dir/ftv2mnode.gif");
-	copy("$cacti_root_path/include/treeview/ftv2node.gif", "$treeview_dir/ftv2node.gif");
-	copy("$cacti_root_path/include/treeview/ftv2plastnode.gif", "$treeview_dir/ftv2plastnode.gif");
-	copy("$cacti_root_path/include/treeview/ftv2pnode.gif", "$treeview_dir/ftv2pnode.gif");
-	copy("$cacti_root_path/include/treeview/ftv2vertline.gif", "$treeview_dir/ftv2vertline.gif");
+	copy("$cacti_root_path/include/js/jquery/jquery.js", "$dir/js/jquery.js");
+	copy("$cacti_root_path/include/js/jquery/jquery.jstree.js", "$dir/js/jquery.jstree.js");
+	copy("$cacti_root_path/include/js/jquery/jquery.cookie.js", "$dir/js/jquery.cookie.js");
+
+	/* theme info for java scripts */
+	copy("$cacti_root_path/include/js/jquery/themes/default/style.css", "$dir/js/style.css");
+	copy("$cacti_root_path/include/js/jquery/themes/default/d.png", "$dir/js/d.png");
+	copy("$cacti_root_path/include/js/jquery/themes/default/d.gif", "$dir/js/d.gif");
+	copy("$cacti_root_path/include/js/jquery/themes/default/throbber.gif", "$dir/js/throbber.gif");
 }
 
 function get_host_description($host_id) {
@@ -1738,8 +1814,9 @@
 	<meta http-equiv=refresh content='300'; url='index.html'>
 	<meta http-equiv=Pragma content=no-cache>
 	<meta http-equiv=cache-control content=no-cache>
-	<script type=\"text/javascript\" src=\"./treeview/ua.js\"></script>
-	<script type=\"text/javascript\" src=\"./treeview/ftiens4.js\"></script>
+	<script type=\"text/javascript\" src=\"./js/jquery.js\" language=\"javascript\"></script>
+	<script type=\"text/javascript\" src=\"./js/jquery.cookie.js\" language=\"javascript\"></script>
+	<script type=\"text/javascript\" src=\"./js/jquery.jstree.js\" language=\"javascript\"></script>
 </head>
 <body>
 <table style='width:100%;height:100%;' cellspacing='0' cellpadding='0'>
--- a/lib/html_tree.php
+++ b/lib/html_tree.php
@@ -495,17 +495,9 @@
 	include_once($config["library_path"] . "/data_query.php");
 
 	?>
-	<script type="text/javascript">
-	<!--
-	USETEXTLINKS = 1
-	STARTALLOPEN = 0
-	USEFRAMES = 0
-	USEICONS = 0
-	WRAPTEXT = 1
-	PERSERVESTATE = 1
-	HIGHLIGHT = 1
 	<?php
 	/* get current time */
+/* Probably not needed anymore as jstree uses jquery.cookies
 	list($micro,$seconds) = explode(" ", microtime());
 	$current_time = $seconds + $micro;
 	$expand_hosts = read_graph_config_option("expand_hosts");
@@ -522,6 +514,8 @@
 			$dhtml_tree = $_SESSION['dhtml_tree'];
 		}
 	}
+*/
+	$dhtml_tree = create_dhtml_tree();
 
 	$total_tree_items = sizeof($dhtml_tree) - 1;
 
@@ -529,8 +523,31 @@
 		print $dhtml_tree[$i];
 	}
 	?>
-	//-->
-	</script>
+<script type="text/javascript">
+$(function () {
+	$("#jtree")
+		.jstree({
+			"plugins" : ["ui","themes","html_data","cookies"],
+			"themes" : {"icons" : false,
+				"url" : "<?php echo  $config['url_path']; ?>include/js/jquery/themes/default/style.css"},
+			"cookies" : {
+				"save_opened" : "Cacti_jstree_open",
+				"save_selected" : "Cacti_jstree_select"
+				}
+			})
+
+		// Make sure that the nodes are actually used as links
+		// We need reselect to prevent endless loops
+		// https://groups.google.com/d/topic/jstree/j6XNq9hQdeA/discussion
+		.bind("reselect.jstree", function (e, data) {
+			data.inst.get_container().bind("select_node.jstree", function (e, data) {
+				// data.rstl.obj is the object that was selected.
+				document.location.href = data.rslt.obj.children("a").attr("href");
+			});
+		});
+
+});
+</script>
 	<?php
 }
 
@@ -543,9 +560,8 @@
 
 	$dhtml_tree[0] = $start;
 	$dhtml_tree[1] = read_graph_config_option("expand_hosts");
-	$dhtml_tree[2] = "foldersTree = gFld(\"\", \"\")\n";
-	$dhtml_tree[3] = "foldersTree.xID = \"root\"\n";
-	$i = 3;
+	$dhtml_tree[2] = "\n<div id=\"jtree\">\n";
+	$i = 2;
 
 	$tree_list = get_graph_tree_array();
 
@@ -567,7 +583,6 @@
 
 	if (sizeof($tree_list) > 0) {
 		foreach ($tree_list as $tree) {
-			$i++;
 			$hierarchy = db_fetch_assoc("select
 				graph_tree_items.id,
 				graph_tree_items.title,
@@ -583,21 +598,45 @@
 				and graph_tree_items.local_graph_id = 0
 				order by graph_tree_items.order_key");
 
-			$dhtml_tree[$i] = "ou0 = insFld(foldersTree, gFld(\"" . htmlspecialchars($tree["name"]) . "\", \"" . htmlspecialchars("graph_view.php?action=tree&tree_id=" . $tree["id"]) . "\"))\n";
 			$i++;
-			$dhtml_tree[$i] = "ou0.xID = \"tree_" . $tree["id"] . "\"\n";
+			$dhtml_tree[$i] = "\t<ul>\n\t\t<li id=\"" . htmlspecialchars("tree_" . $tree["id"]) . "\"><a href=\"" . htmlspecialchars("graph_view.php?action=tree&tree_id=" . $tree["id"]) . "\">" . htmlspecialchars($tree["name"]) . "</a>\n";
 
 			if (sizeof($hierarchy) > 0) {
+				$i++;
+				$dhtml_tree[$i] = "\t\t\t<ul>\n";
+				$last_tier = 1;
+				$openli = false;
+				$lasthost = false;
 				foreach ($hierarchy as $leaf) {
-					$i++;
 					$tier = tree_tier($leaf["order_key"]);
 
-					if ($leaf["host_id"] > 0) {
-						$dhtml_tree[$i] = "ou" . ($tier) . " = insFld(ou" . abs(($tier-1)) . ", gFld(\"" . "Host: " . htmlspecialchars($leaf["hostname"]) . "\", \"" . htmlspecialchars("graph_view.php?action=tree&tree_id=" . $tree["id"] . "&leaf_id=" . $leaf["id"]) . "\"))\n";
+					if ($leaf["host_id"] > 0) {  //It's a host
+						if ($tier > $last_tier) {
+							$i++;
+							$dhtml_tree[$i] = "\t\t\t<ul>\n";
+						} elseif ($tier < $last_tier) {
+							if (!$lasthost) {
+								$i++;
+								$dhtml_tree[$i] = "\t\t\t\t</li>\n";
+							}
+							for ($x = $tier; $x < $last_tier; $x++) {
+								$i++;
+								$dhtml_tree[$i] = "\t\t\t</ul>\n\t\t\t\t</li>\n";
+								$openli = false;
+							}
+						} elseif ($openli && !$lasthost) {
+							$i++;
+							$dhtml_tree[$i] = "\t\t\t\t</li>\n";
+							$openli = false;
+						}
+						$last_tier = $tier;
+						$lasthost = true;
 						$i++;
-						$dhtml_tree[$i] = "ou" . ($tier) . ".xID = \"tree_" . $tree["id"] . "_leaf_" . $leaf["id"] . "\"\n";
+						$dhtml_tree[$i] = "\t\t\t\t<li id=\"" . htmlspecialchars("tree_" . $tree["id"] . "_leaf_" . $leaf["id"]) . "\"><a href=\"" . htmlspecialchars("graph_view.php?action=tree&tree_id=" . $tree["id"] . "&leaf_id=" . $leaf["id"]) . "\">Host: " . htmlspecialchars($leaf["hostname"]) . "</a>\n";
 
 						if (read_graph_config_option("expand_hosts") == "on") {
+							$i++;
+							$dhtml_tree[$i] = "\t\t\t\t\t<ul>\n";
 							if ($leaf["host_grouping_type"] == HOST_GROUPING_GRAPH_TEMPLATE) {
 								$graph_templates = db_fetch_assoc("select
 									graph_templates.id,
@@ -612,9 +651,7 @@
 								if (sizeof($graph_templates) > 0) {
 									foreach ($graph_templates as $graph_template) {
 										$i++;
-										$dhtml_tree[$i] = "ou" . ($tier+1) . " = insFld(ou" . ($tier) . ", gFld(\" " . htmlspecialchars($graph_template["name"]) . "\", \"graph_view.php?action=tree&tree_id=" . $tree["id"] . "&leaf_id=" . $leaf["id"] . "&host_group_data=graph_template:" . $graph_template["id"] . "\"))\n";
-										$i++;
-										$dhtml_tree[$i] = "ou" . ($tier+1) . ".xID = \"tree_" . $tree["id"] . "_leaf_" . $leaf["id"] . "_hgd_gt_" . $graph_template["id"] . "\"\n";
+										$dhtml_tree[$i] = "\t\t\t\t\t\t<li id=\"" . htmlspecialchars("tree_" . $tree["id"] . "_leaf_" . $leaf["id"] . "_hgd_gt_" . $graph_template["id"]) . "\"><a href=\"" . htmlspecialchars("graph_view.php?action=tree&tree_id=" . $tree["id"] . "&leaf_id=" . $leaf["id"] . "&host_group_data=graph_template:" . $graph_template["id"]) . "\">" . htmlspecialchars($graph_template["name"]) . "</a></li>\n";
 									}
 								}
 							}else if ($leaf["host_grouping_type"] == HOST_GROUPING_DATA_QUERY_INDEX) {
@@ -645,33 +682,71 @@
 										if ((($data_query["id"] == 0) && ($non_template_graphs > 0)) ||
 											(($data_query["id"] > 0) && (sizeof($sort_field_data) > 0))) {
 											$i++;
-											$dhtml_tree[$i] = "ou" . ($tier+1) . " = insFld(ou" . ($tier) . ", gFld(\" " . htmlspecialchars($data_query["name"]) . "\", \"" . htmlspecialchars("graph_view.php?action=tree&tree_id=" . $tree["id"] . "&leaf_id=" . $leaf["id"] . "&host_group_data=data_query:" . $data_query["id"]) . "\"))\n";
-											$i++;
-											$dhtml_tree[$i] = "ou" . ($tier+1) . ".xID = \"tree_" . $tree["id"] . "_leaf_" . $leaf["id"] . "_hgd_dq_" . $data_query["id"] . "\"\n";
-
+											$dhtml_tree[$i] = "\t\t\t\t\t\t<li id=\"" . htmlspecialchars("tree_" . $tree["id"] . "_leaf_" . $leaf["id"] . "_hgd_dq_" . $data_query["id"]) . "\"><a href=\"" . htmlspecialchars("graph_view.php?action=tree&tree_id=" . $tree["id"] . "&leaf_id=" . $leaf["id"] . "&host_group_data=data_query:" . $data_query["id"]) . "\">" . htmlspecialchars($data_query["name"]) . "</a>\n";
 											if ($data_query["id"] > 0) {
+												$i++;
+												$dhtml_tree[$i] = "\t\t\t\t\t\t\t<ul>\n";
 												while (list($snmp_index, $sort_field_value) = each($sort_field_data)) {
 													$i++;
-													$dhtml_tree[$i] = "ou" . ($tier+2) . " = insFld(ou" . ($tier+1) . ", gFld(\" " . htmlspecialchars($sort_field_value) . "\", \"" . htmlspecialchars("graph_view.php?action=tree&tree_id=" . $tree["id"] . "&leaf_id=" . $leaf["id"] . "&host_group_data=data_query_index:" . $data_query["id"] . ":" . urlencode($snmp_index)) . "\"))\n";
-													$i++;
-													$dhtml_tree[$i] = "ou" . ($tier+2) . ".xID = \"tree_" . $tree["id"] . "_leaf_" . $leaf["id"] . "_hgd_dqi" . $data_query["id"] . "_" . urlencode($snmp_index) . "\"\n";
+													$dhtml_tree[$i] = "\t\t\t\t\t\t\t\t<li id=\"" . htmlspecialchars("tree_" . $tree["id"] . "_leaf_" . $leaf["id"] . "_hgd_dqi" . $data_query["id"]) . "_" . urlencode($snmp_index) . "\"><a href=\"" . htmlspecialchars("graph_view.php?action=tree&tree_id=" . $tree["id"] . "&leaf_id=" . $leaf["id"] . "&host_group_data=data_query_index:" . $data_query["id"] . ":" . urlencode($snmp_index)) . "\">" . htmlspecialchars($sort_field_value) . "</a></li>\n";
 												}
+											$i++;
+											$dhtml_tree[$i] = "\t\t\t\t\t\t\t</ul>\n";
+											$i++;
+											$dhtml_tree[$i] = "\t\t\t\t\t\t</li>\n";
 											}
 										}
 									}
 								}
+							$i++;
+							$dhtml_tree[$i] = "\t\t\t\t\t\t</li>\n";
+							}
+						$i++;
+						$dhtml_tree[$i] = "\t\t\t\t\t</ul>\n";
+						}
+					$i++;
+					$dhtml_tree[$i] = "\t\t\t\t</li>\n";
+					}else{ //It's not a host
+						if ($tier > $last_tier) {
+							$i++;
+							$dhtml_tree[$i] = "\t\t\t<ul>\n";
+						} elseif ($tier < $last_tier) {
+							if (!$lasthost) {
+								$i++;
+								$dhtml_tree[$i] = "</li>\n";
 							}
+							for ($x = $tier; $x < $last_tier; $x++) {
+								$i++;
+								$dhtml_tree[$i] = "\t\t\t\t</ul>\n\t\t\t\t</li>\n";
+								$openli = false;
+							}
+						} elseif ($openli && !$lasthost) {
+							$i++;
+							$dhtml_tree[$i] = "</li>\n";
+							$openli = false;
 						}
-					}else{
-						$dhtml_tree[$i] = "ou" . ($tier) . " = insFld(ou" . abs(($tier-1)) . ", gFld(\"" . htmlspecialchars($leaf["title"]) . "\", \"" . htmlspecialchars("graph_view.php?action=tree&tree_id=" . $tree["id"] . "&leaf_id=" . $leaf["id"]) . "\"))\n";
+						$last_tier = $tier;
 						$i++;
-						$dhtml_tree[$i] = "ou" . ($tier) . ".xID = \"tree_" . $tree["id"] . "_leaf_" . $leaf["id"] . "\"\n";
+						$dhtml_tree[$i] = "\t\t\t\t<li id=\"" . htmlspecialchars("tree_" . $tree["id"] . "_leaf_" . $leaf["id"]) . "\"><a href=\"" . htmlspecialchars("graph_view.php?action=tree&tree_id=" . $tree["id"] . "&leaf_id=" . $leaf["id"]) . "\">" . htmlspecialchars($leaf["title"]) . "</a>\n";
+						$openli = true;
+						$lasthost = false;
 					}
 				}
+				for ($x = $last_tier; $x > 1; $x--) {
+					$i++;
+					$dhtml_tree[$i] = "\t\t\t\t\t</ul>\n\t\t\t\t</li>\n";
+				}
+				$i++;
+				$dhtml_tree[$i] = "\t\t\t</ul>\n";
 			}
+			$i++;
+			$dhtml_tree[$i] = "\t\t</li>\n\t</ul>\n";
 		}
 	}
 
+	$i++;
+	$dhtml_tree[$i] = "</div>\n";
+
 	return $dhtml_tree;
 }
 
@@ -758,14 +833,6 @@
 		}
 	}
 
-	print "<script type=\"text/javascript\">\n";
-	print "<!--\n";
-	print "myNode = findObj(\"$nodeid\")\n";
-	print "myNode.forceOpeningOfAncestorFolders();\n";
-	print "highlightObjLink(myNode)\n";
-	print "//-->\n";
-	print "</script>";
-
 	/* ================= input validation ================= */
 	input_validate_input_number(get_request_var_post("graphs"));
 	input_validate_input_number(get_request_var_post("page"));
Description: Using jquery.jstree with cacti should use jquery and jquery-cookie from
 existing packages.
 .
 This patch replaces embedded paths by system locations of jquery(|.cookie)
Bug-Debian: http://bugs.debian.org/679980
Forwarded: not needed
Author: Paul Gevers <[email-masked]>
Date: Thu, 28 Mar 2013 21:45:43 +0100

--- a/include/top_graph_header.php
+++ b/include/top_graph_header.php
@@ -84,8 +84,8 @@
 	<link href="<?php echo $config['url_path']; ?>include/main.css" type="text/css" rel="stylesheet">
 	<link href="<?php echo $config['url_path']; ?>images/favicon.ico" rel="shortcut icon"/>
 	<script type="text/javascript" src="<?php echo $config['url_path']; ?>include/layout.js"></script>
-	<script type="text/javascript" src="<?php echo $config['url_path']; ?>include/js/jquery/jquery.js" language="javascript"></script>
-	<script type="text/javascript" src="<?php echo $config['url_path']; ?>include/js/jquery/jquery.cookie.js" language="javascript"></script>
+	<script type="text/javascript" src="/javascript/jquery/jquery.js" language="javascript"></script>
+	<script type="text/javascript" src="/javascript/jquery-cookie/jquery.cookie.js" language="javascript"></script>
 	<script type="text/javascript" src="<?php echo $config['url_path']; ?>include/js/jquery/jquery.jstree.js"></script>
 	<script type="text/javascript" src="<?php echo $config['url_path']; ?>include/jscalendar/calendar.js"></script>
 	<script type="text/javascript" src="<?php echo $config['url_path']; ?>include/jscalendar/lang/calendar-en.js"></script>
--- a/lib/graph_export.php
+++ b/lib/graph_export.php
@@ -1718,9 +1718,9 @@
 	copy("$cacti_root_path/images/shadow_gray.gif", "$dir/shadow_gray.gif");
 
 	/* java scripts for the tree */
-	copy("$cacti_root_path/include/js/jquery/jquery.js", "$dir/js/jquery.js");
+	copy("/usr/share/javascript/jquery/jquery.js", "$dir/js/jquery.js");
 	copy("$cacti_root_path/include/js/jquery/jquery.jstree.js", "$dir/js/jquery.jstree.js");
-	copy("$cacti_root_path/include/js/jquery/jquery.cookie.js", "$dir/js/jquery.cookie.js");
+	copy("/usr/share/javascript/jquery-cookie/jquery.cookie.js", "$dir/js/jquery.cookie.js");
 
 	/* theme info for java scripts */
 	copy("$cacti_root_path/include/js/jquery/themes/default/style.css", "$dir/js/style.css");