// TreeView.js // Javascript Behaviour for the TreeView Control // Copyright (c) by Matthias Hertel, http://www.mathertel.de // This work is licensed under a BSD style license. See http://www.mathertel.de/License.aspx // ----- // 03.01.2006 created by Matthias Hertel // 04.01.2006 FireFox compatible. // 25.08.2007 supporting more attributes title, link, img on file nodes. // 26.08.2007 supporting OpenAjax hub events. var TreeViewBehaviour = { /// <summary>Implementation of a JavaScript Behavior for a treeview control. /// This control implements a treeview that is dynamically expanded with sub nodes /// when the user clicks on an existing non-expanded node. /// The new subnodes are retrieved by using a webservice call.</summary> _namespace: "de.mathertel.treeview.", /// <summary>The root namespace for treview events.</summary> // ----- Properties ----- service: "", /// <summary>Name or object reference to the WebService function proxy.</summary> init: function () { /// <summary>Initialize the control.</summary> this.ExploreAction.call = this.service; }, // init // ----- Events ----- onclick: function (evt) { /// <summary>Handle clicks on folder or file lines.</summary> evt = evt || window.event; var src = evt.srcElement; if ((src.href != null) && (src.href != "") && (src.href != window.location.href+"#")) { return; // just follow the link } // skip some inner elements without any functionality while ((src != null) && ((src.className == "") || (src.className == "ft"))) src = src.parentNode; // clicked on a file ? if (src.className.substr(0,2) == "fl") { var path = TreeViewBehaviour._nodePath(src); OpenAjax.hub.publish(this._namespace + "click", path); } // clicked on a folder ? if ((src.className != "do") && (src.className != "dc") && (src.className != "du")) src = src.parentNode; if ((src.className == "do") || (src.className == "dc") || (src.className == "du")) { var subf = src.nextSibling; if ((subf != null) && (subf.nodeName != "DIV")) subf = subf.nextSibling if ((subf == null) || (subf.nodeName != "DIV")) { // this should never happen } else if (src.className == "do") { // hide subtree src.className = "dc"; subf.style.display = "none"; } else if (src.className == "dc") { // show subtree src.className = "do"; subf.style.display = "block"; } else if (src.className == "du") { // start loading a new subtree fragment src.className = "do"; subf.innerText = "loading..."; subf.style.display = "block"; ajax.Start(this.ExploreAction, src); } } // if // cancle the standard click actions. evt.cancelBubble = true; evt.returnValue = false; }, // onchange xslt: "<?xml version='1.0' ?><xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>\ <xsl:template match='/tree'><xsl:apply-templates /></xsl:template>\ <xsl:template match='folder[@title]'><div class='du'><xsl:attribute name='name'><xsl:value-of select='@name' /></xsl:attribute><span class='ft'><xsl:value-of select='@title' /></span></div><div class='subframe' style='display:none'></div></xsl:template>\ <xsl:template match='folder'><div class='du'><xsl:attribute name='name'><xsl:value-of select='@name' /></xsl:attribute><span class='ft'><xsl:value-of select='@name' /></span></div><div class='subframe' style='display:none'><xsl:apply-templates /></div></xsl:template>\ <xsl:template match='file'><div class='fl'>\ <xsl:attribute name='class'>fl <xsl:value-of select='@img' /></xsl:attribute>\ <xsl:attribute name='name'><xsl:value-of select='@name' /></xsl:attribute><span class='ft'>\ <xsl:choose>\ <xsl:when test='@link'><a><xsl:attribute name='href'><xsl:value-of select='@link' /></xsl:attribute>\ <xsl:choose><xsl:when test='@title'><xsl:value-of select='@title' /></xsl:when><xsl:otherwise><xsl:value-of select='@name' /></xsl:otherwise></xsl:choose>\ </a>\</xsl:when>\ <xsl:otherwise><xsl:choose><xsl:when test='@title'><xsl:value-of select='@title' /></xsl:when><xsl:otherwise><xsl:value-of select='@name' /></xsl:otherwise></xsl:choose>\ </xsl:otherwise></xsl:choose>\ </span></div></xsl:template>\ </xsl:stylesheet>", /// <summary>The xslt that is used to transfer the retrieved nodes into valid HTML code.</summary> // ----- Methods ----- ExtendTree: function (src, data) { /// <summary>Extend the src node by the given xml structure.</summary> var subf = src.nextSibling; if ((subf != null) && (subf.nodeName != "DIV")) subf = subf.nextSibling if (typeof(XSLTProcessor) != "undefined") { // Mozilla... if (typeof(this.xslt) == "string") { this.xslt = ajax._getXMLDOM(this.xslt); } // if // Finally import the .xsl var xsltProcessor = new XSLTProcessor(); xsltProcessor.importStylesheet(this.xslt); var fragment = xsltProcessor.transformToFragment(data, window.document); subf.innerHTML = ""; subf.appendChild(fragment); } else { // IE if (typeof(this.xslt) == "string") { var xsltDoc= new ActiveXObject("Msxml2.DOMDocument"); xsltDoc.async = false; xsltDoc.loadXML(this.xslt); this.xslt = xsltDoc; } // if subf.innerHTML = data.transformNode(this.xslt); } // if if (subf.childNodes.length == 0) { src.className = "de"; subf.style.display="none"; } // if }, // ExtendTree _nodePath: function(src) { /// <summary>Build the full path name for a given node.</summary> var path = ""; while ((src != null) && (src._attachedBehaviour != TreeViewBehaviour)) { if (src.nodeType == 3) { src = src.previousSibling; } else if (src.className == "subframe") { src = src.previousSibling; } else if ((src.className == "do") || (src.className.substr(0,2) == "fl")) { // append the path by the name of this file or folder node. path = "/" + src.attributes["name"].value + path; src = src.parentNode; } else { src = src.parentNode; } // if } while (path.substr(0,2) == "//") path = path.substr(1); return(path); }, // _nodePath // ----- AJAX Actions ----- ExploreAction: { /// <summary>The ajax action that is used to retrieve the sub-nodes of a given folder.</summary> delay: 10, queueMultiple: true, prepare: function(src) { return (TreeViewBehaviour._nodePath(src)); }, call: "", finish: function(data, src) { jcl.FindBehaviourElement(src, TreeViewBehaviour).ExtendTree(src, data); }, onException: proxies.alertException } // ExploreAction } // TreeViewBehaviour
This page is part of the http://www.mathertel.de/AJAXEngine/ project. For updates and discussions see The AJAX Engine blog.
For updates and discussions see http://ajaxaspects.blogspot.com/.