2009-10-11 12:23:27 +00:00
/*
2010-03-16 15:05:05 +00:00
* 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
*
*/
2009-10-11 12:23:27 +00:00
2010-06-23 23:19:49 +00:00
( function ( $ ) {
2010-03-16 15:05:05 +00:00
// 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 ,
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
max_children : - 1 ,
max_depth : - 1 ,
valid_children : "all"
},
lang : {
new_node : "New folder" ,
loading : "Loading ..."
},
callback : {
2010-06-23 23:19:49 +00:00
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 ; }
2010-03-16 15:05:05 +00:00
},
plugins : {}
},
2009-10-11 12:23:27 +00:00
2010-06-23 23:19:49 +00:00
create : function () { return new tree_component (); },
focused : function () { return tree_component . inst [ tree_component . focused ]; },
reference : function ( obj ) {
2010-03-16 15:05:05 +00:00
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 ;
},
2010-06-23 23:19:49 +00:00
rollback : function ( data ) {
2010-03-16 15:05:05 +00:00
for ( var i in data ) {
if ( ! data . hasOwnProperty ( i )) continue ;
var tmp = tree_component . inst [ i ];
var lock = ! tmp . locked ;
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
// 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" );
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
if ( data [ i ]. selected ) {
tmp . selected = $ ( "#" + data [ i ]. selected );
tmp . selected_arr = [];
tmp . container
2010-06-23 23:19:49 +00:00
. find ( "a.clicked" ). each ( function () {
2010-03-16 15:05:05 +00:00
tmp . selected_arr . push ( tmp . get_node ( this ));
2009-10-11 12:23:27 +00:00
});
2010-03-16 15:05:05 +00:00
}
// if this function set the lock - unlock
if ( lock ) tmp . lock ( false );
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
delete lock ;
delete tmp ;
}
},
2010-06-23 23:19:49 +00:00
drop_mode : function ( opts ) {
2010-03-16 15:05:05 +00:00
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 ;
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
if ( ! opts . show ) {
tree_component . drag_drop . drag_help = false ;
tree_component . drag_drop . drag_node = false ;
}
else {
tree_component . drag_drop . drag_help = $ ( "<div id='jstree-dragged' class='tree tree-default'><ul><li class='last dragged foreign'><a href='#'><ins> </ins>" + opts . str + "</a></li></ul></div>" );
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
};
2010-06-23 23:19:49 +00:00
$ . fn . tree = function ( opts ) {
return this . each ( function () {
2010-03-16 15:05:05 +00:00
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 );
});
};
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
// core
function tree_component () {
return {
cntr : ++ tree_component . cntr ,
settings : $ . extend ({}, $ . tree . defaults ),
2009-10-11 12:23:27 +00:00
2010-06-23 23:19:49 +00:00
init : function ( elem , conf ) {
2010-03-16 15:05:05 +00:00
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 );
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
// 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 ) {
2010-06-23 23:19:49 +00:00
$ ( "script" ). each ( function () {
2010-03-16 15:05:05 +00:00
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 });
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
if ( this . settings . rules . multiple ) this . selected_arr = [];
this . offset = false ;
this . hovered = false ;
this . locked = false ;
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
if ( tree_component . drag_drop . marker === false ) tree_component . drag_drop . marker = $ ( "<div>" ). attr ({ id : "jstree-marker" }). hide (). appendTo ( "body" );
this . callback ( "oninit" , [ this ]);
this . refresh ();
this . attach_events ();
this . focus ();
},
2010-06-23 23:19:49 +00:00
refresh : function ( obj ) {
2010-03-16 15:05:05 +00:00
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 ;
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
// SAVE OPENED
this . opened = Array ();
if ( this . settings . opened != false ) {
2010-06-23 23:19:49 +00:00
$ . each ( this . settings . opened , function ( i , item ) {
2010-03-16 15:05:05 +00:00
if ( this . replace ( /^#/ , "" ). length > 0 ) { _this . opened . push ( "#" + this . replace ( /^#/ , "" )); }
});
this . settings . opened = false ;
}
else {
2010-06-23 23:19:49 +00:00
this . container . find ( "li.open" ). each ( function ( i ) { if ( this . id ) { _this . opened . push ( "#" + this . id ); } });
2010-03-16 15:05:05 +00:00
}
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
// SAVE SELECTED
if ( this . selected ) {
this . settings . selected = Array ();
if ( obj ) {
2010-06-23 23:19:49 +00:00
$ ( obj ). find ( "li:has(a.clicked)" ). each ( function () {
2010-03-16 15:05:05 +00:00
if ( this . id ) _this . settings . selected . push ( "#" + this . id );
});
}
else {
if ( this . selected_arr ) {
2010-06-23 23:19:49 +00:00
$ . each ( this . selected_arr , function () {
2010-03-16 15:05:05 +00:00
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" ) {
2010-06-23 23:19:49 +00:00
$ . each ( this . settings . selected , function () {
2010-03-16 15:05:05 +00:00
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 ;
}
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
if ( obj && this . settings . data . async ) {
this . opened = Array ();
obj = this . get_node ( obj );
2010-06-23 23:19:49 +00:00
obj . find ( "li.open" ). each ( function ( i ) { _this . opened . push ( "#" + this . id ); });
2010-03-16 15:05:05 +00:00
if ( obj . hasClass ( "open" )) obj . removeClass ( "open" ). addClass ( "closed" );
if ( obj . hasClass ( "leaf" )) obj . removeClass ( "leaf" );
obj . children ( "ul:eq(0)" ). html ( "" );
2010-06-23 23:19:49 +00:00
return this . open_branch ( obj , true , function () { _this . reselect . apply ( _this ); });
2010-03-16 15:05:05 +00:00
}
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
var _this = this ;
var _datastore = new $ . tree . datastores [ this . settings . data . type ]();
if ( this . container . children ( "ul" ). size () == 0 ) {
this . container . html ( "<ul class='ltr' style='direction:ltr;'><li class='last'><a class='loading' href='#'><ins> </ins>" + ( this . settings . lang . loading || "Loading ..." ) + "</a></li></ul>" );
}
2010-06-23 23:19:49 +00:00
_datastore . load ( this . callback ( "beforedata" , [ false , this ]), this , this . settings . data . opts , function ( data ) {
2010-03-16 15:05:05 +00:00
data = _this . callback ( "ondata" , [ data , _this ]);
2010-06-23 23:19:49 +00:00
_datastore . parse ( data , _this , _this . settings . data . opts , function ( str ) {
2010-03-16 15:05:05 +00:00
str = _this . callback ( "onparse" , [ str , _this ]);
_this . container . empty (). append ( $ ( "<ul class='ltr'>" ). html ( str ));
_this . container . find ( "li:last-child" ). addClass ( "last" ). end (). find ( "li:has(ul)" ). not ( ".open" ). addClass ( "closed" );
_this . container . find ( "li" ). not ( ".open" ). not ( ".closed" ). addClass ( "leaf" );
_this . reselect ();
});
});
},
2010-06-23 23:19:49 +00:00
reselect : function ( is_callback ) {
2010-03-16 15:05:05 +00:00
var _this = this ;
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
if ( ! is_callback ) this . cl_count = 0 ;
else this . cl_count -- ;
// REOPEN BRANCHES
if ( this . opened && this . opened . length ) {
var opn = false ;
for ( var j = 0 ; this . opened && j < this . opened . length ; j ++ ) {
if ( this . settings . data . async ) {
var tmp = this . get_node ( this . opened [ j ]);
if ( tmp . size () && tmp . hasClass ( "closed" ) > 0 ) {
opn = true ;
var tmp = this . opened [ j ]. toString (). replace ( '/' , '\\/' );
delete this . opened [ j ];
2010-06-23 23:19:49 +00:00
this . open_branch ( tmp , true , function () { _this . reselect . apply ( _this , [ true ]); });
2010-03-16 15:05:05 +00:00
this . cl_count ++ ;
}
}
else this . open_branch ( this . opened [ j ], true );
}
if ( this . settings . data . async && opn ) return ;
if ( this . cl_count > 0 ) return ;
delete this . opened ;
}
if ( this . cl_count > 0 ) return ;
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
// DOTS and RIGHT TO LEFT
this . container . css ( "direction" , "ltr" ). children ( "ul:eq(0)" ). addClass ( "ltr" );
if ( this . settings . ui . dots == false ) this . container . children ( "ul:eq(0)" ). addClass ( "no_dots" );
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
// REPOSITION SCROLL
if ( this . scrtop ) {
this . container . scrollTop ( _this . scrtop );
delete this . scrtop ;
}
// RESELECT PREVIOUSLY SELECTED
if ( this . settings . selected !== false ) {
2010-06-23 23:19:49 +00:00
$ . each ( this . settings . selected , function ( i ) {
2010-03-16 15:05:05 +00:00
if ( _this . is_partial_refresh ) _this . select_branch ( $ ( _this . settings . selected [ i ]. toString (). replace ( '/' , '\\/' ), _this . container ), ( _this . settings . rules . multiple !== false ));
else _this . select_branch ( $ ( _this . settings . selected [ i ]. toString (). replace ( '/' , '\\/' ), _this . container ), ( _this . settings . rules . multiple !== false && i > 0 ));
});
this . settings . selected = false ;
}
this . callback ( "onload" , [ _this ]);
},
2009-10-11 12:23:27 +00:00
2010-06-23 23:19:49 +00:00
get : function ( obj , format , opts ) {
2010-03-16 15:05:05 +00:00
if ( ! format ) format = this . settings . data . type ;
if ( ! opts ) opts = this . settings . data . opts ;
return new $ . tree . datastores [ format ](). get ( obj , this , opts );
},
2009-10-11 12:23:27 +00:00
2010-06-23 23:19:49 +00:00
attach_events : function () {
2010-03-16 15:05:05 +00:00
var _this = this ;
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
this . container
2010-06-23 23:19:49 +00:00
. bind ( "mousedown.jstree" , function ( event ) {
2010-03-16 15:05:05 +00:00
if ( tree_component . drag_drop . isdown ) {
tree_component . drag_drop . move_type = false ;
event . preventDefault ();
event . stopPropagation ();
event . stopImmediatePropagation ();
return false ;
}
2009-10-11 12:23:27 +00:00
})
2010-06-23 23:19:49 +00:00
. bind ( "mouseup.jstree" , function ( event ) {
setTimeout ( function () { _this . focus . apply ( _this ); }, 5 );
2009-10-11 12:23:27 +00:00
})
2010-06-23 23:19:49 +00:00
. bind ( "click.jstree" , function ( event ) {
2010-03-16 15:05:05 +00:00
//event.stopPropagation();
return true ;
2009-10-11 12:23:27 +00:00
});
2010-06-23 23:19:49 +00:00
//** THIS IS A MODIFICATION TO JSTREE, IN FIREFOX THE ORIGINAL CONTEXT OF THIS SELECTOR IS LOST IN THE TINY MCE OVERLAY
//$("li", this.container.get(0))
$ ( "#" + this . container . attr ( "id" ) + " li" )
. live ( "click" , function ( event ) { // WHEN CLICK IS ON THE ARROW
2010-03-16 15:05:05 +00:00
if ( event . target . tagName != "LI" ) return true ;
_this . off_height ();
if ( event . pageY - $ ( event . target ). offset (). top > _this . li_height ) return true ;
_this . toggle_branch . apply ( _this , [ event . target ]);
event . stopPropagation ();
return false ;
2009-10-11 12:23:27 +00:00
});
2010-04-08 13:27:33 +00:00
$ ( "a" , this . container . get ( 0 ))
2010-06-23 23:19:49 +00:00
. live ( "click" , function ( event ) { // WHEN CLICK IS ON THE TEXT OR ICON
2010-03-16 15:05:05 +00:00
if ( event . which && event . which == 3 ) return true ;
if ( _this . locked ) {
event . preventDefault ();
event . target . blur ();
return _this . error ( "LOCKED" );
}
_this . select_branch . apply ( _this , [ event . target , event . ctrlKey || _this . settings . rules . multiple == "on" ]);
if ( _this . inp ) { _this . inp . blur (); }
event . preventDefault ();
event . target . blur ();
return false ;
2009-10-11 12:23:27 +00:00
})
2010-06-23 23:19:49 +00:00
. live ( "dblclick" , function ( event ) { // WHEN DOUBLECLICK ON TEXT OR ICON
2010-03-16 15:05:05 +00:00
if ( _this . locked ) {
event . preventDefault ();
event . stopPropagation ();
event . target . blur ();
return _this . error ( "LOCKED" );
}
_this . callback ( "ondblclk" , [ _this . get_node ( event . target ). get ( 0 ), _this ]);
event . preventDefault ();
event . stopPropagation ();
event . target . blur ();
2009-10-11 12:23:27 +00:00
})
2010-06-23 23:19:49 +00:00
. live ( "contextmenu" , function ( event ) {
2010-03-16 15:05:05 +00:00
if ( _this . locked ) {
event . target . blur ();
return _this . error ( "LOCKED" );
}
return _this . callback ( "onrgtclk" , [ _this . get_node ( event . target ). get ( 0 ), _this , event ]);
2009-10-11 12:23:27 +00:00
})
2010-06-23 23:19:49 +00:00
. live ( "mouseover" , function ( event ) {
2010-03-16 15:05:05 +00:00
if ( _this . locked ) {
event . preventDefault ();
event . stopPropagation ();
return _this . error ( "LOCKED" );
}
if ( _this . hovered !== false && ( event . target . tagName == "A" || event . target . tagName == "INS" )) {
_this . hovered . children ( "a" ). removeClass ( "hover" );
_this . hovered = false ;
}
_this . callback ( "onhover" , [ _this . get_node ( event . target ). get ( 0 ), _this ]);
2009-10-11 12:23:27 +00:00
})
2010-06-23 23:19:49 +00:00
. live ( "mousedown" , function ( event ) {
2010-03-16 15:05:05 +00:00
if ( _this . settings . rules . drag_button == "left" && event . which && event . which != 1 ) return true ;
if ( _this . settings . rules . drag_button == "right" && event . which && event . which != 3 ) return true ;
_this . focus . apply ( _this );
if ( _this . locked ) return _this . error ( "LOCKED" );
// SELECT LIST ITEM NODE
var obj = _this . get_node ( event . target );
// IF ITEM IS DRAGGABLE
if ( _this . settings . rules . multiple != false && _this . selected_arr . length > 1 && obj . children ( "a:eq(0)" ). hasClass ( "clicked" )) {
var counter = 0 ;
for ( var i in _this . selected_arr ) {
if ( ! _this . selected_arr . hasOwnProperty ( i )) continue ;
if ( _this . check ( "draggable" , _this . selected_arr [ i ])) {
_this . selected_arr [ i ]. addClass ( "dragged" );
tree_component . drag_drop . origin_tree = _this ;
counter ++ ;
}
}
if ( counter > 0 ) {
if ( _this . check ( "draggable" , obj )) tree_component . drag_drop . drag_node = obj ;
else tree_component . drag_drop . drag_node = _this . container . find ( "li.dragged:eq(0)" );
tree_component . drag_drop . isdown = true ;
tree_component . drag_drop . drag_help = $ ( "<div id='jstree-dragged' class='tree " + ( _this . settings . ui . theme_name != "" ? " tree-" + _this . settings . ui . theme_name : "" ) + "' />" ). append ( "<ul class='" + _this . container . children ( "ul:eq(0)" ). get ( 0 ). className + "' />" );
var tmp = tree_component . drag_drop . drag_node . clone ();
if ( _this . settings . languages . length > 0 ) tmp . find ( "a" ). not ( "." + _this . current_lang ). hide ();
tree_component . drag_drop . drag_help . children ( "ul:eq(0)" ). append ( tmp );
tree_component . drag_drop . drag_help . find ( "li:eq(0)" ). removeClass ( "last" ). addClass ( "last" ). children ( "a" ). html ( "<ins> </ins>Multiple selection" ). end (). children ( "ul" ). remove ();
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
tree_component . drag_drop . dragged = _this . container . find ( "li.dragged" );
}
}
else {
if ( _this . check ( "draggable" , obj )) {
tree_component . drag_drop . drag_node = obj ;
tree_component . drag_drop . drag_help = $ ( "<div id='jstree-dragged' class='tree " + ( _this . settings . ui . theme_name != "" ? " tree-" + _this . settings . ui . theme_name : "" ) + "' />" ). append ( "<ul class='" + _this . container . children ( "ul:eq(0)" ). get ( 0 ). className + "' />" );
var tmp = obj . clone ();
if ( _this . settings . languages . length > 0 ) tmp . find ( "a" ). not ( "." + _this . current_lang ). hide ();
tree_component . drag_drop . drag_help . children ( "ul:eq(0)" ). append ( tmp );
tree_component . drag_drop . drag_help . find ( "li:eq(0)" ). removeClass ( "last" ). addClass ( "last" );
tree_component . drag_drop . isdown = true ;
tree_component . drag_drop . foreign = false ;
tree_component . drag_drop . origin_tree = _this ;
obj . addClass ( "dragged" );
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
tree_component . drag_drop . dragged = _this . container . find ( "li.dragged" );
}
}
tree_component . drag_drop . init_x = event . pageX ;
tree_component . drag_drop . init_y = event . pageY ;
obj . blur ();
event . preventDefault ();
event . stopPropagation ();
return false ;
2009-10-11 12:23:27 +00:00
});
2010-03-16 15:05:05 +00:00
},
2010-06-23 23:19:49 +00:00
focus : function () {
2010-03-16 15:05:05 +00:00
if ( this . locked ) return false ;
if ( tree_component . focused != this . cntr ) {
tree_component . focused = this . cntr ;
this . callback ( "onfocus" , [ this ]);
}
},
2009-10-11 12:23:27 +00:00
2010-06-23 23:19:49 +00:00
off_height : function () {
2010-03-16 15:05:05 +00:00
if ( this . offset === false ) {
this . container . css ({ position : "relative" });
this . offset = this . container . offset ();
var tmp = 0 ;
tmp = parseInt ( $ . curCSS ( this . container . get ( 0 ), "paddingTop" , true ), 10 );
if ( tmp ) this . offset . top += tmp ;
tmp = parseInt ( $ . curCSS ( this . container . get ( 0 ), "borderTopWidth" , true ), 10 );
if ( tmp ) this . offset . top += tmp ;
this . container . css ({ position : "" });
}
if ( ! this . li_height ) {
var tmp = this . container . find ( "ul li.closed, ul li.leaf" ). eq ( 0 );
this . li_height = tmp . height ();
if ( tmp . children ( "ul:eq(0)" ). size ()) this . li_height -= tmp . children ( "ul:eq(0)" ). height ();
if ( ! this . li_height ) this . li_height = 18 ;
}
},
2010-06-23 23:19:49 +00:00
scroll_check : function ( x , y ) {
2010-03-16 15:05:05 +00:00
var _this = this ;
var cnt = _this . container ;
var off = _this . container . offset ();
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
var st = cnt . scrollTop ();
var sl = cnt . scrollLeft ();
// DETECT HORIZONTAL SCROLL
var h_cor = ( cnt . get ( 0 ). scrollWidth > cnt . width ()) ? 40 : 20 ;
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
if ( y - off . top < 20 ) cnt . scrollTop ( Math . max (( st - _this . settings . ui . scroll_spd ), 0 )); // NEAR TOP
if ( cnt . height () - ( y - off . top ) < h_cor ) cnt . scrollTop ( st + _this . settings . ui . scroll_spd ); // NEAR BOTTOM
if ( x - off . left < 20 ) cnt . scrollLeft ( Math . max (( sl - _this . settings . ui . scroll_spd ), 0 )); // NEAR LEFT
if ( cnt . width () - ( x - off . left ) < 40 ) cnt . scrollLeft ( sl + _this . settings . ui . scroll_spd ); // NEAR RIGHT
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
if ( cnt . scrollLeft () != sl || cnt . scrollTop () != st ) {
tree_component . drag_drop . move_type = false ;
tree_component . drag_drop . ref_node = false ;
tree_component . drag_drop . marker . hide ();
}
2010-06-23 23:19:49 +00:00
tree_component . drag_drop . scroll_time = setTimeout ( function () { _this . scroll_check ( x , y ); }, 50 );
2010-03-16 15:05:05 +00:00
},
2010-06-23 23:19:49 +00:00
scroll_into_view : function ( obj ) {
2010-03-16 15:05:05 +00:00
obj = obj ? this . get_node ( obj ) : this . selected ;
if ( ! obj ) return false ;
var off_t = obj . offset (). top ;
var beg_t = this . container . offset (). top ;
var end_t = beg_t + this . container . height ();
var h_cor = ( this . container . get ( 0 ). scrollWidth > this . container . width ()) ? 40 : 20 ;
if ( off_t + 5 < beg_t ) this . container . scrollTop ( this . container . scrollTop () - ( beg_t - off_t + 5 ));
if ( off_t + h_cor > end_t ) this . container . scrollTop ( this . container . scrollTop () + ( off_t + h_cor - end_t ));
},
2009-10-11 12:23:27 +00:00
2010-06-23 23:19:49 +00:00
get_node : function ( obj ) {
2010-03-16 15:05:05 +00:00
return $ ( obj ). closest ( "li" );
},
2010-06-23 23:19:49 +00:00
get_type : function ( obj ) {
2010-03-16 15:05:05 +00:00
obj = ! obj ? this . selected : this . get_node ( obj );
if ( ! obj ) return ;
var tmp = obj . attr ( this . settings . rules . type_attr );
return tmp || "default" ;
},
2010-06-23 23:19:49 +00:00
set_type : function ( str , obj ) {
2010-03-16 15:05:05 +00:00
obj = ! obj ? this . selected : this . get_node ( obj );
if ( ! obj || ! str ) return ;
obj . attr ( this . settings . rules . type_attr , str );
},
2010-06-23 23:19:49 +00:00
get_text : function ( obj , lang ) {
2010-03-16 15:05:05 +00:00
obj = this . get_node ( obj );
if ( ! obj || obj . size () == 0 ) return "" ;
if ( this . settings . languages && this . settings . languages . length ) {
lang = lang ? lang : this . current_lang ;
obj = obj . children ( "a." + lang );
}
else obj = obj . children ( "a:visible" );
var val = "" ;
2010-06-23 23:19:49 +00:00
obj . contents (). each ( function () {
2010-03-16 15:05:05 +00:00
if ( this . nodeType == 3 ) { val = this . data ; return false ; }
});
return val ;
},
2009-10-11 12:23:27 +00:00
2010-06-23 23:19:49 +00:00
check : function ( rule , obj ) {
2010-03-16 15:05:05 +00:00
if ( this . locked ) return false ;
var v = false ;
// if root node
if ( obj === - 1 ) { if ( typeof this . settings . rules [ rule ] != "undefined" ) v = this . settings . rules [ rule ]; }
else {
obj = ! obj ? this . selected : this . get_node ( obj );
if ( ! obj ) return ;
var t = this . get_type ( obj );
if ( typeof this . settings . types [ t ] != "undefined" && typeof this . settings . types [ t ][ rule ] != "undefined" ) v = this . settings . types [ t ][ rule ];
else if ( typeof this . settings . types [ "default" ] != "undefined" && typeof this . settings . types [ "default" ][ rule ] != "undefined" ) v = this . settings . types [ "default" ][ rule ];
}
if ( typeof v == "function" ) v = v . call ( null , obj , this );
v = this . callback ( "check" , [ rule , obj , v , this ]);
return v ;
},
2010-06-23 23:19:49 +00:00
check_move : function ( nod , ref_node , how ) {
2010-03-16 15:05:05 +00:00
if ( this . locked ) return false ;
if ( $ ( ref_node ). closest ( "li.dragged" ). size ()) return false ;
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
var tree1 = nod . parents ( ".tree:eq(0)" ). get ( 0 );
var tree2 = ref_node . parents ( ".tree:eq(0)" ). get ( 0 );
// if different trees
if ( tree1 && tree1 != tree2 ) {
var m = $ . tree . reference ( tree2 . id ). settings . rules . multitree ;
if ( m == "none" || ( $ . isArray ( m ) && $ . inArray ( tree1 . id , m ) == - 1 )) return false ;
}
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
var p = ( how != "inside" ) ? this . parent ( ref_node ) : this . get_node ( ref_node );
nod = this . get_node ( nod );
if ( p == false ) return false ;
var r = {
max_depth : this . settings . rules . use_max_depth ? this . check ( "max_depth" , p ) : - 1 ,
max_children : this . settings . rules . use_max_children ? this . check ( "max_children" , p ) : - 1 ,
valid_children : this . check ( "valid_children" , p )
};
var nod_type = ( typeof nod == "string" ) ? nod : this . get_type ( nod );
if ( typeof r . valid_children != "undefined" && ( r . valid_children == "none" || ( typeof r . valid_children == "object" && $ . inArray ( nod_type , $ . makeArray ( r . valid_children )) == - 1 ))) return false ;
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
if ( this . settings . rules . use_max_children ) {
if ( typeof r . max_children != "undefined" && r . max_children != - 1 ) {
if ( r . max_children == 0 ) return false ;
var c_count = 1 ;
if ( tree_component . drag_drop . moving == true && tree_component . drag_drop . foreign == false ) {
c_count = tree_component . drag_drop . dragged . size ();
c_count = c_count - p . find ( '> ul > li.dragged' ). size ();
}
if ( r . max_children < p . find ( '> ul > li' ). size () + c_count ) return false ;
}
}
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
if ( this . settings . rules . use_max_depth ) {
if ( typeof r . max_depth != "undefined" && r . max_depth === 0 ) return this . error ( "MOVE: MAX-DEPTH REACHED" );
// check for max_depth up the chain
var mx = ( r . max_depth > 0 ) ? r . max_depth : false ;
var i = 0 ;
var t = p ;
while ( t !== - 1 ) {
t = this . parent ( t );
i ++ ;
var m = this . check ( "max_depth" , t );
if ( m >= 0 ) {
mx = ( mx === false ) ? ( m - i ) : Math . min ( mx , m - i );
}
if ( mx !== false && mx <= 0 ) return this . error ( "MOVE: MAX-DEPTH REACHED" );
}
if ( mx !== false && mx <= 0 ) return this . error ( "MOVE: MAX-DEPTH REACHED" );
if ( mx !== false ) {
var incr = 1 ;
if ( typeof nod != "string" ) {
var t = nod ;
// possible async problem - when nodes are not all loaded down the chain
while ( t . size () > 0 ) {
if ( mx - incr < 0 ) return this . error ( "MOVE: MAX-DEPTH REACHED" );
t = t . children ( "ul" ). children ( "li" );
incr ++ ;
}
}
}
}
if ( this . callback ( "check_move" , [ nod , ref_node , how , this ]) == false ) return false ;
return true ;
},
2009-10-11 12:23:27 +00:00
2010-06-23 23:19:49 +00:00
hover_branch : function ( obj ) {
2010-03-16 15:05:05 +00:00
if ( this . locked ) return this . error ( "LOCKED" );
var _this = this ;
var obj = _this . get_node ( obj );
if ( ! obj . size ()) return this . error ( "HOVER: NOT A VALID NODE" );
if ( ! _this . check ( "clickable" , obj )) return this . error ( "SELECT: NODE NOT SELECTABLE" );
if ( this . hovered ) this . hovered . children ( "A" ). removeClass ( "hover" );
this . hovered = obj ;
this . hovered . children ( "a" ). addClass ( "hover" );
this . scroll_into_view ( this . hovered );
},
2010-06-23 23:19:49 +00:00
select_branch : function ( obj , multiple ) {
2010-03-16 15:05:05 +00:00
if ( this . locked ) return this . error ( "LOCKED" );
if ( ! obj && this . hovered !== false ) obj = this . hovered ;
var _this = this ;
obj = _this . get_node ( obj );
if ( ! obj . size ()) return this . error ( "SELECT: NOT A VALID NODE" );
obj . children ( "a" ). removeClass ( "hover" );
// CHECK AGAINST RULES FOR SELECTABLE NODES
if ( ! _this . check ( "clickable" , obj )) return this . error ( "SELECT: NODE NOT SELECTABLE" );
if ( _this . callback ( "beforechange" , [ obj . get ( 0 ), _this ]) === false ) return this . error ( "SELECT: STOPPED BY USER" );
// IF multiple AND obj IS ALREADY SELECTED - DESELECT IT
if ( this . settings . rules . multiple != false && multiple && obj . children ( "a.clicked" ). size () > 0 ) {
return this . deselect_branch ( obj );
}
if ( this . settings . rules . multiple != false && multiple ) {
this . selected_arr . push ( obj );
}
if ( this . settings . rules . multiple != false && ! multiple ) {
for ( var i in this . selected_arr ) {
if ( ! this . selected_arr . hasOwnProperty ( i )) continue ;
this . selected_arr [ i ]. children ( "A" ). removeClass ( "clicked" );
this . callback ( "ondeselect" , [ this . selected_arr [ i ]. get ( 0 ), _this ]);
}
this . selected_arr = [];
this . selected_arr . push ( obj );
if ( this . selected && this . selected . children ( "A" ). hasClass ( "clicked" )) {
this . selected . children ( "A" ). removeClass ( "clicked" );
this . callback ( "ondeselect" , [ this . selected . get ( 0 ), _this ]);
}
}
if ( ! this . settings . rules . multiple ) {
if ( this . selected ) {
this . selected . children ( "A" ). removeClass ( "clicked" );
this . callback ( "ondeselect" , [ this . selected . get ( 0 ), _this ]);
}
}
// SAVE NEWLY SELECTED
this . selected = obj ;
if ( this . hovered !== false ) {
this . hovered . children ( "A" ). removeClass ( "hover" );
this . hovered = obj ;
}
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
// FOCUS NEW NODE AND OPEN ALL PARENT NODES IF CLOSED
2010-06-23 23:19:49 +00:00
this . selected . children ( "a" ). addClass ( "clicked" ). end (). parents ( "li.closed" ). each ( function () { _this . open_branch ( this , true ); });
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
// SCROLL SELECTED NODE INTO VIEW
this . scroll_into_view ( this . selected );
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
this . callback ( "onselect" , [ this . selected . get ( 0 ), _this ]);
this . callback ( "onchange" , [ this . selected . get ( 0 ), _this ]);
},
2010-06-23 23:19:49 +00:00
deselect_branch : function ( obj ) {
2010-03-16 15:05:05 +00:00
if ( this . locked ) return this . error ( "LOCKED" );
var _this = this ;
var obj = this . get_node ( obj );
if ( obj . children ( "a.clicked" ). size () == 0 ) return this . error ( "DESELECT: NODE NOT SELECTED" );
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
obj . children ( "a" ). removeClass ( "clicked" );
this . callback ( "ondeselect" , [ obj . get ( 0 ), _this ]);
if ( this . settings . rules . multiple != false && this . selected_arr . length > 1 ) {
this . selected_arr = [];
2010-06-23 23:19:49 +00:00
this . container . find ( "a.clicked" ). filter ( ":first-child" ). parent (). each ( function () {
2010-03-16 15:05:05 +00:00
_this . selected_arr . push ( $ ( this ));
});
if ( obj . get ( 0 ) == this . selected . get ( 0 )) {
this . selected = this . selected_arr [ 0 ];
}
}
else {
if ( this . settings . rules . multiple != false ) this . selected_arr = [];
this . selected = false ;
}
this . callback ( "onchange" , [ obj . get ( 0 ), _this ]);
},
2010-06-23 23:19:49 +00:00
toggle_branch : function ( obj ) {
2010-03-16 15:05:05 +00:00
if ( this . locked ) return this . error ( "LOCKED" );
var obj = this . get_node ( obj );
if ( obj . hasClass ( "closed" )) return this . open_branch ( obj );
if ( obj . hasClass ( "open" )) return this . close_branch ( obj );
},
2010-06-23 23:19:49 +00:00
open_branch : function ( obj , disable_animation , callback ) {
2010-03-16 15:05:05 +00:00
var _this = this ;
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
if ( this . locked ) return this . error ( "LOCKED" );
var obj = this . get_node ( obj );
if ( ! obj . size ()) return this . error ( "OPEN: NO SUCH NODE" );
if ( obj . hasClass ( "leaf" )) return this . error ( "OPEN: OPENING LEAF NODE" );
if ( this . settings . data . async && obj . find ( "li" ). size () == 0 ) {
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
if ( this . callback ( "beforeopen" , [ obj . get ( 0 ), this ]) === false ) return this . error ( "OPEN: STOPPED BY USER" );
obj . children ( "ul:eq(0)" ). remove (). end (). append ( "<ul><li class='last'><a class='loading' href='#'><ins> </ins>" + ( _this . settings . lang . loading || "Loading ..." ) + "</a></li></ul>" );
obj . removeClass ( "closed" ). addClass ( "open" );
var _datastore = new $ . tree . datastores [ this . settings . data . type ]();
2010-06-23 23:19:49 +00:00
_datastore . load ( this . callback ( "beforedata" , [ obj , this ]), this , this . settings . data . opts , function ( data ) {
2010-03-16 15:05:05 +00:00
data = _this . callback ( "ondata" , [ data , _this ]);
if ( ! data || data . length == 0 ) {
obj . removeClass ( "closed" ). removeClass ( "open" ). addClass ( "leaf" ). children ( "ul" ). remove ();
if ( callback ) callback . call ();
return ;
}
2010-06-23 23:19:49 +00:00
_datastore . parse ( data , _this , _this . settings . data . opts , function ( str ) {
2010-03-16 15:05:05 +00:00
str = _this . callback ( "onparse" , [ str , _this ]);
// if(obj.children('ul:eq(0)').children('li').size() > 1) obj.children("ul").find('.loaading').parent().replaceWith(str); else
obj . children ( "ul:eq(0)" ). replaceWith ( $ ( "<ul>" ). html ( str ));
obj . find ( "li:last-child" ). addClass ( "last" ). end (). find ( "li:has(ul)" ). not ( ".open" ). addClass ( "closed" );
obj . find ( "li" ). not ( ".open" ). not ( ".closed" ). addClass ( "leaf" );
_this . open_branch . apply ( _this , [ obj ]);
if ( callback ) callback . call ();
});
});
return true ;
}
else {
if ( ! this . settings . data . async ) {
if ( this . callback ( "beforeopen" , [ obj . get ( 0 ), this ]) === false ) return this . error ( "OPEN: STOPPED BY USER" );
}
if ( parseInt ( this . settings . ui . animation ) > 0 && ! disable_animation ) {
obj . children ( "ul:eq(0)" ). css ( "display" , "none" );
obj . removeClass ( "closed" ). addClass ( "open" );
2010-06-23 23:19:49 +00:00
obj . children ( "ul:eq(0)" ). slideDown ( parseInt ( this . settings . ui . animation ), function () {
2010-03-16 15:05:05 +00:00
$ ( this ). css ( "display" , "" );
if ( callback ) callback . call ();
});
} else {
obj . removeClass ( "closed" ). addClass ( "open" );
if ( callback ) callback . call ();
}
this . callback ( "onopen" , [ obj . get ( 0 ), this ]);
return true ;
}
},
2010-06-23 23:19:49 +00:00
close_branch : function ( obj , disable_animation ) {
2010-03-16 15:05:05 +00:00
if ( this . locked ) return this . error ( "LOCKED" );
var _this = this ;
var obj = this . get_node ( obj );
if ( ! obj . size ()) return this . error ( "CLOSE: NO SUCH NODE" );
if ( _this . callback ( "beforeclose" , [ obj . get ( 0 ), _this ]) === false ) return this . error ( "CLOSE: STOPPED BY USER" );
if ( parseInt ( this . settings . ui . animation ) > 0 && ! disable_animation && obj . children ( "ul:eq(0)" ). size () == 1 ) {
2010-06-23 23:19:49 +00:00
obj . children ( "ul:eq(0)" ). slideUp ( parseInt ( this . settings . ui . animation ), function () {
2010-03-16 15:05:05 +00:00
if ( obj . hasClass ( "open" )) obj . removeClass ( "open" ). addClass ( "closed" );
$ ( this ). css ( "display" , "" );
});
}
else {
if ( obj . hasClass ( "open" )) obj . removeClass ( "open" ). addClass ( "closed" );
}
if ( this . selected && this . settings . ui . selected_parent_close !== false && obj . children ( "ul:eq(0)" ). find ( "a.clicked" ). size () > 0 ) {
2010-06-23 23:19:49 +00:00
obj . find ( "li:has(a.clicked)" ). each ( function () {
2010-03-16 15:05:05 +00:00
_this . deselect_branch ( this );
});
if ( this . settings . ui . selected_parent_close == "select_parent" && obj . children ( "a.clicked" ). size () == 0 ) this . select_branch ( obj , ( this . settings . rules . multiple != false && this . selected_arr . length > 0 ));
}
this . callback ( "onclose" , [ obj . get ( 0 ), this ]);
},
2010-06-23 23:19:49 +00:00
open_all : function ( obj , callback ) {
2010-03-16 15:05:05 +00:00
if ( this . locked ) return this . error ( "LOCKED" );
var _this = this ;
obj = obj ? this . get_node ( obj ) : this . container ;
var s = obj . find ( "li.closed" ). size ();
if ( ! callback ) this . cl_count = 0 ;
else this . cl_count -- ;
if ( s > 0 ) {
this . cl_count += s ;
// maybe add .andSelf()
2010-06-23 23:19:49 +00:00
obj . find ( "li.closed" ). each ( function () { var __this = this ; _this . open_branch . apply ( _this , [ this , true , function () { _this . open_all . apply ( _this , [ __this , true ]); } ]); });
2010-03-16 15:05:05 +00:00
}
else if ( this . cl_count == 0 ) this . callback ( "onopen_all" , [ this ]);
},
2010-06-23 23:19:49 +00:00
close_all : function ( obj ) {
2010-03-16 15:05:05 +00:00
if ( this . locked ) return this . error ( "LOCKED" );
var _this = this ;
obj = obj ? this . get_node ( obj ) : this . container ;
// maybe add .andSelf()
2010-06-23 23:19:49 +00:00
obj . find ( "li.open" ). each ( function () { _this . close_branch ( this , true ); });
2010-03-16 15:05:05 +00:00
this . callback ( "onclose_all" , [ this ]);
},
2010-06-23 23:19:49 +00:00
set_lang : function ( i ) {
2010-03-16 15:05:05 +00:00
if ( ! $ . isArray ( this . settings . languages ) || this . settings . languages . length == 0 ) return false ;
if ( this . locked ) return this . error ( "LOCKED" );
if ( ! $ . inArray ( i , this . settings . languages ) && typeof this . settings . languages [ i ] != "undefined" ) i = this . settings . languages [ i ];
if ( typeof i == "undefined" ) return false ;
if ( i == this . current_lang ) return true ;
var st = false ;
var id = "#" + this . container . attr ( "id" );
st = tree_component . get_css ( id + " ." + this . current_lang );
if ( st !== false ) st . style . display = "none" ;
st = tree_component . get_css ( id + " ." + i );
if ( st !== false ) st . style . display = "" ;
this . current_lang = i ;
return true ;
},
2010-06-23 23:19:49 +00:00
get_lang : function () {
2010-03-16 15:05:05 +00:00
if ( ! $ . isArray ( this . settings . languages ) || this . settings . languages . length == 0 ) return false ;
return this . current_lang ;
},
2010-06-23 23:19:49 +00:00
create : function ( obj , ref_node , position ) {
2010-03-16 15:05:05 +00:00
if ( this . locked ) return this . error ( "LOCKED" );
var root = false ;
if ( ref_node == - 1 ) { root = true ; ref_node = this . container ; }
else ref_node = ref_node ? this . get_node ( ref_node ) : this . selected ;
if ( ! root && ( ! ref_node || ! ref_node . size ())) return this . error ( "CREATE: NO NODE SELECTED" );
var pos = position ;
var tmp = ref_node ; // for type calculation
if ( position == "before" ) {
position = ref_node . parent (). children (). index ( ref_node );
ref_node = ref_node . parents ( "li:eq(0)" );
}
if ( position == "after" ) {
position = ref_node . parent (). children (). index ( ref_node ) + 1 ;
ref_node = ref_node . parents ( "li:eq(0)" );
}
if ( ! root && ref_node . size () == 0 ) { root = true ; ref_node = this . container ; }
if ( ! root ) {
if ( ! this . check ( "creatable" , ref_node )) return this . error ( "CREATE: CANNOT CREATE IN NODE" );
if ( ref_node . hasClass ( "closed" )) {
if ( this . settings . data . async && ref_node . children ( "ul" ). size () == 0 ) {
var _this = this ;
2010-06-23 23:19:49 +00:00
return this . open_branch ( ref_node , true , function () { _this . create . apply ( _this , [ obj , ref_node , position ]); });
2010-03-16 15:05:05 +00:00
}
else this . open_branch ( ref_node , true );
}
}
// creating new object to pass to parseJSON
var torename = false ;
if ( ! obj ) obj = {};
else obj = $ . extend ( true , {}, obj );
if ( ! obj . attributes ) obj . attributes = {};
if ( ! obj . attributes [ this . settings . rules . type_attr ]) obj . attributes [ this . settings . rules . type_attr ] = this . get_type ( tmp ) || "default" ;
if ( this . settings . languages . length ) {
if ( ! obj . data ) { obj . data = {}; torename = true ; }
for ( var i = 0 ; i < this . settings . languages . length ; i ++ ) {
if ( ! obj . data [ this . settings . languages [ i ]]) obj . data [ this . settings . languages [ i ]] = (( typeof this . settings . lang . new_node ). toLowerCase () != "string" && this . settings . lang . new_node [ i ]) ? this . settings . lang . new_node [ i ] : this . settings . lang . new_node ;
}
}
else {
if ( ! obj . data ) { obj . data = this . settings . lang . new_node ; torename = true ; }
}
obj = this . callback ( "ondata" , [ obj , this ]);
var obj_s = $ . tree . datastores . json (). parse ( obj , this );
obj_s = this . callback ( "onparse" , [ obj_s , this ]);
var $li = $ ( obj_s );
if ( $li . children ( "ul" ). size ()) {
if ( ! $li . is ( ".open" )) $li . addClass ( "closed" );
}
else $li . addClass ( "leaf" );
$li . find ( "li:last-child" ). addClass ( "last" ). end (). find ( "li:has(ul)" ). not ( ".open" ). addClass ( "closed" );
$li . find ( "li" ). not ( ".open" ). not ( ".closed" ). addClass ( "leaf" );
var r = {
max_depth : this . settings . rules . use_max_depth ? this . check ( "max_depth" , ( root ? - 1 : ref_node )) : - 1 ,
max_children : this . settings . rules . use_max_children ? this . check ( "max_children" , ( root ? - 1 : ref_node )) : - 1 ,
valid_children : this . check ( "valid_children" , ( root ? - 1 : ref_node ))
};
var nod_type = this . get_type ( $li );
if ( typeof r . valid_children != "undefined" && ( r . valid_children == "none" || ( $ . isArray ( r . valid_children ) && $ . inArray ( nod_type , r . valid_children ) == - 1 ))) return this . error ( "CREATE: NODE NOT A VALID CHILD" );
if ( this . settings . rules . use_max_children ) {
if ( typeof r . max_children != "undefined" && r . max_children != - 1 && r . max_children >= this . children ( ref_node ). size ()) return this . error ( "CREATE: MAX_CHILDREN REACHED" );
}
if ( this . settings . rules . use_max_depth ) {
if ( typeof r . max_depth != "undefined" && r . max_depth === 0 ) return this . error ( "CREATE: MAX-DEPTH REACHED" );
// check for max_depth up the chain
var mx = ( r . max_depth > 0 ) ? r . max_depth : false ;
var i = 0 ;
var t = ref_node ;
while ( t !== - 1 && ! root ) {
t = this . parent ( t );
i ++ ;
var m = this . check ( "max_depth" , t );
if ( m >= 0 ) {
mx = ( mx === false ) ? ( m - i ) : Math . min ( mx , m - i );
}
if ( mx !== false && mx <= 0 ) return this . error ( "CREATE: MAX-DEPTH REACHED" );
}
if ( mx !== false && mx <= 0 ) return this . error ( "CREATE: MAX-DEPTH REACHED" );
if ( mx !== false ) {
var incr = 1 ;
var t = $li ;
while ( t . size () > 0 ) {
if ( mx - incr < 0 ) return this . error ( "CREATE: MAX-DEPTH REACHED" );
t = t . children ( "ul" ). children ( "li" );
incr ++ ;
}
}
}
if (( typeof position ). toLowerCase () == "undefined" || position == "inside" )
position = ( this . settings . rules . createat == "top" ) ? 0 : ref_node . children ( "ul:eq(0)" ). children ( "li" ). size ();
if ( ref_node . children ( "ul" ). size () == 0 || ( root == true && ref_node . children ( "ul" ). children ( "li" ). size () == 0 )) {
if ( ! root ) var a = this . moved ( $li , ref_node . children ( "a:eq(0)" ), "inside" , true );
else var a = this . moved ( $li , this . container . children ( "ul:eq(0)" ), "inside" , true );
}
else if ( pos == "before" && ref_node . children ( "ul:eq(0)" ). children ( "li:nth-child(" + ( position + 1 ) + ")" ). size ())
var a = this . moved ( $li , ref_node . children ( "ul:eq(0)" ). children ( "li:nth-child(" + ( position + 1 ) + ")" ). children ( "a:eq(0)" ), "before" , true );
else if ( pos == "after" && ref_node . children ( "ul:eq(0)" ). children ( "li:nth-child(" + ( position ) + ")" ). size ())
var a = this . moved ( $li , ref_node . children ( "ul:eq(0)" ). children ( "li:nth-child(" + ( position ) + ")" ). children ( "a:eq(0)" ), "after" , true );
else if ( ref_node . children ( "ul:eq(0)" ). children ( "li:nth-child(" + ( position + 1 ) + ")" ). size ())
var a = this . moved ( $li , ref_node . children ( "ul:eq(0)" ). children ( "li:nth-child(" + ( position + 1 ) + ")" ). children ( "a:eq(0)" ), "before" , true );
else
var a = this . moved ( $li , ref_node . children ( "ul:eq(0)" ). children ( "li:last" ). children ( "a:eq(0)" ), "after" , true );
if ( a === false ) return this . error ( "CREATE: ABORTED" );
if ( torename ) {
this . select_branch ( $li . children ( "a:eq(0)" ));
this . rename ();
}
return $li ;
},
2010-06-23 23:19:49 +00:00
rename : function ( obj , new_name ) {
2010-03-16 15:05:05 +00:00
if ( this . locked ) return this . error ( "LOCKED" );
obj = obj ? this . get_node ( obj ) : this . selected ;
var _this = this ;
if ( ! obj || ! obj . size ()) return this . error ( "RENAME: NO NODE SELECTED" );
if ( ! this . check ( "renameable" , obj )) return this . error ( "RENAME: NODE NOT RENAMABLE" );
if ( ! this . callback ( "beforerename" , [ obj . get ( 0 ), _this . current_lang , _this ])) return this . error ( "RENAME: STOPPED BY USER" );
2010-06-23 23:19:49 +00:00
obj . parents ( "li.closed" ). each ( function () { _this . open_branch ( this ) });
2010-03-16 15:05:05 +00:00
if ( this . current_lang ) obj = obj . find ( "a." + this . current_lang );
else obj = obj . find ( "a:first" );
// Rollback
var rb = {};
rb [ this . container . attr ( "id" )] = this . get_rollback ();
var icn = obj . children ( "ins" ). clone ();
if (( typeof new_name ). toLowerCase () == "string" ) {
obj . text ( new_name ). prepend ( icn );
_this . callback ( "onrename" , [ _this . get_node ( obj ). get ( 0 ), _this , rb ]);
}
else {
var last_value = "" ;
2010-06-23 23:19:49 +00:00
obj . contents (). each ( function () {
2010-03-16 15:05:05 +00:00
if ( this . nodeType == 3 ) { last_value = this . data ; return false ; }
});
_this . inp = $ ( "<input type='text' autocomplete='off' />" );
_this . inp
. val ( last_value . replace ( /&/g , "&" ). replace ( />/g , ">" ). replace ( /</g , "<" ))
2010-06-23 23:19:49 +00:00
. bind ( "mousedown" , function ( event ) { event . stopPropagation (); })
. bind ( "mouseup" , function ( event ) { event . stopPropagation (); })
. bind ( "click" , function ( event ) { event . stopPropagation (); })
. bind ( "keyup" , function ( event ) {
2010-03-16 15:05:05 +00:00
var key = event . keyCode || event . which ;
if ( key == 27 ) { this . value = last_value ; this . blur (); return }
if ( key == 13 ) { this . blur (); return ; }
2009-10-11 12:23:27 +00:00
});
2010-06-23 23:19:49 +00:00
_this . inp . blur ( function ( event ) {
2010-03-16 15:05:05 +00:00
if ( this . value == "" ) this . value = last_value ;
obj . text ( this . value ). prepend ( icn );
obj . get ( 0 ). style . display = "" ;
obj . prevAll ( "span" ). remove ();
_this . inp = false ;
_this . callback ( "onrename" , [ _this . get_node ( obj ). get ( 0 ), _this , rb ]);
});
var spn = $ ( "<span />" ). addClass ( obj . attr ( "class" )). append ( icn ). append ( _this . inp );
obj . get ( 0 ). style . display = "none" ;
obj . parent (). prepend ( spn );
_this . inp . get ( 0 ). focus ();
_this . inp . get ( 0 ). select ();
}
},
2010-06-23 23:19:49 +00:00
remove : function ( obj ) {
2010-03-16 15:05:05 +00:00
if ( this . locked ) return this . error ( "LOCKED" );
var _this = this ;
// Rollback
var rb = {};
rb [ this . container . attr ( "id" )] = this . get_rollback ();
if ( obj && ( ! this . selected || this . get_node ( obj ). get ( 0 ) != this . selected . get ( 0 ))) {
obj = this . get_node ( obj );
if ( obj . size ()) {
if ( ! this . check ( "deletable" , obj )) return this . error ( "DELETE: NODE NOT DELETABLE" );
if ( ! this . callback ( "beforedelete" , [ obj . get ( 0 ), _this ])) return this . error ( "DELETE: STOPPED BY USER" );
$parent = obj . parent ();
if ( obj . find ( "a.clicked" ). size ()) {
var reset_selected = false ;
_this . selected_arr = [];
2010-06-23 23:19:49 +00:00
this . container . find ( "a.clicked" ). filter ( ":first-child" ). parent (). each ( function () {
2010-03-16 15:05:05 +00:00
if ( ! reset_selected && this == _this . selected . get ( 0 )) reset_selected = true ;
if ( $ ( this ). parents (). index ( obj ) != - 1 ) return true ;
_this . selected_arr . push ( $ ( this ));
});
if ( reset_selected ) this . selected = this . selected_arr [ 0 ] || false ;
}
obj = obj . remove ();
$parent . children ( "li:last" ). addClass ( "last" );
if ( $parent . children ( "li" ). size () == 0 ) {
$li = $parent . parents ( "li:eq(0)" );
$li . removeClass ( "open" ). removeClass ( "closed" ). addClass ( "leaf" ). children ( "ul" ). remove ();
}
this . callback ( "ondelete" , [ obj . get ( 0 ), this , rb ]);
}
}
else if ( this . selected ) {
if ( ! this . check ( "deletable" , this . selected )) return this . error ( "DELETE: NODE NOT DELETABLE" );
if ( ! this . callback ( "beforedelete" , [ this . selected . get ( 0 ), _this ])) return this . error ( "DELETE: STOPPED BY USER" );
$parent = this . selected . parent ();
var obj = this . selected ;
if ( this . settings . rules . multiple == false || this . selected_arr . length == 1 ) {
var stop = true ;
var tmp = this . settings . ui . selected_delete == "select_previous" ? this . prev ( this . selected ) : false ;
}
obj = obj . remove ();
$parent . children ( "li:last" ). addClass ( "last" );
if ( $parent . children ( "li" ). size () == 0 ) {
$li = $parent . parents ( "li:eq(0)" );
$li . removeClass ( "open" ). removeClass ( "closed" ). addClass ( "leaf" ). children ( "ul" ). remove ();
}
if ( ! stop && this . settings . rules . multiple != false ) {
var _this = this ;
this . selected_arr = [];
2010-06-23 23:19:49 +00:00
this . container . find ( "a.clicked" ). filter ( ":first-child" ). parent (). each ( function () {
2010-03-16 15:05:05 +00:00
_this . selected_arr . push ( $ ( this ));
});
if ( this . selected_arr . length > 0 ) {
this . selected = this . selected_arr [ 0 ];
this . remove ();
}
}
if ( stop && tmp ) this . select_branch ( tmp );
this . callback ( "ondelete" , [ obj . get ( 0 ), this , rb ]);
}
else return this . error ( "DELETE: NO NODE SELECTED" );
},
2010-06-23 23:19:49 +00:00
next : function ( obj , strict ) {
2010-03-16 15:05:05 +00:00
obj = this . get_node ( obj );
if ( ! obj . size ()) return false ;
if ( strict ) return ( obj . nextAll ( "li" ). size () > 0 ) ? obj . nextAll ( "li:eq(0)" ) : false ;
if ( obj . hasClass ( "open" )) return obj . find ( "li:eq(0)" );
else if ( obj . nextAll ( "li" ). size () > 0 ) return obj . nextAll ( "li:eq(0)" );
else return obj . parents ( "li" ). next ( "li" ). eq ( 0 );
},
2010-06-23 23:19:49 +00:00
prev : function ( obj , strict ) {
2010-03-16 15:05:05 +00:00
obj = this . get_node ( obj );
if ( ! obj . size ()) return false ;
if ( strict ) return ( obj . prevAll ( "li" ). size () > 0 ) ? obj . prevAll ( "li:eq(0)" ) : false ;
if ( obj . prev ( "li" ). size ()) {
var obj = obj . prev ( "li" ). eq ( 0 );
while ( obj . hasClass ( "open" )) obj = obj . children ( "ul:eq(0)" ). children ( "li:last" );
return obj ;
}
else return obj . parents ( "li:eq(0)" ). size () ? obj . parents ( "li:eq(0)" ) : false ;
},
2010-06-23 23:19:49 +00:00
parent : function ( obj ) {
2010-03-16 15:05:05 +00:00
obj = this . get_node ( obj );
if ( ! obj . size ()) return false ;
return obj . parents ( "li:eq(0)" ). size () ? obj . parents ( "li:eq(0)" ) : - 1 ;
},
2010-06-23 23:19:49 +00:00
children : function ( obj ) {
2010-03-16 15:05:05 +00:00
if ( obj === - 1 ) return this . container . children ( "ul:eq(0)" ). children ( "li" );
obj = this . get_node ( obj );
if ( ! obj . size ()) return false ;
return obj . children ( "ul:eq(0)" ). children ( "li" );
},
2010-06-23 23:19:49 +00:00
toggle_dots : function () {
2010-03-16 15:05:05 +00:00
if ( this . settings . ui . dots ) {
this . settings . ui . dots = false ;
this . container . children ( "ul:eq(0)" ). addClass ( "no_dots" );
}
else {
this . settings . ui . dots = true ;
this . container . children ( "ul:eq(0)" ). removeClass ( "no_dots" );
}
},
2010-06-23 23:19:49 +00:00
callback : function ( cb , args ) {
2010-03-16 15:05:05 +00:00
var p = false ;
var r = null ;
for ( var i in this . settings . plugins ) {
if ( typeof $ . tree . plugins [ i ] != "object" ) continue ;
p = $ . tree . plugins [ i ];
if ( p . callbacks && typeof p . callbacks [ cb ] == "function" ) r = p . callbacks [ cb ]. apply ( this , args );
if ( typeof r !== "undefined" && r !== null ) {
if ( cb == "ondata" || cb == "onparse" ) args [ 0 ] = r ; // keep the chain if data or parse
else return r ;
}
}
p = this . settings . callback [ cb ];
if ( typeof p == "function" ) return p . apply ( null , args );
},
2010-06-23 23:19:49 +00:00
get_rollback : function () {
2010-03-16 15:05:05 +00:00
var rb = {};
rb . html = this . container . html ();
rb . selected = this . selected ? this . selected . attr ( "id" ) : false ;
return rb ;
},
2010-06-23 23:19:49 +00:00
moved : function ( what , where , how , is_new , is_copy , rb ) {
2010-03-16 15:05:05 +00:00
var what = $ ( what );
var $parent = $ ( what ). parents ( "ul:eq(0)" );
var $where = $ ( where );
if ( $where . is ( "ins" )) $where = $where . parent ();
// Rollback
if ( ! rb ) {
var rb = {};
rb [ this . container . attr ( "id" )] = this . get_rollback ();
if ( ! is_new ) {
var tmp = what . size () > 1 ? what . eq ( 0 ). parents ( ".tree:eq(0)" ) : what . parents ( ".tree:eq(0)" );
if ( tmp . get ( 0 ) != this . container . get ( 0 )) {
tmp = tree_component . inst [ tmp . attr ( "id" )];
rb [ tmp . container . attr ( "id" )] = tmp . get_rollback ();
}
delete tmp ;
}
}
if ( how == "inside" && this . settings . data . async ) {
var _this = this ;
if ( this . get_node ( $where ). hasClass ( "closed" )) {
2010-06-23 23:19:49 +00:00
return this . open_branch ( this . get_node ( $where ), true , function () { _this . moved . apply ( _this , [ what , where , how , is_new , is_copy , rb ]); });
2010-03-16 15:05:05 +00:00
}
if ( this . get_node ( $where ). find ( "> ul > li > a.loading" ). size () == 1 ) {
2010-06-23 23:19:49 +00:00
setTimeout ( function () { _this . moved . apply ( _this , [ what , where , how , is_new , is_copy ]); }, 200 );
2010-03-16 15:05:05 +00:00
return ;
}
}
// IF MULTIPLE
if ( what . size () > 1 ) {
var _this = this ;
var tmp = this . moved ( what . eq ( 0 ), where , how , false , is_copy , rb );
2010-06-23 23:19:49 +00:00
what . each ( function ( i ) {
2010-03-16 15:05:05 +00:00
if ( i == 0 ) return ;
if ( tmp ) { // if tmp is false - the previous move was a no-go
tmp = _this . moved ( this , tmp . children ( "a:eq(0)" ), "after" , false , is_copy , rb );
}
});
return what ;
}
if ( is_copy ) {
_what = what . clone ();
2010-06-23 23:19:49 +00:00
_what . each ( function ( i ) {
2010-03-16 15:05:05 +00:00
this . id = this . id + "_copy" ;
2010-06-23 23:19:49 +00:00
$ ( this ). find ( "li" ). each ( function () {
2010-03-16 15:05:05 +00:00
this . id = this . id + "_copy" ;
});
$ ( this ). removeClass ( "dragged" ). find ( "a.clicked" ). removeClass ( "clicked" ). end (). find ( "li.dragged" ). removeClass ( "dragged" );
});
}
else _what = what ;
if ( is_new ) {
if ( ! this . callback ( "beforecreate" , [ this . get_node ( what ). get ( 0 ), this . get_node ( where ). get ( 0 ), how , this ])) return false ;
}
else {
if ( ! this . callback ( "beforemove" , [ this . get_node ( what ). get ( 0 ), this . get_node ( where ). get ( 0 ), how , this ])) return false ;
}
if ( ! is_new ) {
var tmp = what . parents ( ".tree:eq(0)" );
// if different trees
if ( tmp . get ( 0 ) != this . container . get ( 0 )) {
tmp = tree_component . inst [ tmp . attr ( "id" )];
// if there are languages - otherwise - no cleanup needed
if ( tmp . settings . languages . length ) {
var res = [];
// if new tree has no languages - use current visible
if ( this . settings . languages . length == 0 ) res . push ( "." + tmp . current_lang );
else {
for ( var i in this . settings . languages ) {
if ( ! this . settings . languages . hasOwnProperty ( i )) continue ;
for ( var j in tmp . settings . languages ) {
if ( ! tmp . settings . languages . hasOwnProperty ( j )) continue ;
if ( this . settings . languages [ i ] == tmp . settings . languages [ j ]) res . push ( "." + this . settings . languages [ i ]);
}
}
}
if ( res . length == 0 ) return this . error ( "MOVE: NO COMMON LANGUAGES" );
_what . find ( "a" ). not ( res . join ( "," )). remove ();
}
_what . find ( "a.clicked" ). removeClass ( "clicked" );
}
}
what = _what ;
// ADD NODE TO NEW PLACE
switch ( how ) {
case "before" :
$where . parents ( "ul:eq(0)" ). children ( "li.last" ). removeClass ( "last" );
$where . parent (). before ( what . removeClass ( "last" ));
$where . parents ( "ul:eq(0)" ). children ( "li:last" ). addClass ( "last" );
break ;
case "after" :
$where . parents ( "ul:eq(0)" ). children ( "li.last" ). removeClass ( "last" );
$where . parent (). after ( what . removeClass ( "last" ));
$where . parents ( "ul:eq(0)" ). children ( "li:last" ). addClass ( "last" );
break ;
case "inside" :
if ( $where . parent (). children ( "ul:first" ). size ()) {
if ( this . settings . rules . createat == "top" ) {
$where . parent (). children ( "ul:first" ). prepend ( what . removeClass ( "last" )). children ( "li:last" ). addClass ( "last" );
// restored this section
var tmp_node = $where . parent (). children ( "ul:first" ). children ( "li:first" );
if ( tmp_node . size ()) {
how = "before" ;
where = tmp_node ;
}
}
else {
// restored this section
var tmp_node = $where . parent (). children ( "ul:first" ). children ( ".last" );
if ( tmp_node . size ()) {
how = "after" ;
where = tmp_node ;
}
$where . parent (). children ( "ul:first" ). children ( ".last" ). removeClass ( "last" ). end (). append ( what . removeClass ( "last" )). children ( "li:last" ). addClass ( "last" );
}
}
else {
what . addClass ( "last" );
$where . parent (). removeClass ( "leaf" ). append ( "<ul/>" );
if ( ! $where . parent (). hasClass ( "open" )) $where . parent (). addClass ( "closed" );
$where . parent (). children ( "ul:first" ). prepend ( what );
}
if ( $where . parent (). hasClass ( "closed" )) { this . open_branch ( $where ); }
break ;
default :
break ;
}
// CLEANUP OLD PARENT
if ( $parent . find ( "li" ). size () == 0 ) {
var $li = $parent . parent ();
$li . removeClass ( "open" ). removeClass ( "closed" ). addClass ( "leaf" );
if ( ! $li . is ( ".tree" )) $li . children ( "ul" ). remove ();
$li . parents ( "ul:eq(0)" ). children ( "li.last" ). removeClass ( "last" ). end (). children ( "li:last" ). addClass ( "last" );
}
else {
$parent . children ( "li.last" ). removeClass ( "last" );
$parent . children ( "li:last" ). addClass ( "last" );
}
// NO LONGER CORRECT WITH position PARAM - if(is_new && how != "inside") where = this.get_node(where).parents("li:eq(0)");
if ( is_copy ) this . callback ( "oncopy" , [ this . get_node ( what ). get ( 0 ), this . get_node ( where ). get ( 0 ), how , this , rb ]);
else if ( is_new ) this . callback ( "oncreate" , [ this . get_node ( what ). get ( 0 ), ( $where . is ( "ul" ) ? - 1 : this . get_node ( where ). get ( 0 )), how , this , rb ]);
else this . callback ( "onmove" , [ this . get_node ( what ). get ( 0 ), this . get_node ( where ). get ( 0 ), how , this , rb ]);
return what ;
},
2010-06-23 23:19:49 +00:00
error : function ( code ) {
2010-03-16 15:05:05 +00:00
this . callback ( "error" , [ code , this ]);
return false ;
},
2010-06-23 23:19:49 +00:00
lock : function ( state ) {
2010-03-16 15:05:05 +00:00
this . locked = state ;
if ( this . locked ) this . container . children ( "ul:eq(0)" ). addClass ( "locked" );
else this . container . children ( "ul:eq(0)" ). removeClass ( "locked" );
},
2010-06-23 23:19:49 +00:00
cut : function ( obj ) {
2010-03-16 15:05:05 +00:00
if ( this . locked ) return this . error ( "LOCKED" );
obj = obj ? this . get_node ( obj ) : this . container . find ( "a.clicked" ). filter ( ":first-child" ). parent ();
if ( ! obj || ! obj . size ()) return this . error ( "CUT: NO NODE SELECTED" );
tree_component . cut_copy . copy_nodes = false ;
tree_component . cut_copy . cut_nodes = obj ;
},
2010-06-23 23:19:49 +00:00
copy : function ( obj ) {
2010-03-16 15:05:05 +00:00
if ( this . locked ) return this . error ( "LOCKED" );
obj = obj ? this . get_node ( obj ) : this . container . find ( "a.clicked" ). filter ( ":first-child" ). parent ();
if ( ! obj || ! obj . size ()) return this . error ( "COPY: NO NODE SELECTED" );
tree_component . cut_copy . copy_nodes = obj ;
tree_component . cut_copy . cut_nodes = false ;
},
2010-06-23 23:19:49 +00:00
paste : function ( obj , position ) {
2010-03-16 15:05:05 +00:00
if ( this . locked ) return this . error ( "LOCKED" );
var root = false ;
if ( obj == - 1 ) { root = true ; obj = this . container ; }
else obj = obj ? this . get_node ( obj ) : this . selected ;
if ( ! root && ( ! obj || ! obj . size ())) return this . error ( "PASTE: NO NODE SELECTED" );
if ( ! tree_component . cut_copy . copy_nodes && ! tree_component . cut_copy . cut_nodes ) return this . error ( "PASTE: NOTHING TO DO" );
var _this = this ;
var pos = position ;
if ( position == "before" ) {
position = obj . parent (). children (). index ( obj );
obj = obj . parents ( "li:eq(0)" );
}
else if ( position == "after" ) {
position = obj . parent (). children (). index ( obj ) + 1 ;
obj = obj . parents ( "li:eq(0)" );
}
else if (( typeof position ). toLowerCase () == "undefined" || position == "inside" ) {
position = ( this . settings . rules . createat == "top" ) ? 0 : obj . children ( "ul:eq(0)" ). children ( "li" ). size ();
}
if ( ! root && obj . size () == 0 ) { root = true ; obj = this . container ; }
if ( tree_component . cut_copy . copy_nodes && tree_component . cut_copy . copy_nodes . size ()) {
var ok = true ;
if ( ! root && ! this . check_move ( tree_component . cut_copy . copy_nodes , obj . children ( "a:eq(0)" ), "inside" )) return false ;
if ( obj . children ( "ul" ). size () == 0 || ( root == true && obj . children ( "ul" ). children ( "li" ). size () == 0 )) {
if ( ! root ) var a = this . moved ( tree_component . cut_copy . copy_nodes , obj . children ( "a:eq(0)" ), "inside" , false , true );
else var a = this . moved ( tree_component . cut_copy . copy_nodes , this . container . children ( "ul:eq(0)" ), "inside" , false , true );
}
else if ( pos == "before" && obj . children ( "ul:eq(0)" ). children ( "li:nth-child(" + ( position + 1 ) + ")" ). size ())
var a = this . moved ( tree_component . cut_copy . copy_nodes , obj . children ( "ul:eq(0)" ). children ( "li:nth-child(" + ( position + 1 ) + ")" ). children ( "a:eq(0)" ), "before" , false , true );
else if ( pos == "after" && obj . children ( "ul:eq(0)" ). children ( "li:nth-child(" + ( position ) + ")" ). size ())
var a = this . moved ( tree_component . cut_copy . copy_nodes , obj . children ( "ul:eq(0)" ). children ( "li:nth-child(" + ( position ) + ")" ). children ( "a:eq(0)" ), "after" , false , true );
else if ( obj . children ( "ul:eq(0)" ). children ( "li:nth-child(" + ( position + 1 ) + ")" ). size ())
var a = this . moved ( tree_component . cut_copy . copy_nodes , obj . children ( "ul:eq(0)" ). children ( "li:nth-child(" + ( position + 1 ) + ")" ). children ( "a:eq(0)" ), "before" , false , true );
else
var a = this . moved ( tree_component . cut_copy . copy_nodes , obj . children ( "ul:eq(0)" ). children ( "li:last" ). children ( "a:eq(0)" ), "after" , false , true );
tree_component . cut_copy . copy_nodes = false ;
}
if ( tree_component . cut_copy . cut_nodes && tree_component . cut_copy . cut_nodes . size ()) {
var ok = true ;
2010-06-23 23:19:49 +00:00
obj . parents (). andSelf (). each ( function () {
2010-03-16 15:05:05 +00:00
if ( tree_component . cut_copy . cut_nodes . index ( this ) != - 1 ) {
ok = false ;
return false ;
}
});
if ( ! ok ) return this . error ( "Invalid paste" );
if ( ! root && ! this . check_move ( tree_component . cut_copy . cut_nodes , obj . children ( "a:eq(0)" ), "inside" )) return false ;
if ( obj . children ( "ul" ). size () == 0 || ( root == true && obj . children ( "ul" ). children ( "li" ). size () == 0 )) {
if ( ! root ) var a = this . moved ( tree_component . cut_copy . cut_nodes , obj . children ( "a:eq(0)" ), "inside" );
else var a = this . moved ( tree_component . cut_copy . cut_nodes , this . container . children ( "ul:eq(0)" ), "inside" );
}
else if ( pos == "before" && obj . children ( "ul:eq(0)" ). children ( "li:nth-child(" + ( position + 1 ) + ")" ). size ())
var a = this . moved ( tree_component . cut_copy . cut_nodes , obj . children ( "ul:eq(0)" ). children ( "li:nth-child(" + ( position + 1 ) + ")" ). children ( "a:eq(0)" ), "before" );
else if ( pos == "after" && obj . children ( "ul:eq(0)" ). children ( "li:nth-child(" + ( position ) + ")" ). size ())
var a = this . moved ( tree_component . cut_copy . cut_nodes , obj . children ( "ul:eq(0)" ). children ( "li:nth-child(" + ( position ) + ")" ). children ( "a:eq(0)" ), "after" );
else if ( obj . children ( "ul:eq(0)" ). children ( "li:nth-child(" + ( position + 1 ) + ")" ). size ())
var a = this . moved ( tree_component . cut_copy . cut_nodes , obj . children ( "ul:eq(0)" ). children ( "li:nth-child(" + ( position + 1 ) + ")" ). children ( "a:eq(0)" ), "before" );
else
var a = this . moved ( tree_component . cut_copy . cut_nodes , obj . children ( "ul:eq(0)" ). children ( "li:last" ). children ( "a:eq(0)" ), "after" );
tree_component . cut_copy . cut_nodes = false ;
}
},
2010-06-23 23:19:49 +00:00
search : function ( str , func ) {
2010-03-16 15:05:05 +00:00
var _this = this ;
if ( ! str || ( this . srch && str != this . srch )) {
this . srch = "" ;
this . srch_opn = false ;
this . container . find ( "a.search" ). removeClass ( "search" );
}
this . srch = str ;
if ( ! str ) return ;
if ( ! func ) func = "contains" ;
if ( this . settings . data . async ) {
if ( ! this . srch_opn ) {
var dd = $ . extend ({ "search" : str }, this . callback ( "beforedata" , [ false , this ]));
$ . ajax ({
type : this . settings . data . opts . method ,
url : this . settings . data . opts . url ,
data : dd ,
dataType : "text" ,
2010-06-23 23:19:49 +00:00
success : function ( data ) {
2010-03-16 15:05:05 +00:00
_this . srch_opn = $ . unique ( data . split ( "," ));
_this . search . apply ( _this , [ str , func ]);
}
});
}
else if ( this . srch_opn . length ) {
if ( this . srch_opn && this . srch_opn . length ) {
var opn = false ;
for ( var j = 0 ; j < this . srch_opn . length ; j ++ ) {
if ( this . get_node ( "#" + this . srch_opn [ j ]). size () > 0 ) {
opn = true ;
var tmp = "#" + this . srch_opn [ j ];
delete this . srch_opn [ j ];
2010-06-23 23:19:49 +00:00
this . open_branch ( tmp , true , function () { _this . search . apply ( _this , [ str , func ]); });
2010-03-16 15:05:05 +00:00
}
}
if ( ! opn ) {
this . srch_opn = [];
_this . search . apply ( _this , [ str , func ]);
}
}
}
else {
this . srch_opn = false ;
var selector = "a" ;
// IF LANGUAGE VERSIONS
if ( this . settings . languages . length ) selector += "." + this . current_lang ;
this . callback ( "onsearch" , [ this . container . find ( selector + ":" + func + "('" + str + "')" ), this ]);
}
}
else {
var selector = "a" ;
// IF LANGUAGE VERSIONS
if ( this . settings . languages . length ) selector += "." + this . current_lang ;
var nn = this . container . find ( selector + ":" + func + "('" + str + "')" );
2010-06-23 23:19:49 +00:00
nn . parents ( "li.closed" ). each ( function () { _this . open_branch ( this , true ); });
2010-03-16 15:05:05 +00:00
this . callback ( "onsearch" , [ nn , this ]);
}
},
add_sheet : tree_component . add_sheet ,
2010-06-23 23:19:49 +00:00
destroy : function () {
2010-03-16 15:05:05 +00:00
this . callback ( "ondestroy" , [ this ]);
this . container . unbind ( ".jstree" );
$ ( "#" + this . container . attr ( "id" )). die ( "click.jstree" ). die ( "dblclick.jstree" ). die ( "mouseover.jstree" ). die ( "mouseout.jstree" ). die ( "mousedown.jstree" );
this . container . removeClass ( "tree ui-widget ui-widget-content tree-default tree-" + this . settings . ui . theme_name ). children ( "ul" ). removeClass ( "no_dots ltr locked" ). find ( "li" ). removeClass ( "leaf" ). removeClass ( "open" ). removeClass ( "closed" ). removeClass ( "last" ). children ( "a" ). removeClass ( "clicked hover search" );
if ( this . cntr == tree_component . focused ) {
for ( var i in tree_component . inst ) {
if ( i != this . cntr && i != this . container . attr ( "id" )) {
tree_component . inst [ i ]. focus ();
break ;
}
}
}
tree_component . inst [ this . cntr ] = false ;
tree_component . inst [ this . container . attr ( "id" )] = false ;
delete tree_component . inst [ this . cntr ];
delete tree_component . inst [ this . container . attr ( "id" )];
tree_component . cntr -- ;
}
}
};
// instance manager
tree_component . cntr = 0 ;
tree_component . inst = {};
// themes
tree_component . themes = [];
// drag'n'drop stuff
tree_component . drag_drop = {
isdown : false , // Is there a drag
drag_node : false , // The actual node
drag_help : false , // The helper
dragged : false ,
init_x : false ,
init_y : false ,
moving : false ,
origin_tree : false ,
marker : false ,
move_type : false , // before, after or inside
ref_node : false , // reference node
appended : false , // is helper appended
foreign : false , // Is the dragged node a foreign one
droppable : [], // Array of classes that can be dropped onto the tree
open_time : false , // Timeout for opening nodes
scroll_time : false // Timeout for scrolling
};
2010-06-23 23:19:49 +00:00
tree_component . mouseup = function ( event ) {
2010-03-16 15:05:05 +00:00
var tmp = tree_component . drag_drop ;
if ( tmp . open_time ) clearTimeout ( tmp . open_time );
if ( tmp . scroll_time ) clearTimeout ( tmp . scroll_time );
if ( tmp . moving && $ . tree . drag_end !== false ) $ . tree . drag_end . call ( null , event , tmp );
if ( tmp . foreign === false && tmp . drag_node && tmp . drag_node . size ()) {
tmp . drag_help . remove ();
if ( tmp . move_type ) {
var tree1 = tree_component . inst [ tmp . ref_node . parents ( ".tree:eq(0)" ). attr ( "id" )];
if ( tree1 ) tree1 . moved ( tmp . dragged , tmp . ref_node , tmp . move_type , false , ( tmp . origin_tree . settings . rules . drag_copy == "on" || ( tmp . origin_tree . settings . rules . drag_copy == "ctrl" && event . ctrlKey )));
}
tmp . move_type = false ;
tmp . ref_node = false ;
}
if ( tmp . foreign !== false ) {
if ( tmp . drag_help ) tmp . drag_help . remove ();
if ( tmp . move_type ) {
var tree1 = tree_component . inst [ tmp . ref_node . parents ( ".tree:eq(0)" ). attr ( "id" )];
if ( tree1 ) tree1 . callback ( "ondrop" , [ tmp . f_data , tree1 . get_node ( tmp . ref_node ). get ( 0 ), tmp . move_type , tree1 ]);
}
tmp . foreign = false ;
tmp . move_type = false ;
tmp . ref_node = false ;
}
// RESET EVERYTHING
if ( tree_component . drag_drop . marker ) tree_component . drag_drop . marker . hide ();
if ( tmp . dragged && tmp . dragged . size ()) tmp . dragged . removeClass ( "dragged" );
tmp . dragged = false ;
tmp . drag_help = false ;
tmp . drag_node = false ;
tmp . f_type = false ;
tmp . f_data = false ;
tmp . init_x = false ;
tmp . init_y = false ;
tmp . moving = false ;
tmp . appended = false ;
tmp . origin_tree = false ;
if ( tmp . isdown ) {
tmp . isdown = false ;
event . preventDefault ();
event . stopPropagation ();
return false ;
}
};
2010-06-23 23:19:49 +00:00
tree_component . mousemove = function ( event ) {
2010-03-16 15:05:05 +00:00
var tmp = tree_component . drag_drop ;
var is_start = false ;
if ( tmp . isdown ) {
if ( ! tmp . moving && Math . abs ( tmp . init_x - event . pageX ) < 5 && Math . abs ( tmp . init_y - event . pageY ) < 5 ) {
event . preventDefault ();
event . stopPropagation ();
return false ;
}
else {
if ( ! tmp . moving ) {
tree_component . drag_drop . moving = true ;
is_start = true ;
}
}
if ( tmp . open_time ) clearTimeout ( tmp . open_time );
if ( tmp . drag_help !== false ) {
if ( ! tmp . appended ) {
if ( tmp . foreign !== false ) tmp . origin_tree = $ . tree . focused ();
$ ( "body" ). append ( tmp . drag_help );
tmp . w = tmp . drag_help . width ();
tmp . appended = true ;
}
tmp . drag_help . css ({ "left" : ( event . pageX + 5 ), "top" : ( event . pageY + 15 ) });
}
if ( is_start && $ . tree . drag_start !== false ) $ . tree . drag_start . call ( null , event , tmp );
if ( $ . tree . drag !== false ) $ . tree . drag . call ( null , event , tmp );
if ( event . target . tagName == "DIV" && event . target . id == "jstree-marker" ) return false ;
var et = $ ( event . target );
if ( et . is ( "ins" )) et = et . parent ();
var cnt = et . is ( ".tree" ) ? et : et . parents ( ".tree:eq(0)" );
// if not moving over a tree
if ( cnt . size () == 0 || ! tree_component . inst [ cnt . attr ( "id" )]) {
if ( tmp . scroll_time ) clearTimeout ( tmp . scroll_time );
if ( tmp . drag_help !== false ) tmp . drag_help . find ( "li:eq(0) ins" ). addClass ( "forbidden" );
tmp . move_type = false ;
tmp . ref_node = false ;
tree_component . drag_drop . marker . hide ();
return false ;
}
var tree2 = tree_component . inst [ cnt . attr ( "id" )];
tree2 . off_height ();
if ( tmp . scroll_time ) clearTimeout ( tmp . scroll_time );
2010-06-23 23:19:49 +00:00
tmp . scroll_time = setTimeout ( function () { tree2 . scroll_check ( event . pageX , event . pageY ); }, 50 );
2010-03-16 15:05:05 +00:00
var mov = false ;
var st = cnt . scrollTop ();
if ( event . target . tagName == "A" || event . target . tagName == "INS" ) {
// just in case if hover is over the draggable
if ( et . is ( "#jstree-dragged" )) return false ;
if ( tree2 . get_node ( event . target ). hasClass ( "closed" )) {
2010-06-23 23:19:49 +00:00
tmp . open_time = setTimeout ( function () { tree2 . open_branch ( et ); }, 500 );
2010-03-16 15:05:05 +00:00
}
var et_off = et . offset ();
var goTo = {
x : ( et_off . left - 1 ),
y : ( event . pageY - et_off . top )
};
var arr = [];
if ( goTo . y < tree2 . li_height / 3 + 1 ) arr = [ "before" , "inside" , "after" ];
else if ( goTo . y > tree2 . li_height * 2 / 3 - 1 ) arr = [ "after" , "inside" , "before" ];
else {
if ( goTo . y < tree2 . li_height / 2 ) arr = [ "inside" , "before" , "after" ];
else arr = [ "inside" , "after" , "before" ];
}
var ok = false ;
var nn = ( tmp . foreign == false ) ? tmp . origin_tree . container . find ( "li.dragged" ) : tmp . f_type ;
2010-06-23 23:19:49 +00:00
$ . each ( arr , function ( i , val ) {
2010-03-16 15:05:05 +00:00
if ( tree2 . check_move ( nn , et , val )) {
mov = val ;
ok = true ;
return false ;
}
});
if ( ok ) {
switch ( mov ) {
case "before" :
goTo . y = et_off . top - 2 ;
tree_component . drag_drop . marker . attr ( "class" , "marker" );
break ;
case "after" :
goTo . y = et_off . top - 2 + tree2 . li_height ;
tree_component . drag_drop . marker . attr ( "class" , "marker" );
break ;
case "inside" :
goTo . x -= 2 ;
goTo . y = et_off . top - 2 + tree2 . li_height / 2 ;
tree_component . drag_drop . marker . attr ( "class" , "marker_plus" );
break ;
}
tmp . move_type = mov ;
tmp . ref_node = $ ( event . target );
if ( tmp . drag_help !== false ) tmp . drag_help . find ( ".forbidden" ). removeClass ( "forbidden" );
tree_component . drag_drop . marker . css ({ "left" : goTo . x , "top" : goTo . y }). show ();
}
}
if (( et . is ( ".tree" ) || et . is ( "ul" )) && et . find ( "li:eq(0)" ). size () == 0 ) {
var et_off = et . offset ();
tmp . move_type = "inside" ;
tmp . ref_node = cnt . children ( "ul:eq(0)" );
if ( tmp . drag_help !== false ) tmp . drag_help . find ( ".forbidden" ). removeClass ( "forbidden" );
tree_component . drag_drop . marker . attr ( "class" , "marker_plus" );
tree_component . drag_drop . marker . css ({ "left" : ( et_off . left + 10 ), "top" : et_off . top + 15 }). show ();
}
else if (( event . target . tagName != "A" && event . target . tagName != "INS" ) || ! ok ) {
if ( tmp . drag_help !== false ) tmp . drag_help . find ( "li:eq(0) ins" ). addClass ( "forbidden" );
tmp . move_type = false ;
tmp . ref_node = false ;
tree_component . drag_drop . marker . hide ();
}
event . preventDefault ();
event . stopPropagation ();
return false ;
}
return true ;
};
2010-06-23 23:19:49 +00:00
$ ( function () {
2010-03-16 15:05:05 +00:00
$ ( document ). bind ( "mousemove.jstree" , tree_component . mousemove );
$ ( document ). bind ( "mouseup.jstree" , tree_component . mouseup );
});
// cut, copy, paste stuff
tree_component . cut_copy = {
copy_nodes : false ,
cut_nodes : false
};
// css stuff
tree_component . css = false ;
2010-06-23 23:19:49 +00:00
tree_component . get_css = function ( rule_name , delete_flag ) {
2010-03-16 15:05:05 +00:00
rule_name = rule_name . toLowerCase ();
var css_rules = tree_component . css . cssRules || tree_component . css . rules ;
var j = 0 ;
do {
if ( css_rules . length && j > css_rules . length + 5 ) return false ;
if ( css_rules [ j ]. selectorText && css_rules [ j ]. selectorText . toLowerCase () == rule_name ) {
if ( delete_flag == true ) {
if ( tree_component . css . removeRule ) document . styleSheets [ i ]. removeRule ( j );
if ( tree_component . css . deleteRule ) document . styleSheets [ i ]. deleteRule ( j );
return true ;
}
else return css_rules [ j ];
}
}
while ( css_rules [ ++ j ]);
return false ;
};
2010-06-23 23:19:49 +00:00
tree_component . add_css = function ( rule_name ) {
2010-03-16 15:05:05 +00:00
if ( tree_component . get_css ( rule_name )) return false ;
( tree_component . css . insertRule ) ? tree_component . css . insertRule ( rule_name + ' { }' , 0 ) : tree_component . css . addRule ( rule_name , null , 0 );
return tree_component . get_css ( rule_name );
};
2010-06-23 23:19:49 +00:00
tree_component . remove_css = function ( rule_name ) {
2010-03-16 15:05:05 +00:00
return tree_component . get_css ( rule_name , true );
};
2010-06-23 23:19:49 +00:00
tree_component . add_sheet = function ( opts ) {
2010-03-16 15:05:05 +00:00
if ( opts . str ) {
var tmp = document . createElement ( "style" );
tmp . setAttribute ( 'type' , "text/css" );
if ( tmp . styleSheet ) {
document . getElementsByTagName ( "head" )[ 0 ]. appendChild ( tmp );
tmp . styleSheet . cssText = opts . str ;
}
else {
tmp . appendChild ( document . createTextNode ( opts . str ));
document . getElementsByTagName ( "head" )[ 0 ]. appendChild ( tmp );
}
return tmp . sheet || tmp . styleSheet ;
}
if ( opts . url ) {
if ( document . createStyleSheet ) {
try { document . createStyleSheet ( opts . url ); } catch ( e ) { };
}
else {
var newSS = document . createElement ( 'link' );
newSS . rel = 'stylesheet' ;
newSS . type = 'text/css' ;
newSS . media = "all" ;
newSS . href = opts . url ;
// var styles = "@import url(' " + url + " ');";
// newSS.href ='data:text/css,'+escape(styles);
document . getElementsByTagName ( "head" )[ 0 ]. appendChild ( newSS );
return newSS . styleSheet ;
}
}
};
2010-06-23 23:19:49 +00:00
$ ( function () {
2010-03-16 15:05:05 +00:00
var u = navigator . userAgent . toLowerCase ();
var v = ( u . match ( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [ 0 , '0' ])[ 1 ];
var css = '/* TREE LAYOUT */ .tree ul { margin:0 0 0 5px; padding:0 0 0 0; list-style-type:none; } .tree li { display:block; min-height:18px; line-height:18px; padding:0 0 0 15px; margin:0 0 0 0; /* Background fix */ clear:both; } .tree li ul { display:none; } .tree li a, .tree li span { display:inline-block;line-height:16px;height:16px;color:black;white-space:nowrap;text-decoration:none;padding:1px 4px 1px 4px;margin:0; } .tree li a:focus { outline: none; } .tree li a input, .tree li span input { margin:0;padding:0 0;display:inline-block;height:12px !important;border:1px solid white;background:white;font-size:10px;font-family:Verdana; } .tree li a input:not([class="xxx"]), .tree li span input:not([class="xxx"]) { padding:1px 0; } /* FOR DOTS */ .tree .ltr li.last { float:left; } .tree > ul li.last { overflow:visible; } /* OPEN OR CLOSE */ .tree li.open ul { display:block; } .tree li.closed ul { display:none !important; } /* FOR DRAGGING */ #jstree-dragged { position:absolute; top:-10px; left:-10px; margin:0; padding:0; } #jstree-dragged ul ul ul { display:none; } #jstree-marker { padding:0; margin:0; line-height:5px; font-size:1px; overflow:hidden; height:5px; position:absolute; left:-45px; top:-30px; z-index:1000; background-color:transparent; background-repeat:no-repeat; display:none; } #jstree-marker.marker { width:45px; background-position:-32px top; } #jstree-marker.marker_plus { width:5px; background-position:right top; } /* BACKGROUND DOTS */ .tree li li { overflow:hidden; } .tree > .ltr > li { display:table; } /* ICONS */ .tree ul ins { display:inline-block; text-decoration:none; width:16px; height:16px; } .tree .ltr ins { margin:0 4px 0 0px; } ' ;
if ( $ . browser . msie ) {
if ( $ . browser . version == 6 ) css += '.tree li { height:18px; zoom:1; } .tree li li { overflow:visible; } .tree .ltr li.last { margin-top: expression( (this.previousSibling && /open/.test(this.previousSibling.className) ) ? "-2px" : "0"); } .marker { width:45px; background-position:-32px top; } .marker_plus { width:5px; background-position:right top; }' ;
if ( $ . browser . version == 7 ) css += '.tree li li { overflow:visible; } .tree .ltr li.last { margin-top: expression( (this.previousSibling && /open/.test(this.previousSibling.className) ) ? "-2px" : "0"); }' ;
}
if ( $ . browser . opera ) css += '.tree > ul > li.last:after { content:"."; display: block; height:1px; clear:both; visibility:hidden; }' ;
if ( $ . browser . mozilla && $ . browser . version . indexOf ( "1.8" ) == 0 ) css += '.tree .ltr li a { display:inline; float:left; } .tree li ul { clear:both; }' ;
tree_component . css = tree_component . add_sheet ({ str : css });
});
2009-10-11 12:23:27 +00:00
})( jQuery );
// Datastores
// HTML and JSON are included here by default
2010-03-16 15:05:05 +00:00
( function ( $ ) {
$ . extend ( $ . tree . datastores , {
"html" : function () {
return {
get : function ( obj , tree , opts ) {
return obj && $ ( obj ). size () ? $ ( '<div>' ). append ( tree . get_node ( obj ). clone ()). html () : tree . container . children ( "ul:eq(0)" ). html ();
},
parse : function ( data , tree , opts , callback ) {
if ( callback ) callback . call ( null , data );
return data ;
},
load : function ( data , tree , opts , callback ) {
if ( opts . url ) {
$ . ajax ({
'type' : opts . method ,
'url' : opts . url ,
'data' : data ,
'dataType' : "html" ,
'success' : function ( d , textStatus ) {
callback . call ( null , d );
},
'error' : function ( xhttp , textStatus , errorThrown ) {
callback . call ( null , false );
tree . error ( errorThrown + " " + textStatus );
}
});
}
else {
callback . call ( null , opts . static || tree . container . children ( "ul:eq(0)" ). html ());
}
}
};
},
"json" : function () {
return {
get : function ( obj , tree , opts ) {
var _this = this ;
if ( ! obj || $ ( obj ). size () == 0 ) obj = tree . container . children ( "ul" ). children ( "li" );
else obj = $ ( obj );
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
if ( ! opts ) opts = {};
if ( ! opts . outer_attrib ) opts . outer_attrib = [ "id" , "rel" , "class" ];
if ( ! opts . inner_attrib ) opts . inner_attrib = [];
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
if ( obj . size () > 1 ) {
var arr = [];
obj . each ( function () {
arr . push ( _this . get ( this , tree , opts ));
});
return arr ;
}
if ( obj . size () == 0 ) return [];
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
var json = { attributes : {}, data : {} };
if ( obj . hasClass ( "open" )) json . data . state = "open" ;
if ( obj . hasClass ( "closed" )) json . data . state = "closed" ;
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
for ( var i in opts . outer_attrib ) {
if ( ! opts . outer_attrib . hasOwnProperty ( i )) continue ;
var val = ( opts . outer_attrib [ i ] == "class" ) ? obj . attr ( opts . outer_attrib [ i ]). replace ( /(^| )last( |$)/ig , " " ). replace ( /(^| )(leaf|closed|open)( |$)/ig , " " ) : obj . attr ( opts . outer_attrib [ i ]);
if ( typeof val != "undefined" && val . toString (). replace ( " " , "" ). length > 0 ) json . attributes [ opts . outer_attrib [ i ]] = val ;
delete val ;
}
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
if ( tree . settings . languages . length ) {
for ( var i in tree . settings . languages ) {
if ( ! tree . settings . languages . hasOwnProperty ( i )) continue ;
var a = obj . children ( "a." + tree . settings . languages [ i ]);
if ( opts . force || opts . inner_attrib . length || a . children ( "ins" ). get ( 0 ). style . backgroundImage . toString (). length || a . children ( "ins" ). get ( 0 ). className . length ) {
json . data [ tree . settings . languages [ i ]] = {};
json . data [ tree . settings . languages [ i ]]. title = tree . get_text ( obj , tree . settings . languages [ i ]);
if ( a . children ( "ins" ). get ( 0 ). style . className . length ) {
json . data [ tree . settings . languages [ i ]]. icon = a . children ( "ins" ). get ( 0 ). style . className ;
}
if ( a . children ( "ins" ). get ( 0 ). style . backgroundImage . length ) {
json . data [ tree . settings . languages [ i ]]. icon = a . children ( "ins" ). get ( 0 ). style . backgroundImage . replace ( "url(" , "" ). replace ( ")" , "" );
}
if ( opts . inner_attrib . length ) {
json . data [ tree . settings . languages [ i ]]. attributes = {};
for ( var j in opts . inner_attrib ) {
if ( ! opts . inner_attrib . hasOwnProperty ( j )) continue ;
var val = a . attr ( opts . inner_attrib [ j ]);
if ( typeof val != "undefined" && val . toString (). replace ( " " , "" ). length > 0 ) json . data [ tree . settings . languages [ i ]]. attributes [ opts . inner_attrib [ j ]] = val ;
delete val ;
}
}
}
else {
json . data [ tree . settings . languages [ i ]] = tree . get_text ( obj , tree . settings . languages [ i ]);
}
}
}
else {
var a = obj . children ( "a" );
json . data . title = tree . get_text ( obj );
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
if ( a . children ( "ins" ). size () && a . children ( "ins" ). get ( 0 ). className . length ) {
json . data . icon = a . children ( "ins" ). get ( 0 ). className ;
}
if ( a . children ( "ins" ). size () && a . children ( "ins" ). get ( 0 ). style . backgroundImage . length ) {
json . data . icon = a . children ( "ins" ). get ( 0 ). style . backgroundImage . replace ( "url(" , "" ). replace ( ")" , "" );
}
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
if ( opts . inner_attrib . length ) {
json . data . attributes = {};
for ( var j in opts . inner_attrib ) {
if ( ! opts . inner_attrib . hasOwnProperty ( j )) continue ;
var val = a . attr ( opts . inner_attrib [ j ]);
if ( typeof val != "undefined" && val . toString (). replace ( " " , "" ). length > 0 ) json . data . attributes [ opts . inner_attrib [ j ]] = val ;
delete val ;
}
}
}
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
if ( obj . children ( "ul" ). size () > 0 ) {
json . children = [];
obj . children ( "ul" ). children ( "li" ). each ( function () {
json . children . push ( _this . get ( this , tree , opts ));
});
}
return json ;
},
parse : function ( data , tree , opts , callback ) {
if ( Object . prototype . toString . apply ( data ) === "[object Array]" ) {
var str = '' ;
for ( var i = 0 ; i < data . length ; i ++ ) {
if ( typeof data [ i ] == "function" ) continue ;
str += this . parse ( data [ i ], tree , opts );
}
if ( callback ) callback . call ( null , str );
return str ;
}
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
if ( ! data || ! data . data ) {
if ( callback ) callback . call ( null , false );
return "" ;
}
2009-10-11 12:23:27 +00:00
2010-03-16 15:05:05 +00:00
var str = '' ;
str += "<li " ;
var cls = false ;
if ( data . attributes ) {
for ( var i in data . attributes ) {
if ( ! data . attributes . hasOwnProperty ( i )) continue ;
if ( i == "class" ) {
str += " class='" + data . attributes [ i ] + " " ;
if ( data . state == "closed" || data . state == "open" ) str += " " + data . state + " " ;
str += "' " ;
cls = true ;
}
else str += " " + i + "='" + data . attributes [ i ] + "' " ;
}
}
if ( ! cls && ( data . state == "closed" || data . state == "open" )) str += " class='" + data . state + "' " ;
str += ">" ;
if ( tree . settings . languages . length ) {
for ( var i = 0 ; i < tree . settings . languages . length ; i ++ ) {
var attr = {};
attr [ "href" ] = "" ;
attr [ "style" ] = "" ;
attr [ "class" ] = tree . settings . languages [ i ];
if ( data . data [ tree . settings . languages [ i ]] && ( typeof data . data [ tree . settings . languages [ i ]]. attributes ). toLowerCase () != "undefined" ) {
for ( var j in data . data [ tree . settings . languages [ i ]]. attributes ) {
if ( ! data . data [ tree . settings . languages [ i ]]. attributes . hasOwnProperty ( j )) continue ;
if ( j == "style" || j == "class" ) attr [ j ] += " " + data . data [ tree . settings . languages [ i ]]. attributes [ j ];
else attr [ j ] = data . data [ tree . settings . languages [ i ]]. attributes [ j ];
}
}
str += "<a" ;
for ( var j in attr ) {
if ( ! attr . hasOwnProperty ( j )) continue ;
str += ' ' + j + '="' + attr [ j ] + '" ' ;
}
str += ">" ;
if ( data . data [ tree . settings . languages [ i ]] && data . data [ tree . settings . languages [ i ]]. icon ) {
str += "<ins " + ( data . data [ tree . settings . languages [ i ]]. icon . indexOf ( "/" ) == - 1 ? " class='" + data . data [ tree . settings . languages [ i ]]. icon + "' " : " style='background-image:url(\"" + data . data [ tree . settings . languages [ i ]]. icon + "\");' " ) + "> </ins>" ;
}
else str += "<ins> </ins>" ;
str += (( typeof data . data [ tree . settings . languages [ i ]]. title ). toLowerCase () != "undefined" ? data . data [ tree . settings . languages [ i ]]. title : data . data [ tree . settings . languages [ i ]]) + "</a>" ;
}
}
else {
var attr = {};
attr [ "href" ] = "" ;
attr [ "style" ] = "" ;
attr [ "class" ] = "" ;
if (( typeof data . data . attributes ). toLowerCase () != "undefined" ) {
for ( var i in data . data . attributes ) {
if ( ! data . data . attributes . hasOwnProperty ( i )) continue ;
if ( i == "style" || i == "class" ) attr [ i ] += " " + data . data . attributes [ i ];
else attr [ i ] = data . data . attributes [ i ];
}
}
str += "<a" ;
for ( var i in attr ) {
if ( ! attr . hasOwnProperty ( i )) continue ;
str += ' ' + i + '="' + attr [ i ] + '" ' ;
}
str += ">" ;
if ( data . data . icon ) {
str += "<ins " + ( data . data . icon . indexOf ( "/" ) == - 1 ? " class='" + data . data . icon + "' " : " style='background-image:url(\"" + data . data . icon + "\");' " ) + "> </ins>" ;
}
else str += "<ins> </ins>" ;
str += (( typeof data . data . title ). toLowerCase () != "undefined" ? data . data . title : data . data ) + "</a>" ;
}
if ( data . children && data . children . length ) {
str += '<ul>' ;
for ( var i = 0 ; i < data . children . length ; i ++ ) {
str += this . parse ( data . children [ i ], tree , opts );
}
str += '</ul>' ;
}
str += "</li>" ;
if ( callback ) callback . call ( null , str );
return str ;
},
load : function ( data , tree , opts , callback ) {
if ( opts . static ) {
callback . call ( null , opts . static );
}
else {
$ . ajax ({
'type' : opts . method ,
'url' : opts . url ,
'data' : data ,
'dataType' : "json" ,
'success' : function ( d , textStatus ) {
callback . call ( null , d );
},
'error' : function ( xhttp , textStatus , errorThrown ) {
callback . call ( null , false );
tree . error ( errorThrown + " " + textStatus );
}
});
}
}
}
}
});
2009-10-11 12:23:27 +00:00
})( jQuery );