This box includes basic usage information for this template. When calling the template, this documentation will not appear. Functional template code should be placed outside the dotted box.
| Template Description | This template produces a collapsible wiki tree. Rather than pre-fetching the entire tree, it dynamically fetches only as much as necessary via AJAX and the Mindtouch API. This means it loads quickly even if the full tree is very large, and makes it suitable for implementing a navigation tree for an entire wiki site. If you're not working with a large tree and therefore performance isn't an issue, you can also look at the non-AJAX version, "CollapsibleTree". This template was originally implemented by Blake Harms based on the CollapsibleTree template, and currently maintained by Neil Weinstock. |
| Requirements |
|
| Documentation URL | http://developer.mindtouch.com/App_Catalog/AJAX_collapsible_wiki_tree |
| Discussion URL | http://forums.developer.mindtouch.com/showthread.php?5972-NEW-AJAX-Collapsible-Wiki.Tree |
Place newest version at the top of the table.
| Version | Date | Author | Description |
|---|---|---|---|
| 1.8.1 | 12-May-2011 | Neil Weinstock | Fixed alphabetization error for top-level list. |
| 1.8 | 11-May-2011 | Neil Weinstock |
|
| 1.7 | 30-Sep-2009 | Neil Weinstock | Converted to use page IDs as links, to fix all character encoding and URL escaping issues |
| 1.6 | 4-Sep-2009 | Blake Harms | Fixes for German language - Thanks Baum! |
| 1.5.1 | 10-Jul-2009 | Blake Harms | Removed click function from pages that do not have subpages |
| 1.5 | 10-Jul-2009 | Blake Harms | Added Ajax checks for subpage #s and added depth to the bullets |
| 1.3 | 10-Jul-2009 | Blake Harms | Fixed XML parsing for all major browsers |
| 1.2 | 9-Jul-2009 | Blake Harms | Fixed a MAJOR bug where IE didn't read XML properly |
| 1.0 | 9-Jul-2009 | Blake Harms | First version posted to App Catalog |
| Name | Type | Default | Description |
|---|---|---|---|
| path | str? | page.path | Path to the root of the tree |
| slide | bool? | false | Use "slide" effect to collapse and expand sub-trees |
var thisTemplate = wiki.inclusions()[-1];
if (!wiki.pagepermissions(thisTemplate.id, thisTemplate.author.id).unsafecontent)
<div style="color:red; width:75%; padding:5px; border:1px solid red;">
"WARNING: The page '"..thisTemplate.path.."' must be re-saved by a user with UNSAFECONTENT permission in order to work correctly. ";
<a href="http://developer.mindtouch.com/en/kb/Using_templates_which_require_UNSAFECONTENT_permission"> "See this" </a>;
" for more info.";
</div>;
// Deki AJAX API extension required!
dekiapi();
// Image files "collapse_icons.gif" and "loadinfo.net.gif" must be attached to this template!
var iconsIMG = thisTemplate.files["collapse_icons.gif"].uri;
var loaderIMG = thisTemplate.files["loadinfo.net.gif" ].uri;
// USAGE: template.collapsibleList(path, slide)
// "path": Path for wiki.tree to load.
// "slide": if true, use "slide" effect to show/hide subtrees (default: false)
// Args
var path = $0 ?? $path ?? page.path;
var slide = $1 ?? $slide ?? false;
// Output
<html>
<head>
//
// First script element is unique to each template call, passing args to the common code
//
<script type="text/javascript">"
DekiWiki.$(document).ready(function($) {
ajax_collapse_list(Deki.$('#" .. @id .. "').find('ul'),0, "..json.emit(slide)..");
});
"</script>;
//
// This script element is always the same, so only one copy will end up on the page even if the
// template is called multiple times
//
<script type="text/javascript">"
var collapseIcon_hide = '0px -64px';
var collapseIcon_show = '0px -80px';
function readXML(str){
var xml;
if ($.browser.msie && typeof str == 'string') {
xml = new ActiveXObject('Microsoft.XMLDOM');
xml.async = false;
xml.loadXML(str);
} else {
var parser = new DOMParser();
xml = parser.parseFromString(str, 'text/xml');
}
return xml;
}
function ajax_collapse_list(ul, depth, slide){
Deki.$(ul).children().each(function(){
var $child = Deki.$(this).css({'margin-left':'0', 'padding-left':'0', 'list-style-type':'none'}).prepend(
'<img src=\"/skins/common/icons/icon-trans.gif\" style=\"background-image:url(".. iconsIMG .. ")\" /> ');
var $img = $child.children('img:first');
var child_id = $child.children('a:first').attr('pageid');
// Check each item for subpages, if they have them, add the + button, if not, set depth.
Deki.$.ajax({
url: '/@api/deki/pages/'+child_id+'/subpages',
type: 'GET',
data: {
limit:0
},
dataType: ($.browser.msie) ? 'text' : 'xml',
complete: function(data) {
var xml = readXML(data.responseText);
var count = Deki.$('subpages',xml).attr('totalcount');
if(count > 0 ){
$img.css('background-position', collapseIcon_show);
}
else {
$img.css('background-position', '0px -'+(16+16*(depth%3))+'px')
.css('cursor','auto')
.unbind('click');
}
}
});
// Take action when expand or collapse icon is clicked
$img.css('background-position', collapseIcon_show)
.css('cursor','pointer')
.click(function(){
$self= Deki.$(this);
$parent = $self.parent();
var subpages = $parent.children('ul:first');
if(subpages.css('display') == 'none'){ // subpages is hidden
//show sublist
if(slide) subpages.slideDown('fast');
else subpages.show();
$self.css('background-position',collapseIcon_hide);
}
else if(subpages.html() && subpages.html().length > 0){ // subpages is not hidden
//hide sublist
if(slide) subpages.slideUp('fast');
else subpages.hide();
$self.css('background-position',collapseIcon_show);
}
else { // the hard part...
// loader icon.
$self.css('background-image','url("..loaderIMG..")');
//strip all empty uls
$parent.find('ul').each(function(){
if(! subpages.html() || subpages.html().length <= 0){
Deki.$(this).remove();
}
});
// collect parent's page id.
var link = $parent.find('a');
var pageid = link.attr('pageid');
// load list with ajax
// create and immediately hide the list
subpages = Deki.$('<ul></ul>').css('display','none');
Deki.$.ajax({
url: '/@api/deki/pages/'+pageid+'/subpages',
type: 'GET',
dataType: ($.browser.msie) ? 'text' : 'xml',
complete: function(data) {
var xml = readXML(data.responseText);
var titles = Deki.$('title',xml);
var paths = Deki.$('path', xml);
if(titles.length > 0 ){
// Pre-populate list
for(var i=0; i< titles.length;i++){
var pageid = Deki.$(titles[i]).parent().attr('id');
var $child = Deki.$('<li></li>')
.append(Deki.$('<a></a>')
.text(Deki.$(titles[i]).text())
// This link method uses a backdoor mechanism, but it seems safe
.attr({'href':'/index.php?title=_&curid='+pageid, 'pageid':pageid }))
.appendTo(subpages);
}
$self.css('background-image','url("..iconsIMG..")')
.css('background-position', collapseIcon_hide);
$parent.append(subpages);
if(slide) subpages.slideDown('fast')
else subpages.show();
ajax_collapse_list(subpages, depth+1, slide);
}
else {
$self.css('background-image','url("..iconsIMG..")')
.css('background-position', '0px -'+(16+16*(depth%3))+'px');
}
}
});
}
});
});
}
"</script>;
</head>
// Content goes in the body
<body>
<div id=(@id)>
<ul> foreach (var p in list.sort(map.values(wiki.getpage(path).subpages),"title"))
<li> <a href=(p.uri) title=(p.title) pageid=(p.id)> p.title </a> </li>;
</ul>;
</div>;
</body>
</html>
| File | Version | Size | Modified | |
|---|---|---|---|---|
| ||||
| ||||
Copyright © 2011 MindTouch, Inc. Powered by