/* * jsTree 0.9.9a * http://jstree.com/ * * Copyright (c) 2009 Ivan Bozhanov (vakata.com) * * Dual licensed under the MIT and GPL licenses: * http://www.opensource.org/licenses/mit-license.php * http://www.gnu.org/licenses/gpl.html * * Date: 2009-10-06 * */ (function($) { // jQuery plugin $.tree = { datastores : { }, plugins : { }, defaults : { data : { async : false, // Are async requests used to load open_branch contents type : "html", // One of included datastores opts : { method: "GET", url: false } // Options passed to datastore }, selected : false, // FALSE or STRING or ARRAY opened : [], // ARRAY OF INITIALLY OPENED NODES languages : [], // ARRAY of string values (which will be used as CSS classes - so they must be valid) ui : { dots : true, // BOOL - dots or no dots animation : 0, // INT - duration of open/close animations in miliseconds scroll_spd : 4, theme_path : false, // Path to the theme CSS file - if set to false and theme_name is not false - will lookup jstree-path-here/themes/theme-name-here/style.css theme_name : "default",// if set to false no theme will be loaded selected_parent_close : "select_parent", // false, "deselect", "select_parent" selected_delete : "select_previous" // false, "select_previous" }, types : { "default" : { clickable : true, // can be function renameable : true, // can be function deletable : true, // can be function creatable : true, // can be function draggable : true, // can be function max_children : -1, // -1 - not set, 0 - no children, 1 - one child, etc // can be function max_depth : -1, // -1 - not set, 0 - no children, 1 - one level of children, etc // can be function valid_children : "all", // all, none, array of values // can be function icon : { image : false, position : false } } }, rules : { multiple : false, // FALSE | CTRL | ON - multiple selection off/ with or without holding Ctrl multitree : "none", // all, none, array of tree IDs to accept from type_attr : "rel", // STRING attribute name (where is the type stored as string) createat : "bottom", // STRING (top or bottom) new nodes get inserted at top or bottom drag_copy : "ctrl", // FALSE | CTRL | ON - drag to copy off/ with or without holding Ctrl drag_button : "left", // left, right or both use_max_children : true, use_max_depth : true, max_children: -1, max_depth : -1, valid_children : "all" }, lang : { new_node : "New folder", loading : "Loading ..." }, callback : { beforechange: function(NODE,TREE_OBJ) { return true }, beforeopen : function(NODE,TREE_OBJ) { return true }, beforeclose : function(NODE,TREE_OBJ) { return true }, beforemove : function(NODE,REF_NODE,TYPE,TREE_OBJ) { return true }, beforecreate: function(NODE,REF_NODE,TYPE,TREE_OBJ) { return true }, beforerename: function(NODE,LANG,TREE_OBJ) { return true }, beforedelete: function(NODE,TREE_OBJ) { return true }, beforedata : function(NODE,TREE_OBJ) { return { id : $(NODE).attr("id") || 0 } }, // PARAMETERS PASSED TO SERVER ondata : function(DATA,TREE_OBJ) { return DATA; }, // modify data before parsing it onparse : function(STR,TREE_OBJ) { return STR; }, // modify string before visualizing it onhover : function(NODE,TREE_OBJ) { }, // node hovered onselect : function(NODE,TREE_OBJ) { }, // node selected ondeselect : function(NODE,TREE_OBJ) { }, // node deselected onchange : function(NODE,TREE_OBJ) { }, // focus changed onrename : function(NODE,TREE_OBJ,RB) { }, // node renamed onmove : function(NODE,REF_NODE,TYPE,TREE_OBJ,RB) { }, // move completed oncopy : function(NODE,REF_NODE,TYPE,TREE_OBJ,RB) { }, // copy completed oncreate : function(NODE,REF_NODE,TYPE,TREE_OBJ,RB) { }, // node created ondelete : function(NODE,TREE_OBJ,RB) { }, // node deleted onopen : function(NODE,TREE_OBJ) { }, // node opened onopen_all : function(TREE_OBJ) { }, // all nodes opened onclose_all : function(TREE_OBJ) { }, // all nodes closed onclose : function(NODE,TREE_OBJ) { }, // node closed error : function(TEXT,TREE_OBJ) { }, // error occured ondblclk : function(NODE,TREE_OBJ) { TREE_OBJ.toggle_branch.call(TREE_OBJ, NODE); TREE_OBJ.select_branch.call(TREE_OBJ, NODE); }, onrgtclk : function(NODE,TREE_OBJ,EV) { }, // right click - to prevent use: EV.preventDefault(); EV.stopPropagation(); return false onload : function(TREE_OBJ) { }, oninit : function(TREE_OBJ) { }, onfocus : function(TREE_OBJ) { }, ondestroy : function(TREE_OBJ) { }, onsearch : function(NODES, TREE_OBJ) { NODES.addClass("search"); }, ondrop : function(NODE,REF_NODE,TYPE,TREE_OBJ) { }, check : function(RULE,NODE,VALUE,TREE_OBJ) { return VALUE; }, check_move : function(NODE,REF_NODE,TYPE,TREE_OBJ) { return true; } }, plugins : { } }, create : function () { return new tree_component(); }, focused : function () { return tree_component.inst[tree_component.focused]; }, reference : function (obj) { var o = $(obj); if(!o.size()) o = $("#" + obj); if(!o.size()) return null; o = (o.is(".tree")) ? o.attr("id") : o.parents(".tree:eq(0)").attr("id"); return tree_component.inst[o] || null; }, rollback : function (data) { for(var i in data) { if(!data.hasOwnProperty(i)) continue; var tmp = tree_component.inst[i]; var lock = !tmp.locked; // if not locked - lock the tree if(lock) tmp.lock(true); // Cancel ongoing rename tmp.inp = false; tmp.container.html(data[i].html).find(".dragged").removeClass("dragged").end().find(".hover").removeClass("hover"); if(data[i].selected) { tmp.selected = $("#" + data[i].selected); tmp.selected_arr = []; tmp.container .find("a.clicked").each( function () { tmp.selected_arr.push(tmp.get_node(this)); }); } // if this function set the lock - unlock if(lock) tmp.lock(false); delete lock; delete tmp; } }, drop_mode : function (opts) { opts = $.extend(opts, { show : false, type : "default", str : "Foreign node" }); tree_component.drag_drop.foreign = true; tree_component.drag_drop.isdown = true; tree_component.drag_drop.moving = true; tree_component.drag_drop.appended = false; tree_component.drag_drop.f_type = opts.type; tree_component.drag_drop.f_data = opts; if(!opts.show) { tree_component.drag_drop.drag_help = false; tree_component.drag_drop.drag_node = false; } else { tree_component.drag_drop.drag_help = $("
"); tree_component.drag_drop.drag_node = tree_component.drag_drop.drag_help.find("li:eq(0)"); } if($.tree.drag_start !== false) $.tree.drag_start.call(null, false); }, drag_start : false, drag : false, drag_end : false }; $.fn.tree = function (opts) { return this.each(function() { var conf = $.extend({},opts); if(tree_component.inst && tree_component.inst[$(this).attr('id')]) tree_component.inst[$(this).attr('id')].destroy(); if(conf !== false) new tree_component().init(this, conf); }); }; // core function tree_component () { return { cntr : ++tree_component.cntr, settings : $.extend({},$.tree.defaults), init : function(elem, conf) { var _this = this; this.container = $(elem); if(this.container.size == 0) return false; tree_component.inst[this.cntr] = this; if(!this.container.attr("id")) this.container.attr("id","jstree_" + this.cntr); tree_component.inst[this.container.attr("id")] = tree_component.inst[this.cntr]; tree_component.focused = this.cntr; this.settings = $.extend(true, {}, this.settings, conf); // DEAL WITH LANGUAGE VERSIONS if(this.settings.languages && this.settings.languages.length) { this.current_lang = this.settings.languages[0]; var st = false; var id = "#" + this.container.attr("id"); for(var ln = 0; ln < this.settings.languages.length; ln++) { st = tree_component.add_css(id + " ." + this.settings.languages[ln]); if(st !== false) st.style.display = (this.settings.languages[ln] == this.current_lang) ? "" : "none"; } } else this.current_lang = false; // THEMES this.container.addClass("tree"); if(this.settings.ui.theme_name !== false) { if(this.settings.ui.theme_path === false) { $("script").each(function () { if(this.src.toString().match(/jquery\.tree.*?js$/)) { _this.settings.ui.theme_path = this.src.toString().replace(/jquery\.tree.*?js$/, "") + "themes/" + _this.settings.ui.theme_name + "/style.css"; return false; } }); } if(this.settings.ui.theme_path != "" && $.inArray(this.settings.ui.theme_path, tree_component.themes) == -1) { tree_component.add_sheet({ url : this.settings.ui.theme_path }); tree_component.themes.push(this.settings.ui.theme_path); } this.container.addClass("tree-" + this.settings.ui.theme_name); } // TYPE ICONS var type_icons = ""; for(var t in this.settings.types) { if(!this.settings.types.hasOwnProperty(t)) continue; if(!this.settings.types[t].icon) continue; if( this.settings.types[t].icon.image || this.settings.types[t].icon.position) { if(t == "default") type_icons += "#" + this.container.attr("id") + " li > a ins { "; else type_icons += "#" + this.container.attr("id") + " li[rel=" + t + "] > a ins { "; if(this.settings.types[t].icon.image) type_icons += " background-image:url(" + this.settings.types[t].icon.image + "); "; if(this.settings.types[t].icon.position) type_icons += " background-position:" + this.settings.types[t].icon.position + "; "; type_icons += "} "; } } if(type_icons != "") tree_component.add_sheet({ str : type_icons }); if(this.settings.rules.multiple) this.selected_arr = []; this.offset = false; this.hovered = false; this.locked = false; if(tree_component.drag_drop.marker === false) tree_component.drag_drop.marker = $("
").attr({ id : "jstree-marker" }).hide().appendTo("body"); this.callback("oninit", [this]); this.refresh(); this.attach_events(); this.focus(); }, refresh : function (obj) { if(this.locked) return this.error("LOCKED"); var _this = this; if(obj && !this.settings.data.async) obj = false; this.is_partial_refresh = obj ? true : false; // SAVE OPENED this.opened = Array(); if(this.settings.opened != false) { $.each(this.settings.opened, function (i, item) { if(this.replace(/^#/,"").length > 0) { _this.opened.push("#" + this.replace(/^#/,"")); } }); this.settings.opened = false; } else { this.container.find("li.open").each(function (i) { if(this.id) { _this.opened.push("#" + this.id); } }); } // SAVE SELECTED if(this.selected) { this.settings.selected = Array(); if(obj) { $(obj).find("li:has(a.clicked)").each(function () { if(this.id) _this.settings.selected.push("#" + this.id); }); } else { if(this.selected_arr) { $.each(this.selected_arr, function () { if(this.attr("id")) _this.settings.selected.push("#" + this.attr("id")); }); } else { if(this.selected.attr("id")) this.settings.selected.push("#" + this.selected.attr("id")); } } } else if(this.settings.selected !== false) { var tmp = Array(); if((typeof this.settings.selected).toLowerCase() == "object") { $.each(this.settings.selected, function () { if(this.replace(/^#/,"").length > 0) tmp.push("#" + this.replace(/^#/,"")); }); } else { if(this.settings.selected.replace(/^#/,"").length > 0) tmp.push("#" + this.settings.selected.replace(/^#/,"")); } this.settings.selected = tmp; } if(obj && this.settings.data.async) { this.opened = Array(); obj = this.get_node(obj); obj.find("li.open").each(function (i) { _this.opened.push("#" + this.id); }); if(obj.hasClass("open")) obj.removeClass("open").addClass("closed"); if(obj.hasClass("leaf")) obj.removeClass("leaf"); obj.children("ul:eq(0)").html(""); return this.open_branch(obj, true, function () { _this.reselect.apply(_this); }); } var _this = this; var _datastore = new $.tree.datastores[this.settings.data.type](); if(this.container.children("ul").size() == 0) { this.container.html(""); } _datastore.load(this.callback("beforedata",[false,this]),this,this.settings.data.opts,function(data) { data = _this.callback("ondata",[data, _this]); _datastore.parse(data,_this,_this.settings.data.opts,function(str) { str = _this.callback("onparse", [str, _this]); _this.container.empty().append($("