fancytree-rails 0.0.2 → 2.0.0.pre.6.pre.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +4 -4
- data/Rakefile +1 -1
- data/lib/fancytree/rails/version.rb +2 -2
- data/vendor/assets/javascripts/fancytree/jquery.fancytree-all.js +853 -659
- data/vendor/assets/javascripts/fancytree/jquery.fancytree-all.min.js +3 -3
- data/vendor/assets/javascripts/fancytree/jquery.fancytree.awesome.js +4 -2
- data/vendor/assets/javascripts/fancytree/jquery.fancytree.js +380 -340
- data/vendor/assets/javascripts/fancytree/jquery.fancytree.min.js +3 -3
- data/vendor/assets/stylesheets/fancytree/skin-awesome/ui.fancytree.min.css +6 -0
- data/vendor/assets/stylesheets/fancytree/skin-lion/ui.fancytree.min.css +6 -0
- data/vendor/assets/stylesheets/fancytree/skin-themeroller/ui.fancytree.min.css +1 -0
- data/vendor/assets/stylesheets/fancytree/skin-vista/ui.fancytree.min.css +6 -0
- data/vendor/assets/stylesheets/fancytree/skin-win7/ui.fancytree.min.css +6 -0
- data/vendor/assets/stylesheets/fancytree/skin-win8/ui.fancytree.min.css +6 -0
- data/vendor/assets/stylesheets/fancytree/skin-xp/ui.fancytree.min.css +6 -0
- metadata +11 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f3bd0723ab5734e8be4fb9538142c604bc0e103
|
4
|
+
data.tar.gz: 70027741a2c1b9432fac77556e7e7ba4d8238961
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 755155660f79623e8c76001669dece17ecc56111fd9fd680e20dfd35b7dc51a8cfea71aca2f7923e4435c028d0be889d7cb3946549dc09ca45948c089e7d70fb
|
7
|
+
data.tar.gz: 7c2d1befb9f1661c6c0c91129064e3909fd2fd231ab8fa582892e8b2b2b9d501c75583e0f25be1b2beea14b3b52397a43ad469f6de8a35ae3ae17f810be2bfdd
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -48,10 +48,10 @@ or if you want to use another style include it directly:
|
|
48
48
|
*= require fancytree/skin-awesome/ui.fancytree
|
49
49
|
```
|
50
50
|
Note that for awesome style (extension) to work you to:
|
51
|
-
|
52
|
-
application.css)
|
53
|
-
2
|
54
|
-
3
|
51
|
+
|
52
|
+
1. Add ```font-awesome-rails``` gem (and include its style in application.css)
|
53
|
+
2. Enable ```awesome``` extension in Fancytree.
|
54
|
+
3. Include extension code (```//= require fancytree/jquery.fancytree.awesome```) to ```app/assets/javascripts/application.js```.
|
55
55
|
|
56
56
|
## Contributing
|
57
57
|
|
data/Rakefile
CHANGED
@@ -24,7 +24,7 @@ namespace :fancytree do
|
|
24
24
|
end
|
25
25
|
|
26
26
|
#following files are not in the build yet:
|
27
|
-
FileUtils.cp(['src/jquery.fancytree.
|
27
|
+
FileUtils.cp(['src/jquery.fancytree.awesome.js'], '../../vendor/assets/javascripts/fancytree')
|
28
28
|
|
29
29
|
end
|
30
30
|
end
|
@@ -3,14 +3,18 @@
|
|
3
3
|
* Dynamic tree view control, with support for lazy loading of branches.
|
4
4
|
* https://github.com/mar10/fancytree/
|
5
5
|
*
|
6
|
-
* Copyright (c) 2006-
|
6
|
+
* Copyright (c) 2006-2014, Martin Wendt (http://wwWendt.de)
|
7
7
|
* Released under the MIT license
|
8
8
|
* https://github.com/mar10/fancytree/wiki/LicenseInfo
|
9
9
|
*
|
10
|
-
* @version 2.0.0-
|
11
|
-
* @date 2014-
|
10
|
+
* @version 2.0.0-6
|
11
|
+
* @date 2014-02-10T10:52
|
12
12
|
*/
|
13
13
|
|
14
|
+
/** Core Fancytree module.
|
15
|
+
*/
|
16
|
+
|
17
|
+
|
14
18
|
// Start of local namespace
|
15
19
|
;(function($, window, document, undefined) {
|
16
20
|
"use strict";
|
@@ -174,7 +178,7 @@ function _makeNodeTitleMatcher(s){
|
|
174
178
|
|
175
179
|
var i,
|
176
180
|
FT = null, // initialized below
|
177
|
-
//
|
181
|
+
//boolean attributes that can be set with equivalent class names in the LI tags
|
178
182
|
CLASS_ATTRS = "active expanded focus folder lazy selected unselectable".split(" "),
|
179
183
|
CLASS_ATTR_MAP = {},
|
180
184
|
// Top-level Fancytree node attributes, that can be set by dict
|
@@ -193,29 +197,29 @@ for(i=0; i<NODE_ATTRS.length; i++){ NODE_ATTR_MAP[NODE_ATTRS[i]] = true; }
|
|
193
197
|
|
194
198
|
|
195
199
|
/**
|
196
|
-
* Creates a new
|
197
|
-
*
|
198
|
-
* @
|
199
|
-
* @
|
200
|
+
* Creates a new FancytreeNode
|
201
|
+
*
|
202
|
+
* @class FancytreeNode
|
203
|
+
* @classdesc A FancytreeNode represents the hierarchical data model and operations.
|
204
|
+
*
|
200
205
|
* @param {FancytreeNode} parent
|
201
|
-
* @param {NodeData}
|
206
|
+
* @param {NodeData} obj
|
202
207
|
*
|
203
208
|
* @property {Fancytree} tree
|
204
209
|
* @property {FancytreeNode} parent Parent node
|
205
|
-
* @property {
|
206
|
-
* @property {
|
210
|
+
* @property {string} key
|
211
|
+
* @property {string} title
|
207
212
|
* @property {object} data Contains all extra data that was passed on node creation
|
208
213
|
* @property {FancytreeNode[] | null | undefined} children list of child nodes
|
209
|
-
* @property {
|
210
|
-
* @property {
|
211
|
-
* @property {
|
212
|
-
* @property {
|
213
|
-
* @property {
|
214
|
-
* @property {
|
215
|
-
* @property {
|
216
|
-
* @property {
|
217
|
-
* @property {
|
218
|
-
* @property {String} tooltip
|
214
|
+
* @property {boolean} isStatusNode
|
215
|
+
* @property {boolean} expanded
|
216
|
+
* @property {boolean} folder
|
217
|
+
* @property {string} extraClasses
|
218
|
+
* @property {boolean} lazy
|
219
|
+
* @property {boolean} selected
|
220
|
+
* @property {string} tooltip
|
221
|
+
* @property {string} data.href
|
222
|
+
* @property {string} data.target
|
219
223
|
*/
|
220
224
|
function FancytreeNode(parent, obj){
|
221
225
|
var i, l, name, cl;
|
@@ -266,7 +270,7 @@ function FancytreeNode(parent, obj){
|
|
266
270
|
}
|
267
271
|
|
268
272
|
|
269
|
-
FancytreeNode.prototype =
|
273
|
+
FancytreeNode.prototype = /** @lends FancytreeNode# */{
|
270
274
|
/* Return the direct child FancytreeNode with a given key, index. */
|
271
275
|
_findDirectChild: function(ptr){
|
272
276
|
var i, l,
|
@@ -301,16 +305,11 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
301
305
|
* Append (or insert) a list of child nodes.
|
302
306
|
*
|
303
307
|
* @param {NodeData[]} children array of child node definitions (also single child accepted)
|
304
|
-
* @param {FancytreeNode |
|
308
|
+
* @param {FancytreeNode | string | Integer} [insertBefore] child node (or key or index of such).
|
305
309
|
* If omitted, the new children are appended.
|
306
310
|
* @returns {FancytreeNode} first child added
|
307
311
|
*
|
308
|
-
* @see applyPatch
|
309
|
-
* @see FanctreeNode.applyPatch to modify existing child nodes.
|
310
|
-
* @see FanctreeNode#applyPatch to modify existing child nodes.
|
311
|
-
* @see applyPatch
|
312
|
-
* @see FanctreeNode.applyPatch
|
313
|
-
* @see FanctreeNode#applyPatch
|
312
|
+
* @see FancytreeNode#applyPatch
|
314
313
|
*/
|
315
314
|
addChildren: function(children, insertBefore){
|
316
315
|
var i, l, pos,
|
@@ -348,8 +347,10 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
348
347
|
/**
|
349
348
|
* Append or prepend a node, or append a child node.
|
350
349
|
*
|
350
|
+
* This a convenience function that calls addChildren()
|
351
|
+
*
|
351
352
|
* @param {NodeData} node node definition
|
352
|
-
* @param {
|
353
|
+
* @param {string} [mode=child] 'before', 'after', or 'child' ('over' is a synonym for 'child')
|
353
354
|
* @returns {FancytreeNode} new node
|
354
355
|
*/
|
355
356
|
addNode: function(node, mode){
|
@@ -368,10 +369,10 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
368
369
|
_assert(false, "Invalid mode: " + mode);
|
369
370
|
},
|
370
371
|
/**
|
372
|
+
* Modify existing child nodes.
|
371
373
|
*
|
372
374
|
* @param {NodePatch} patch
|
373
375
|
* @returns {$.Promise}
|
374
|
-
* @see {@link applyPatch} to modify existing child nodes.
|
375
376
|
* @see FancytreeNode#addChildren
|
376
377
|
*/
|
377
378
|
applyPatch: function(patch) {
|
@@ -425,7 +426,7 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
425
426
|
/** Copy this node as sibling or child of `node`.
|
426
427
|
*
|
427
428
|
* @param {FancytreeNode} node source node
|
428
|
-
* @param {
|
429
|
+
* @param {string} mode 'before' | 'after' | 'child'
|
429
430
|
* @param {Function} [map] callback function(NodeData) that could modify the new node
|
430
431
|
* @returns {FancytreeNode} new
|
431
432
|
*/
|
@@ -434,7 +435,7 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
434
435
|
},
|
435
436
|
/** Count direct and indirect children.
|
436
437
|
*
|
437
|
-
* @param {
|
438
|
+
* @param {boolean} [deep=true] pass 'false' to only count direct children
|
438
439
|
* @returns {int} number of child nodes
|
439
440
|
*/
|
440
441
|
countChildren: function(deep) {
|
@@ -471,7 +472,7 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
471
472
|
// TODO: expand(flag)
|
472
473
|
/**Find all nodes that contain `match` in the title.
|
473
474
|
*
|
474
|
-
* @param {
|
475
|
+
* @param {string | function(node)} match string to search for, of a function that
|
475
476
|
* returns `true` if a node is matched.
|
476
477
|
* @returns {FancytreeNode[]} array of nodes (may be empty)
|
477
478
|
* @see FancytreeNode#findAll
|
@@ -488,7 +489,7 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
488
489
|
},
|
489
490
|
/**Find first node that contains `match` in the title (not including self).
|
490
491
|
*
|
491
|
-
* @param {
|
492
|
+
* @param {string | function(node)} match string to search for, of a function that
|
492
493
|
* returns `true` if a node is matched.
|
493
494
|
* @returns {FancytreeNode} matching node or null
|
494
495
|
* @example
|
@@ -673,7 +674,7 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
673
674
|
// return this.parent.children.indexOf(this);
|
674
675
|
return $.inArray(this, this.parent.children); // indexOf doesn't work in IE7
|
675
676
|
},
|
676
|
-
/**@returns {
|
677
|
+
/**@returns {string} hierarchical child index (1-based: '3.2.4').*/
|
677
678
|
getIndexHier: function(separator) {
|
678
679
|
separator = separator || ".";
|
679
680
|
var res = [];
|
@@ -683,8 +684,8 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
683
684
|
return res.join(separator);
|
684
685
|
},
|
685
686
|
/**
|
686
|
-
* @param {
|
687
|
-
* @returns {
|
687
|
+
* @param {boolean} [excludeSelf=false]
|
688
|
+
* @returns {string} parent keys separated by options.keyPathSeparator
|
688
689
|
*/
|
689
690
|
getKeyPath: function(excludeSelf) {
|
690
691
|
var path = [],
|
@@ -731,8 +732,8 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
731
732
|
return this.parent;
|
732
733
|
},
|
733
734
|
/**
|
734
|
-
* @param {
|
735
|
-
* @param {
|
735
|
+
* @param {boolean} [includeRoot=false]
|
736
|
+
* @param {boolean} [includeSelf=false]
|
736
737
|
* @returns {FancytreeNode[]}
|
737
738
|
*/
|
738
739
|
getParentList: function(includeRoot, includeSelf) {
|
@@ -777,24 +778,24 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
777
778
|
}
|
778
779
|
return !!this.children;
|
779
780
|
},
|
780
|
-
/**@returns {
|
781
|
+
/**@returns {boolean} true, if node has keyboard focus*/
|
781
782
|
hasFocus: function() {
|
782
783
|
return (this.tree.hasFocus() && this.tree.focusNode === this);
|
783
784
|
},
|
784
|
-
/**@returns {
|
785
|
+
/**@returns {boolean} true, if node is active*/
|
785
786
|
isActive: function() {
|
786
787
|
return (this.tree.activeNode === this);
|
787
788
|
},
|
788
789
|
/**
|
789
790
|
* @param {FancytreeNode} otherNode
|
790
|
-
* @returns {
|
791
|
+
* @returns {boolean} true, if node is a direct child of otherNode
|
791
792
|
*/
|
792
793
|
isChildOf: function(otherNode) {
|
793
794
|
return (this.parent && this.parent === otherNode);
|
794
795
|
},
|
795
796
|
/**
|
796
797
|
* @param {FancytreeNode} otherNode
|
797
|
-
* @returns {
|
798
|
+
* @returns {boolean} true, if node is a sub node of otherNode
|
798
799
|
*/
|
799
800
|
isDescendantOf: function(otherNode) {
|
800
801
|
if(!otherNode || otherNode.tree !== this.tree){
|
@@ -809,37 +810,37 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
809
810
|
}
|
810
811
|
return false;
|
811
812
|
},
|
812
|
-
/** @returns {
|
813
|
+
/** @returns {boolean} true, if node is expanded*/
|
813
814
|
isExpanded: function() {
|
814
815
|
return !!this.expanded;
|
815
816
|
},
|
816
|
-
/** @returns {
|
817
|
+
/** @returns {boolean}*/
|
817
818
|
isFirstSibling: function() {
|
818
819
|
var p = this.parent;
|
819
820
|
return !p || p.children[0] === this;
|
820
821
|
},
|
821
|
-
/** @returns {
|
822
|
+
/** @returns {boolean}*/
|
822
823
|
isFolder: function() {
|
823
824
|
return !!this.folder;
|
824
825
|
},
|
825
|
-
/** @returns {
|
826
|
+
/** @returns {boolean}*/
|
826
827
|
isLastSibling: function() {
|
827
828
|
var p = this.parent;
|
828
829
|
return !p || p.children[p.children.length-1] === this;
|
829
830
|
},
|
830
|
-
/** @returns {
|
831
|
+
/** @returns {boolean} true, if node is lazy (even if data was already loaded)*/
|
831
832
|
isLazy: function() {
|
832
833
|
return !!this.lazy;
|
833
834
|
},
|
834
|
-
/** @returns {
|
835
|
+
/** @returns {boolean} true, if children are currently beeing loaded*/
|
835
836
|
isLoading: function() {
|
836
837
|
_raiseNotImplemented(); // TODO: implement
|
837
838
|
},
|
838
|
-
/**@returns {
|
839
|
+
/**@returns {boolean} true, if node is the (invisible) system root node*/
|
839
840
|
isRoot: function() {
|
840
841
|
return (this.tree.rootNode === this);
|
841
842
|
},
|
842
|
-
/** @returns {
|
843
|
+
/** @returns {boolean} true, if node is selected (e.g. has a checkmark set)*/
|
843
844
|
isSelected: function() {
|
844
845
|
return !!this.selected;
|
845
846
|
},
|
@@ -872,7 +873,7 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
872
873
|
},
|
873
874
|
/** Move this node to targetNode.
|
874
875
|
* @param {FancytreeNode} targetNode
|
875
|
-
* @param {
|
876
|
+
* @param {string} mode
|
876
877
|
* 'child': append this node as last child of targetNode.
|
877
878
|
* This is the default. To be compatble with the D'n'd
|
878
879
|
* hitMode, we also accept 'over'.
|
@@ -893,7 +894,7 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
893
894
|
}else if( !this.parent ){
|
894
895
|
throw "Cannot move system root";
|
895
896
|
}else if( targetParent.isDescendantOf(this) ){
|
896
|
-
throw "Cannot move a node to
|
897
|
+
throw "Cannot move a node to its own descendant";
|
897
898
|
}
|
898
899
|
// Unlink this node from current parent
|
899
900
|
if( this.parent.children.length === 1 ) {
|
@@ -963,10 +964,10 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
963
964
|
}, true);
|
964
965
|
}
|
965
966
|
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
967
|
+
// A collaposed node won't re-render children, so we have to remove it manually
|
968
|
+
// if( !targetParent.expanded ){
|
969
|
+
// prevParent.ul.removeChild(this.li);
|
970
|
+
// }
|
970
971
|
|
971
972
|
// Update HTML markup
|
972
973
|
if( !prevParent.isDescendantOf(targetParent)) {
|
@@ -1031,6 +1032,12 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
1031
1032
|
function _goto(n){
|
1032
1033
|
if( n ){
|
1033
1034
|
n.makeVisible();
|
1035
|
+
// Node may still be hidden by a filter
|
1036
|
+
if( ! $(n.span).is(":visible") ) {
|
1037
|
+
n.debug("Navigate: skipping hidden node");
|
1038
|
+
n.navigate(where, activate);
|
1039
|
+
return;
|
1040
|
+
}
|
1034
1041
|
return activate === false ? n.setFocus() : n.setActive();
|
1035
1042
|
}
|
1036
1043
|
}
|
@@ -1044,20 +1051,16 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
1044
1051
|
case KC.LEFT:
|
1045
1052
|
if( this.expanded ) {
|
1046
1053
|
this.setExpanded(false);
|
1047
|
-
// tree.nodeSetFocus(ctx);
|
1048
1054
|
_goto(this);
|
1049
1055
|
} else if( this.parent && this.parent.parent ) {
|
1050
|
-
// this.parent.setFocus();
|
1051
1056
|
_goto(this.parent);
|
1052
1057
|
}
|
1053
1058
|
break;
|
1054
1059
|
case KC.RIGHT:
|
1055
1060
|
if( !this.expanded && (this.children || this.lazy) ) {
|
1056
1061
|
this.setExpanded();
|
1057
|
-
// tree.nodeSetFocus(ctx);
|
1058
1062
|
_goto(this);
|
1059
1063
|
} else if( this.children && this.children.length ) {
|
1060
|
-
// this.children[0].setFocus();
|
1061
1064
|
_goto(this.children[0]);
|
1062
1065
|
}
|
1063
1066
|
break;
|
@@ -1089,7 +1092,7 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
1089
1092
|
},
|
1090
1093
|
/**
|
1091
1094
|
* Discard and reload all children of a lazy node.
|
1092
|
-
* @param {
|
1095
|
+
* @param {boolean} [discard=false]
|
1093
1096
|
* @returns $.Promise
|
1094
1097
|
*/
|
1095
1098
|
lazyLoad: function(discard) {
|
@@ -1102,19 +1105,19 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
1102
1105
|
return this.tree._callHook("nodeLoadChildren", this, source);
|
1103
1106
|
},
|
1104
1107
|
/**
|
1105
|
-
* @see
|
1108
|
+
* @see Fancytree_Hooks#nodeRender
|
1106
1109
|
*/
|
1107
1110
|
render: function(force, deep) {
|
1108
1111
|
return this.tree._callHook("nodeRender", this, force, deep);
|
1109
1112
|
},
|
1110
1113
|
/**
|
1111
|
-
* @see
|
1114
|
+
* @see Fancytree_Hooks#nodeRenderTitle
|
1112
1115
|
*/
|
1113
1116
|
renderTitle: function() {
|
1114
1117
|
return this.tree._callHook("nodeRenderTitle", this);
|
1115
1118
|
},
|
1116
1119
|
/**
|
1117
|
-
* @see
|
1120
|
+
* @see Fancytree_Hooks#nodeRenderStatus
|
1118
1121
|
*/
|
1119
1122
|
renderStatus: function() {
|
1120
1123
|
return this.tree._callHook("nodeRenderStatus", this);
|
@@ -1165,7 +1168,7 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
1165
1168
|
},
|
1166
1169
|
/**
|
1167
1170
|
*
|
1168
|
-
* @param {
|
1171
|
+
* @param {boolean | PlainObject} [effects=false] animation options.
|
1169
1172
|
* @param {FancytreeNode} [topNode=null] this node will remain visible in
|
1170
1173
|
* any case, even if `this` is outside the scroll pane.
|
1171
1174
|
* @returns $.Promise
|
@@ -1199,7 +1202,7 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
1199
1202
|
if(topNode){
|
1200
1203
|
topNodeY = topNode ? $(topNode.span).position().top : 0;
|
1201
1204
|
if((nodeY - topNodeY) > containerHeight){
|
1202
|
-
newScrollTop = scrollTop +
|
1205
|
+
newScrollTop = scrollTop + topNodeY;
|
1203
1206
|
}
|
1204
1207
|
}
|
1205
1208
|
}
|
@@ -1236,19 +1239,22 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
1236
1239
|
},
|
1237
1240
|
|
1238
1241
|
/**Activate this node.
|
1239
|
-
* @param {
|
1242
|
+
* @param {boolean} [flag=true] pass false to deactivate
|
1243
|
+
* @param {object} [opts] additional options. Defaults to {noEvents: false}
|
1240
1244
|
*/
|
1241
|
-
setActive: function(flag){
|
1242
|
-
return this.tree._callHook("nodeSetActive", this, flag);
|
1245
|
+
setActive: function(flag, opts){
|
1246
|
+
return this.tree._callHook("nodeSetActive", this, flag, opts);
|
1243
1247
|
},
|
1244
|
-
/**Expand this node.
|
1245
|
-
* @param {
|
1248
|
+
/**Expand or collapse this node.
|
1249
|
+
* @param {boolean} [flag=true] pass false to collapse
|
1250
|
+
* @param {object} [opts] additional options. Defaults to {noAnimation: false, noEvents: false}
|
1251
|
+
* @returns {$.Promise} resolved, when lazy loading and animations are done
|
1246
1252
|
*/
|
1247
|
-
setExpanded: function(flag){
|
1248
|
-
return this.tree._callHook("nodeSetExpanded", this, flag);
|
1253
|
+
setExpanded: function(flag, opts){
|
1254
|
+
return this.tree._callHook("nodeSetExpanded", this, flag, opts);
|
1249
1255
|
},
|
1250
1256
|
/**Set keyboard focus to this node.
|
1251
|
-
* @param {
|
1257
|
+
* @param {boolean} [flag=true] pass false to blur
|
1252
1258
|
* @see Fancytree#setFocus
|
1253
1259
|
*/
|
1254
1260
|
setFocus: function(flag){
|
@@ -1256,7 +1262,7 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
1256
1262
|
},
|
1257
1263
|
// TODO: setLazyNodeStatus
|
1258
1264
|
/**Select this node.
|
1259
|
-
* @param {
|
1265
|
+
* @param {boolean} [flag=true] pass false to deselect
|
1260
1266
|
*/
|
1261
1267
|
setSelected: function(flag){
|
1262
1268
|
return this.tree._callHook("nodeSetSelected", this, flag);
|
@@ -1269,8 +1275,8 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
1269
1275
|
this.renderTitle();
|
1270
1276
|
},
|
1271
1277
|
/**Sort child list by title.
|
1272
|
-
* @param {function} [
|
1273
|
-
* @param {
|
1278
|
+
* @param {function} [cmp] custom compare function(a, b) that returns -1, 0, or 1 (defaults to sort by title).
|
1279
|
+
* @param {boolean} [deep=false] pass true to sort all descendant nodes
|
1274
1280
|
*/
|
1275
1281
|
sortChildren: function(cmp, deep) {
|
1276
1282
|
var i,l,
|
@@ -1296,13 +1302,13 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
1296
1302
|
this.render();
|
1297
1303
|
}
|
1298
1304
|
},
|
1299
|
-
/** Convert node (or whole branch) into a
|
1305
|
+
/** Convert node (or whole branch) into a plain object.
|
1300
1306
|
*
|
1301
1307
|
* The result is compatible with node.addChildren().
|
1302
1308
|
*
|
1303
|
-
* @param {
|
1304
|
-
* @param {function} callback callback(dict) is called for every
|
1305
|
-
* @returns {
|
1309
|
+
* @param {boolean} recursive
|
1310
|
+
* @param {function} callback callback(dict) is called for every node, in order to allow modifications
|
1311
|
+
* @returns {NodeData}
|
1306
1312
|
*/
|
1307
1313
|
toDict: function(recursive, callback) {
|
1308
1314
|
var i, l, node,
|
@@ -1310,7 +1316,6 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
1310
1316
|
self = this;
|
1311
1317
|
|
1312
1318
|
$.each(NODE_ATTRS, function(i, a){
|
1313
|
-
// if(self[a] !== undefined && self[a] !== null){
|
1314
1319
|
if(self[a] || self[a] === false){
|
1315
1320
|
dict[a] = self[a];
|
1316
1321
|
}
|
@@ -1354,8 +1359,8 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
1354
1359
|
* Skip current branch, if fn() returns 'skip'.
|
1355
1360
|
* @param {function} fn the callback function.
|
1356
1361
|
* Return false to stop iteration, return "skip" to skip this node and children only.
|
1357
|
-
* @param {
|
1358
|
-
* @returns {
|
1362
|
+
* @param {boolean} [includeSelf=false]
|
1363
|
+
* @returns {boolean} false, if the iterator was stopped.
|
1359
1364
|
*/
|
1360
1365
|
visit: function(fn, includeSelf) {
|
1361
1366
|
var i, l,
|
@@ -1382,7 +1387,7 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
1382
1387
|
*
|
1383
1388
|
* @param fn
|
1384
1389
|
* @param includeSelf
|
1385
|
-
* @returns {
|
1390
|
+
* @returns {boolean}
|
1386
1391
|
*/
|
1387
1392
|
visitParents: function(fn, includeSelf) {
|
1388
1393
|
// Visit parent nodes (bottom up)
|
@@ -1413,10 +1418,12 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
1413
1418
|
* Fancytree
|
1414
1419
|
*/
|
1415
1420
|
/**
|
1416
|
-
* Construct a new tree.
|
1417
|
-
*
|
1418
|
-
* @
|
1419
|
-
* @
|
1421
|
+
* Construct a new tree object.
|
1422
|
+
*
|
1423
|
+
* @class Fancytree
|
1424
|
+
* @classdesc A Fancytree is the controller behind a fancytree.
|
1425
|
+
* This class also contains 'hook methods': see {@link Fancytree_Hooks}.
|
1426
|
+
*
|
1420
1427
|
* @param {Widget} widget
|
1421
1428
|
*
|
1422
1429
|
* @property {FancytreeOptions} options
|
@@ -1428,15 +1435,14 @@ FancytreeNode.prototype = /**@lends FancytreeNode*/{
|
|
1428
1435
|
* @property {object} ext
|
1429
1436
|
* @property {object} data
|
1430
1437
|
* @property {object} options
|
1431
|
-
* @property {
|
1432
|
-
* @property {
|
1433
|
-
* @property {
|
1434
|
-
* @property {
|
1435
|
-
* @property {
|
1438
|
+
* @property {string} _id
|
1439
|
+
* @property {string} statusClassPropName
|
1440
|
+
* @property {string} ariaPropName
|
1441
|
+
* @property {string} nodeContainerAttrName
|
1442
|
+
* @property {string} $container
|
1436
1443
|
* @property {FancytreeNode} lastSelectedNode
|
1437
1444
|
*/
|
1438
|
-
function Fancytree(widget){
|
1439
|
-
// TODO: rename widget to widget (it's not a jQuery object)
|
1445
|
+
function Fancytree(widget) {
|
1440
1446
|
this.widget = widget;
|
1441
1447
|
this.$div = widget.element;
|
1442
1448
|
this.options = widget.options;
|
@@ -1463,7 +1469,8 @@ function Fancytree(widget){
|
|
1463
1469
|
this.rootNode = new FancytreeNode(fakeParent, {
|
1464
1470
|
title: "root",
|
1465
1471
|
key: "root_" + this._id,
|
1466
|
-
children: null
|
1472
|
+
children: null,
|
1473
|
+
expanded: true
|
1467
1474
|
});
|
1468
1475
|
this.rootNode.parent = null;
|
1469
1476
|
|
@@ -1488,8 +1495,8 @@ function Fancytree(widget){
|
|
1488
1495
|
}
|
1489
1496
|
|
1490
1497
|
|
1491
|
-
Fancytree.prototype =
|
1492
|
-
|
1498
|
+
Fancytree.prototype = /** @lends Fancytree# */{
|
1499
|
+
/* Return a context object that can be re-used for _callHook().
|
1493
1500
|
* @param {Fancytree | FancytreeNode | EventData} obj
|
1494
1501
|
* @param {Event} originalEvent
|
1495
1502
|
* @param {Object} extra
|
@@ -1518,11 +1525,11 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
1518
1525
|
}
|
1519
1526
|
return ctx;
|
1520
1527
|
},
|
1521
|
-
|
1528
|
+
/* Trigger a hook function: funcName(ctx, [...]).
|
1522
1529
|
*
|
1523
|
-
* @param {
|
1530
|
+
* @param {string} funcName
|
1524
1531
|
* @param {Fancytree|FancytreeNode|EventData} contextObject
|
1525
|
-
* @param {any
|
1532
|
+
* @param {any} [_extraArgs] optional additional arguments
|
1526
1533
|
* @returns {any}
|
1527
1534
|
*/
|
1528
1535
|
_callHook: function(funcName, contextObject, _extraArgs) {
|
@@ -1536,11 +1543,47 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
1536
1543
|
// this.debug("_hook", funcName, ctx.node && ctx.node.toString() || ctx.tree.toString(), args);
|
1537
1544
|
return fn.apply(this, args);
|
1538
1545
|
},
|
1539
|
-
|
1546
|
+
/* Check if current extensions dependencies are met and throw an error if not.
|
1547
|
+
*
|
1548
|
+
* This method may be called inside the `treeInit` hook for custom extensions.
|
1549
|
+
*
|
1550
|
+
* @param {string} extension name of the required extension
|
1551
|
+
* @param {boolean} [required=true] pass `false` if the extension is optional, but we want to check for order if it is present
|
1552
|
+
* @param {boolean} [before] `true` if `name` must be included before this, `false` otherwise (use `null` if order doesn't matter)
|
1553
|
+
* @param {string} [message] optional error message (defaults to a descriptve error message)
|
1554
|
+
*/
|
1555
|
+
_requireExtension: function(name, required, before, message) {
|
1556
|
+
before = !!before;
|
1557
|
+
var thisName = this._local.name,
|
1558
|
+
extList = this.options.extensions,
|
1559
|
+
isBefore = $.inArray(name, extList) < $.inArray(thisName, extList),
|
1560
|
+
isMissing = required && this.ext[name] == null,
|
1561
|
+
badOrder = !isMissing && before != null && (before !== isBefore);
|
1562
|
+
|
1563
|
+
_assert(thisName && thisName !== name);
|
1564
|
+
|
1565
|
+
if( isMissing || badOrder ){
|
1566
|
+
if( !message ){
|
1567
|
+
if( isMissing || required ){
|
1568
|
+
message = "'" + thisName + "' extension requires '" + name + "'";
|
1569
|
+
if( badOrder ){
|
1570
|
+
message += " to be registered " + (before ? "before" : "after") + " itself";
|
1571
|
+
}
|
1572
|
+
}else{
|
1573
|
+
message = "If used together, `" + name + "` must be registered " + (before ? "before" : "after") + " `" + thisName + "`";
|
1574
|
+
}
|
1575
|
+
}
|
1576
|
+
$.error(message);
|
1577
|
+
return false;
|
1578
|
+
}
|
1579
|
+
return true;
|
1580
|
+
},
|
1581
|
+
/** Activate node with a given key and fire focus and activate events.
|
1540
1582
|
*
|
1541
1583
|
* A prevously activated node will be deactivated.
|
1584
|
+
* If activeVisible option is set, all parents will be expanded as necessary.
|
1542
1585
|
* Pass key = false, to deactivate the current node only.
|
1543
|
-
* @param {
|
1586
|
+
* @param {string} key
|
1544
1587
|
* @returns {FancytreeNode} activated node (null, if not found)
|
1545
1588
|
*/
|
1546
1589
|
activateKey: function(key) {
|
@@ -1552,7 +1595,7 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
1552
1595
|
}
|
1553
1596
|
return node;
|
1554
1597
|
},
|
1555
|
-
/**
|
1598
|
+
/** (experimental)
|
1556
1599
|
*
|
1557
1600
|
* @param {Array} patchList array of [key, NodePatch] arrays
|
1558
1601
|
* @returns {$.Promise} resolved, when all patches have been applied
|
@@ -1588,11 +1631,13 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
1588
1631
|
}
|
1589
1632
|
},
|
1590
1633
|
*/
|
1591
|
-
/** Return the number of
|
1634
|
+
/** Return the number of nodes.
|
1635
|
+
* @returns {integer}
|
1636
|
+
*/
|
1592
1637
|
count: function() {
|
1593
1638
|
return this.rootNode.countChildren();
|
1594
1639
|
},
|
1595
|
-
/** Write to browser console if debugLevel >= 2 (prepending tree
|
1640
|
+
/** Write to browser console if debugLevel >= 2 (prepending tree name)
|
1596
1641
|
*
|
1597
1642
|
* @param {*} msg string or object or array of such
|
1598
1643
|
*/
|
@@ -1611,8 +1656,8 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
1611
1656
|
*
|
1612
1657
|
* In selectMode 3 only the topmost selected nodes are considered.
|
1613
1658
|
*
|
1614
|
-
* @param {
|
1615
|
-
* @param {
|
1659
|
+
* @param {boolean | string} [selected=true]
|
1660
|
+
* @param {boolean | string} [active=true]
|
1616
1661
|
*/
|
1617
1662
|
generateFormElements: function(selected, active) {
|
1618
1663
|
// TODO: test case
|
@@ -1650,19 +1695,21 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
1650
1695
|
}
|
1651
1696
|
},
|
1652
1697
|
/**
|
1653
|
-
* Return
|
1698
|
+
* Return the currently active FancytreeNode or null.
|
1654
1699
|
* @returns {FancytreeNode}
|
1655
1700
|
*/
|
1656
1701
|
getActiveNode: function() {
|
1657
1702
|
return this.activeNode;
|
1658
1703
|
},
|
1659
|
-
/**
|
1704
|
+
/** Return the first top level node if any (not the invisible root node).
|
1705
|
+
* @returns {FancytreeNode | null}
|
1706
|
+
*/
|
1660
1707
|
getFirstChild: function() {
|
1661
1708
|
return this.rootNode.getFirstChild();
|
1662
1709
|
},
|
1663
1710
|
/**
|
1664
1711
|
* Return node that has keyboard focus.
|
1665
|
-
* @param {
|
1712
|
+
* @param {boolean} [ifTreeHasFocus=false] (not yet implemented)
|
1666
1713
|
* @returns {FancytreeNode}
|
1667
1714
|
*/
|
1668
1715
|
getFocusNode: function(ifTreeHasFocus) {
|
@@ -1670,8 +1717,8 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
1670
1717
|
return this.focusNode;
|
1671
1718
|
},
|
1672
1719
|
/**
|
1673
|
-
* Return node with a given key.
|
1674
|
-
* @param {
|
1720
|
+
* Return node with a given key or null if not found.
|
1721
|
+
* @param {string} key
|
1675
1722
|
* @param {FancytreeNode} [searchRoot] only search below this node
|
1676
1723
|
* @returns {FancytreeNode | null}
|
1677
1724
|
*/
|
@@ -1701,8 +1748,8 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
1701
1748
|
},
|
1702
1749
|
// TODO: getRoot()
|
1703
1750
|
/**
|
1704
|
-
* Return
|
1705
|
-
* @param {
|
1751
|
+
* Return an array of selected nodes.
|
1752
|
+
* @param {boolean} [stopOnParents=false] only return the topmost selected
|
1706
1753
|
* node (useful with selectMode 3)
|
1707
1754
|
* @returns {FancytreeNode[]}
|
1708
1755
|
*/
|
@@ -1718,14 +1765,13 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
1718
1765
|
});
|
1719
1766
|
return nodeList;
|
1720
1767
|
},
|
1721
|
-
/**
|
1722
|
-
* @returns {
|
1768
|
+
/** Return true if the tree control has keyboard focus
|
1769
|
+
* @returns {boolean}
|
1723
1770
|
*/
|
1724
1771
|
hasFocus: function(){
|
1725
1772
|
return !!this._hasFocus;
|
1726
1773
|
},
|
1727
|
-
/** Write to browser console if debugLevel >= 1 (prepending tree
|
1728
|
-
*
|
1774
|
+
/** Write to browser console if debugLevel >= 1 (prepending tree name)
|
1729
1775
|
* @param {*} msg string or object or array of such
|
1730
1776
|
*/
|
1731
1777
|
info: function(msg){
|
@@ -1745,69 +1791,22 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
1745
1791
|
return ( this.phase=="userEvent" );
|
1746
1792
|
},
|
1747
1793
|
*/
|
1748
|
-
/**
|
1749
|
-
* Expand all parents of one or more nodes.
|
1750
|
-
* Calls
|
1751
|
-
* @param {String | String[]} keyPath one or more key paths (e.g. '/3/2_1/7')
|
1752
|
-
* @param {function} callback callbeck(mode) is called for every visited node
|
1753
|
-
* @returns {$.Promise}
|
1754
|
-
*/
|
1755
|
-
/*
|
1756
|
-
_loadKeyPath: function(keyPath, callback) {
|
1757
|
-
var tree = this.tree;
|
1758
|
-
tree.logDebug("%s._loadKeyPath(%s)", this, keyPath);
|
1759
|
-
if(keyPath === ""){
|
1760
|
-
throw "Key path must not be empty";
|
1761
|
-
}
|
1762
|
-
var segList = keyPath.split(tree.options.keyPathSeparator);
|
1763
|
-
if(segList[0] === ""){
|
1764
|
-
throw "Key path must be relative (don't start with '/')";
|
1765
|
-
}
|
1766
|
-
var seg = segList.shift();
|
1767
|
-
|
1768
|
-
for(var i=0, l=this.childList.length; i < l; i++){
|
1769
|
-
var child = this.childList[i];
|
1770
|
-
if( child.data.key === seg ){
|
1771
|
-
if(segList.length === 0) {
|
1772
|
-
// Found the end node
|
1773
|
-
callback.call(tree, child, "ok");
|
1774
|
-
|
1775
|
-
}else if(child.data.isLazy && (child.childList === null || child.childList === undefined)){
|
1776
|
-
tree.logDebug("%s._loadKeyPath(%s) -> reloading %s...", this, keyPath, child);
|
1777
|
-
var self = this;
|
1778
|
-
child.reloadChildren(function(node, isOk){
|
1779
|
-
// After loading, look for direct child with that key
|
1780
|
-
if(isOk){
|
1781
|
-
tree.logDebug("%s._loadKeyPath(%s) -> reloaded %s.", node, keyPath, node);
|
1782
|
-
callback.call(tree, child, "loaded");
|
1783
|
-
node._loadKeyPath(segList.join(tree.options.keyPathSeparator), callback);
|
1784
|
-
}else{
|
1785
|
-
tree.logWarning("%s._loadKeyPath(%s) -> reloadChildren() failed.", self, keyPath);
|
1786
|
-
callback.call(tree, child, "error");
|
1787
|
-
}
|
1788
|
-
}); // Note: this line gives a JSLint warning (Don't make functions within a loop)
|
1789
|
-
// we can ignore it, since it will only be exectuted once, the the loop is ended
|
1790
|
-
// See also http://stackoverflow.com/questions/3037598/how-to-get-around-the-jslint-error-dont-make-functions-within-a-loop
|
1791
|
-
} else {
|
1792
|
-
callback.call(tree, child, "loaded");
|
1793
|
-
// Look for direct child with that key
|
1794
|
-
child._loadKeyPath(segList.join(tree.options.keyPathSeparator), callback);
|
1795
|
-
}
|
1796
|
-
return;
|
1797
|
-
}
|
1798
|
-
}
|
1799
|
-
// Could not find key
|
1800
|
-
tree.logWarning("Node not found: " + seg);
|
1801
|
-
return;
|
1802
|
-
},
|
1803
|
-
|
1804
|
-
*/
|
1805
1794
|
|
1806
1795
|
/**
|
1807
|
-
*
|
1808
|
-
*
|
1809
|
-
*
|
1810
|
-
* @
|
1796
|
+
* Make sure that a node with a given ID is loaded, by traversing - and
|
1797
|
+
* loading - its parents. This method is ment for lazy hierarchies.
|
1798
|
+
* A callback is executed for every node as we go.
|
1799
|
+
* @example
|
1800
|
+
* tree.loadKeyPath("/_3/_23/_26/_27", function(node, status){
|
1801
|
+
* if(status === "loaded") {
|
1802
|
+
* console.log("loaded intermiediate node " + node);
|
1803
|
+
* }else if(status === "ok") {
|
1804
|
+
* node.activate();
|
1805
|
+
* }
|
1806
|
+
* });
|
1807
|
+
*
|
1808
|
+
* @param {string | string[]} keyPathList one or more key paths (e.g. '/3/2_1/7')
|
1809
|
+
* @param {function} callback callback(node, status) is called for every visited node ('loading', 'loaded', 'ok', 'error')
|
1811
1810
|
* @returns {$.Promise}
|
1812
1811
|
*/
|
1813
1812
|
loadKeyPath: function(keyPathList, callback, _rootNode) {
|
@@ -1881,6 +1880,110 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
1881
1880
|
// Return a promise that is resovled, when ALL paths were loaded
|
1882
1881
|
return $.when.apply($, deferredList).promise();
|
1883
1882
|
},
|
1883
|
+
/** Re-fire beforeActivate and activate events. */
|
1884
|
+
reactivate: function(setFocus) {
|
1885
|
+
var node = this.activeNode;
|
1886
|
+
if( node ) {
|
1887
|
+
this.activeNode = null; // Force re-activating
|
1888
|
+
node.setActive();
|
1889
|
+
if( setFocus ){
|
1890
|
+
node.setFocus();
|
1891
|
+
}
|
1892
|
+
}
|
1893
|
+
},
|
1894
|
+
/** Reload tree from source and return a promise.
|
1895
|
+
* @param [source] optional new source (defaults to initial source data)
|
1896
|
+
* @returns {$.Promise}
|
1897
|
+
*/
|
1898
|
+
reload: function(source) {
|
1899
|
+
this._callHook("treeClear", this);
|
1900
|
+
return this._callHook("treeLoad", this, source);
|
1901
|
+
},
|
1902
|
+
/**Render tree (i.e. create DOM elements for all top-level nodes).
|
1903
|
+
* @param {boolean} [force=false] create DOM elemnts, even is parent is collapsed
|
1904
|
+
* @param {boolean} [deep=false]
|
1905
|
+
*/
|
1906
|
+
render: function(force, deep) {
|
1907
|
+
return this.rootNode.render(force, deep);
|
1908
|
+
},
|
1909
|
+
// TODO: selectKey: function(key, select)
|
1910
|
+
// TODO: serializeArray: function(stopOnParents)
|
1911
|
+
/**
|
1912
|
+
* @param {boolean} [flag=true]
|
1913
|
+
*/
|
1914
|
+
setFocus: function(flag) {
|
1915
|
+
return this._callHook("treeSetFocus", this, flag);
|
1916
|
+
},
|
1917
|
+
/**
|
1918
|
+
* Return all nodes as nested list of {@link NodeData}.
|
1919
|
+
*
|
1920
|
+
* @param {boolean} [includeRoot=false] Returns the hidden system root node (and its children)
|
1921
|
+
* @param {function} [callback(node)] Called for every node
|
1922
|
+
* @returns {Array | object}
|
1923
|
+
* @see FancytreeNode#toDict
|
1924
|
+
*/
|
1925
|
+
toDict: function(includeRoot, callback){
|
1926
|
+
var res = this.rootNode.toDict(true, callback);
|
1927
|
+
return includeRoot ? res : res.children;
|
1928
|
+
},
|
1929
|
+
/* Implicitly called for string conversions.
|
1930
|
+
* @returns {string}
|
1931
|
+
*/
|
1932
|
+
toString: function(){
|
1933
|
+
return "<Fancytree(#" + this._id + ")>";
|
1934
|
+
},
|
1935
|
+
/* _trigger a widget event with additional node ctx.
|
1936
|
+
* @see EventData
|
1937
|
+
*/
|
1938
|
+
_triggerNodeEvent: function(type, node, originalEvent, extra) {
|
1939
|
+
// this.debug("_trigger(" + type + "): '" + ctx.node.title + "'", ctx);
|
1940
|
+
var ctx = this._makeHookContext(node, originalEvent, extra),
|
1941
|
+
res = this.widget._trigger(type, originalEvent, ctx);
|
1942
|
+
if(res !== false && ctx.result !== undefined){
|
1943
|
+
return ctx.result;
|
1944
|
+
}
|
1945
|
+
return res;
|
1946
|
+
},
|
1947
|
+
/* _trigger a widget event with additional tree data. */
|
1948
|
+
_triggerTreeEvent: function(type, originalEvent) {
|
1949
|
+
// this.debug("_trigger(" + type + ")", ctx);
|
1950
|
+
var ctx = this._makeHookContext(this, originalEvent),
|
1951
|
+
res = this.widget._trigger(type, originalEvent, ctx);
|
1952
|
+
|
1953
|
+
if(res !== false && ctx.result !== undefined){
|
1954
|
+
return ctx.result;
|
1955
|
+
}
|
1956
|
+
return res;
|
1957
|
+
},
|
1958
|
+
/** Call fn(node) for all nodes.
|
1959
|
+
*
|
1960
|
+
* @param {function} fn the callback function.
|
1961
|
+
* Return false to stop iteration, return "skip" to skip this node and children only.
|
1962
|
+
* @returns {boolean} false, if the iterator was stopped.
|
1963
|
+
*/
|
1964
|
+
visit: function(fn) {
|
1965
|
+
return this.rootNode.visit(fn, false);
|
1966
|
+
},
|
1967
|
+
/** Write warning to browser console (prepending tree info)
|
1968
|
+
*
|
1969
|
+
* @param {*} msg string or object or array of such
|
1970
|
+
*/
|
1971
|
+
warn: function(msg){
|
1972
|
+
Array.prototype.unshift.call(arguments, this.toString());
|
1973
|
+
consoleApply("warn", arguments);
|
1974
|
+
}
|
1975
|
+
};
|
1976
|
+
|
1977
|
+
/**
|
1978
|
+
* These additional methods of the {@link Fancytree} class are 'hook functions'
|
1979
|
+
* that can be used and overloaded by extensions.
|
1980
|
+
* (See <a href="https://github.com/mar10/fancytree/wiki/TutorialExtensions">writing extensions</a>.)
|
1981
|
+
* @mixin Fancytree_Hooks
|
1982
|
+
*/
|
1983
|
+
$.extend(Fancytree.prototype,
|
1984
|
+
/** @lends Fancytree_Hooks# */
|
1985
|
+
{
|
1986
|
+
|
1884
1987
|
/** _Default handling for mouse click events. */
|
1885
1988
|
nodeClick: function(ctx) {
|
1886
1989
|
// this.tree.logDebug("ftnode.onClick(" + event.type + "): ftnode:" + this + ", button:" + event.button + ", which: " + event.which);
|
@@ -1934,7 +2037,7 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
1934
2037
|
}
|
1935
2038
|
// TODO: return promise?
|
1936
2039
|
},
|
1937
|
-
nodeCollapseSiblings: function(ctx) {
|
2040
|
+
nodeCollapseSiblings: function(ctx, callOpts) {
|
1938
2041
|
// TODO: return promise?
|
1939
2042
|
var ac, i, l,
|
1940
2043
|
node = ctx.node;
|
@@ -1943,7 +2046,7 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
1943
2046
|
ac = node.parent.children;
|
1944
2047
|
for (i=0, l=ac.length; i<l; i++) {
|
1945
2048
|
if ( ac[i] !== node && ac[i].expanded ){
|
1946
|
-
this._callHook("nodeSetExpanded", ac[i], false);
|
2049
|
+
this._callHook("nodeSetExpanded", ac[i], false, callOpts);
|
1947
2050
|
}
|
1948
2051
|
}
|
1949
2052
|
}
|
@@ -2166,7 +2269,7 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
2166
2269
|
},
|
2167
2270
|
/**
|
2168
2271
|
* Remove a single direct child of ctx.node.
|
2169
|
-
* @param ctx
|
2272
|
+
* @param {EventData} ctx
|
2170
2273
|
* @param {FancytreeNode} childNode dircect child of ctx.node
|
2171
2274
|
*/
|
2172
2275
|
nodeRemoveChild: function(ctx, childNode) {
|
@@ -2212,11 +2315,15 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
2212
2315
|
FT.debug("nodeRemoveChildMarkup()", node.toString());
|
2213
2316
|
// TODO: Unlink attr.ftnode to support GC
|
2214
2317
|
if(node.ul){
|
2215
|
-
|
2318
|
+
if( node.isRoot() ) {
|
2319
|
+
$(node.ul).empty();
|
2320
|
+
} else {
|
2321
|
+
$(node.ul).remove();
|
2322
|
+
node.ul = null;
|
2323
|
+
}
|
2216
2324
|
node.visit(function(n){
|
2217
2325
|
n.li = n.ul = null;
|
2218
2326
|
});
|
2219
|
-
node.ul = null;
|
2220
2327
|
}
|
2221
2328
|
},
|
2222
2329
|
/**Remove all descendants of ctx.node.
|
@@ -2296,9 +2403,9 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
2296
2403
|
* </code>
|
2297
2404
|
*
|
2298
2405
|
* @param: {EventData} ctx
|
2299
|
-
* @param: {
|
2300
|
-
* @param: {
|
2301
|
-
* @param: {
|
2406
|
+
* @param: {boolean} [force=false] re-render, even if html markup was already created
|
2407
|
+
* @param: {boolean} [deep=false] also render all descendants, even if parent is collapsed
|
2408
|
+
* @param: {boolean} [collapsed=false] force root node to be collapsed, so we can apply animated expand later
|
2302
2409
|
*/
|
2303
2410
|
nodeRender: function(ctx, force, deep, collapsed, _recursive) {
|
2304
2411
|
/* This method must take care of all cases where the current data mode
|
@@ -2310,7 +2417,7 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
2310
2417
|
* - children have been added
|
2311
2418
|
* - childern have been removed
|
2312
2419
|
*/
|
2313
|
-
var childLI, childNode1, childNode2, i, l, subCtx,
|
2420
|
+
var childLI, childNode1, childNode2, i, l, next, subCtx,
|
2314
2421
|
node = ctx.node,
|
2315
2422
|
tree = ctx.tree,
|
2316
2423
|
opts = ctx.options,
|
@@ -2319,7 +2426,7 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
2319
2426
|
parent = node.parent,
|
2320
2427
|
isRootNode = !parent,
|
2321
2428
|
children = node.children;
|
2322
|
-
|
2429
|
+
FT.debug("nodeRender(" + !!force + ", " + !!deep + ")", node.toString());
|
2323
2430
|
|
2324
2431
|
if( ! isRootNode && ! parent.ul ) {
|
2325
2432
|
// issue #105: calling node.collapse on a deep, unrendered node
|
@@ -2327,6 +2434,14 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
2327
2434
|
}
|
2328
2435
|
_assert(isRootNode || parent.ul, "parent UL must exist");
|
2329
2436
|
|
2437
|
+
// if(node.li && (force || (node.li.parentNode !== node.parent.ul) ) ){
|
2438
|
+
// if(node.li.parentNode !== node.parent.ul){
|
2439
|
+
// // alert("unlink " + node + " (must be child of " + node.parent + ")");
|
2440
|
+
// this.warn("unlink " + node + " (must be child of " + node.parent + ")");
|
2441
|
+
// }
|
2442
|
+
// // this.debug("nodeRemoveMarkup...");
|
2443
|
+
// this.nodeRemoveMarkup(ctx);
|
2444
|
+
// }
|
2330
2445
|
// Render the node
|
2331
2446
|
if( !isRootNode ){
|
2332
2447
|
// Discard markup on force-mode, or if it is not linked to parent <ul>
|
@@ -2360,17 +2475,11 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
2360
2475
|
$(node.span).attr("aria-labelledby", "ftal_" + node.key);
|
2361
2476
|
}
|
2362
2477
|
node.li.appendChild(node.span);
|
2363
|
-
// Note: we don't add the LI to the DOM know, but only after we
|
2364
|
-
// added all sub elements (hoping that this performs better since
|
2365
|
-
// the browser only have to render once)
|
2366
|
-
// TODO: benchmarks to prove this
|
2367
|
-
// parent.ul.appendChild(node.li);
|
2368
2478
|
|
2369
2479
|
// Create inner HTML for the <span> (expander, checkbox, icon, and title)
|
2370
2480
|
this.nodeRenderTitle(ctx);
|
2371
2481
|
|
2372
2482
|
// Allow tweaking and binding, after node was created for the first time
|
2373
|
-
// tree._triggerNodeEvent("createNode", ctx);
|
2374
2483
|
if ( opts.createNode ){
|
2375
2484
|
opts.createNode.call(tree, {type: "createNode"}, ctx);
|
2376
2485
|
}
|
@@ -2378,7 +2487,6 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
2378
2487
|
// this.nodeRenderTitle(ctx);
|
2379
2488
|
}
|
2380
2489
|
// Allow tweaking after node state was rendered
|
2381
|
-
// tree._triggerNodeEvent("renderNode", ctx);
|
2382
2490
|
if ( opts.renderNode ){
|
2383
2491
|
opts.renderNode.call(tree, {type: "renderNode"}, ctx);
|
2384
2492
|
}
|
@@ -2408,8 +2516,20 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
2408
2516
|
subCtx = $.extend({}, ctx, {node: children[i]});
|
2409
2517
|
this.nodeRender(subCtx, force, deep, false, true);
|
2410
2518
|
}
|
2519
|
+
// Remove <li> if nodes have moved to another parent
|
2520
|
+
childLI = node.ul.firstChild;
|
2521
|
+
while( childLI ){
|
2522
|
+
childNode2 = childLI.ftnode;
|
2523
|
+
if( childNode2 && childNode2.parent !== node ) {
|
2524
|
+
node.debug("_fixParent: remove missing " + childNode2, childLI);
|
2525
|
+
next = childLI.nextSibling;
|
2526
|
+
childLI.parentNode.removeChild(childLI);
|
2527
|
+
childLI = next;
|
2528
|
+
}else{
|
2529
|
+
childLI = childLI.nextSibling;
|
2530
|
+
}
|
2531
|
+
}
|
2411
2532
|
// Make sure, that <li> order matches node.children order.
|
2412
|
-
// this.nodeFixOrder(ctx);
|
2413
2533
|
childLI = node.ul.firstChild;
|
2414
2534
|
for(i=0, l=children.length-1; i<l; i++) {
|
2415
2535
|
childNode1 = children[i];
|
@@ -2421,7 +2541,6 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
2421
2541
|
childLI = childLI.nextSibling;
|
2422
2542
|
}
|
2423
2543
|
}
|
2424
|
-
// TODO: need to check, if node.ul has <li>s, that are not in node.children[] ?
|
2425
2544
|
}
|
2426
2545
|
}else{
|
2427
2546
|
// No children: remove markup if any
|
@@ -2439,14 +2558,13 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
2439
2558
|
parent.ul.appendChild(node.li);
|
2440
2559
|
}
|
2441
2560
|
}
|
2442
|
-
return;
|
2443
2561
|
},
|
2444
2562
|
/** Create HTML for the node's outer <span> (expander, checkbox, icon, and title).
|
2445
2563
|
* @param {EventData} ctx
|
2446
2564
|
*/
|
2447
2565
|
nodeRenderTitle: function(ctx, title) {
|
2448
2566
|
// set node connector images, links and text
|
2449
|
-
var id, imageSrc, nodeTitle, role, tooltip,
|
2567
|
+
var id, imageSrc, nodeTitle, role, tabindex, tooltip,
|
2450
2568
|
node = ctx.node,
|
2451
2569
|
tree = ctx.tree,
|
2452
2570
|
opts = ctx.options,
|
@@ -2513,16 +2631,13 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
2513
2631
|
tooltip = node.tooltip ? " title='" + node.tooltip.replace(/\"/g, """) + "'" : "";
|
2514
2632
|
id = aria ? " id='ftal_" + node.key + "'" : "";
|
2515
2633
|
role = aria ? " role='treeitem'" : "";
|
2516
|
-
|
2517
|
-
|
2518
|
-
|
2519
|
-
nodeTitle = "<span " + role + " class='fancytree-title'" + id + tooltip + ">" + node.title + "</span>";
|
2520
|
-
// } else {
|
2521
|
-
// nodeTitle = "<a href='" + href + "' tabindex='-1' class='fancytree-title'" + tooltip + ">" + node.title + "</a>";
|
2522
|
-
// }
|
2634
|
+
tabindex = opts.titlesTabbable ? " tabindex='0'" : "";
|
2635
|
+
|
2636
|
+
nodeTitle = "<span " + role + " class='fancytree-title'" + id + tooltip + tabindex + ">" + node.title + "</span>";
|
2523
2637
|
}
|
2524
2638
|
ares.push(nodeTitle);
|
2525
2639
|
// Note: this will trigger focusout, if node had the focus
|
2640
|
+
//$(node.span).html(ares.join("")); // it will cleanup the jQuery data currently associated with SPAN (if any), but it executes more slowly
|
2526
2641
|
node.span.innerHTML = ares.join("");
|
2527
2642
|
},
|
2528
2643
|
/** Update element classes according to node state.
|
@@ -2639,16 +2754,19 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
2639
2754
|
* If flag is true, the node is activated (must be a synchronous operation)
|
2640
2755
|
* If flag is false, the node is deactivated (must be a synchronous operation)
|
2641
2756
|
* @param {EventData} ctx
|
2642
|
-
* @param {
|
2757
|
+
* @param {boolean} [flag=true]
|
2758
|
+
* @param {object} [opts] additional options. Defaults to {}
|
2643
2759
|
*/
|
2644
|
-
nodeSetActive: function(ctx, flag) {
|
2760
|
+
nodeSetActive: function(ctx, flag, callOpts) {
|
2645
2761
|
// Handle user click / [space] / [enter], according to clickFolderMode.
|
2762
|
+
callOpts = callOpts || {};
|
2646
2763
|
var subCtx,
|
2647
2764
|
node = ctx.node,
|
2648
2765
|
tree = ctx.tree,
|
2649
2766
|
opts = ctx.options,
|
2650
2767
|
// userEvent = !!ctx.originalEvent,
|
2651
2768
|
isActive = (node === tree.activeNode);
|
2769
|
+
|
2652
2770
|
// flag defaults to true
|
2653
2771
|
flag = (flag !== false);
|
2654
2772
|
node.debug("nodeSetActive", flag);
|
@@ -2684,22 +2802,24 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
2684
2802
|
/** Expand or collapse node, return Deferred.promise.
|
2685
2803
|
*
|
2686
2804
|
* @param {EventData} ctx
|
2687
|
-
* @param {
|
2805
|
+
* @param {boolean} [flag=true]
|
2806
|
+
* @param {object} [opts] additional options. Defaults to {noAnimation: false}
|
2688
2807
|
* @returns {$.Promise} The deferred will be resolved as soon as the (lazy)
|
2689
2808
|
* data was retrieved, rendered, and the expand animation finshed.
|
2690
2809
|
*/
|
2691
|
-
nodeSetExpanded: function(ctx, flag) {
|
2810
|
+
nodeSetExpanded: function(ctx, flag, callOpts) {
|
2811
|
+
callOpts = callOpts || {};
|
2692
2812
|
var _afterLoad, dfd, i, l, parents, prevAC,
|
2693
2813
|
node = ctx.node,
|
2694
2814
|
tree = ctx.tree,
|
2695
|
-
opts = ctx.options
|
2815
|
+
opts = ctx.options,
|
2816
|
+
noAnimation = callOpts.noAnimation === true;
|
2817
|
+
|
2696
2818
|
// flag defaults to true
|
2697
2819
|
flag = (flag !== false);
|
2698
2820
|
|
2699
2821
|
node.debug("nodeSetExpanded(" + flag + ")");
|
2700
|
-
|
2701
|
-
// https://github.com/jshint/jshint/issues/455
|
2702
|
-
// if( !!node.expanded === !!flag){
|
2822
|
+
|
2703
2823
|
if((node.expanded && flag) || (!node.expanded && !flag)){
|
2704
2824
|
// Nothing to do
|
2705
2825
|
node.debug("nodeSetExpanded(" + flag + "): nothing to do");
|
@@ -2714,7 +2834,11 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
2714
2834
|
// Callback returned false
|
2715
2835
|
return _getRejectedPromise(node, ["rejected"]);
|
2716
2836
|
}
|
2717
|
-
//
|
2837
|
+
// If this node inside a collpased node, no animation and scrolling is needed
|
2838
|
+
if( !noAnimation && !node.isVisible() ) {
|
2839
|
+
noAnimation = callOpts.noAnimation = true;
|
2840
|
+
}
|
2841
|
+
|
2718
2842
|
dfd = new $.Deferred();
|
2719
2843
|
|
2720
2844
|
// Auto-collapse mode: collapse all siblings
|
@@ -2725,7 +2849,7 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
2725
2849
|
opts.autoCollapse = false;
|
2726
2850
|
for(i=0, l=parents.length; i<l; i++){
|
2727
2851
|
// TODO: should return promise?
|
2728
|
-
this._callHook("nodeCollapseSiblings", parents[i]);
|
2852
|
+
this._callHook("nodeCollapseSiblings", parents[i], callOpts);
|
2729
2853
|
}
|
2730
2854
|
}finally{
|
2731
2855
|
opts.autoCollapse = prevAC;
|
@@ -2734,7 +2858,7 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
2734
2858
|
// Trigger expand/collapse after expanding
|
2735
2859
|
dfd.done(function(){
|
2736
2860
|
ctx.tree._triggerNodeEvent(flag ? "expand" : "collapse", ctx);
|
2737
|
-
if(opts.autoScroll){
|
2861
|
+
if( opts.autoScroll && !noAnimation ) {
|
2738
2862
|
// Scroll down to last child, but keep current node visible
|
2739
2863
|
node.getLastChild().scrollIntoView(true, node);
|
2740
2864
|
}
|
@@ -2765,8 +2889,10 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
2765
2889
|
isExpanded = !!node.expanded;
|
2766
2890
|
if ( isVisible === isExpanded ) {
|
2767
2891
|
node.warn("nodeSetExpanded: UL.style.display already set");
|
2768
|
-
|
2892
|
+
|
2893
|
+
} else if ( !opts.fx || noAnimation ) {
|
2769
2894
|
node.ul.style.display = ( node.expanded || !parent ) ? "" : "none";
|
2895
|
+
|
2770
2896
|
} else {
|
2771
2897
|
duration = opts.fx.duration || 200;
|
2772
2898
|
easing = opts.fx.easing;
|
@@ -2816,7 +2942,7 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
2816
2942
|
},
|
2817
2943
|
/**
|
2818
2944
|
* @param {EventData} ctx
|
2819
|
-
* @param {
|
2945
|
+
* @param {boolean} [flag=true]
|
2820
2946
|
*/
|
2821
2947
|
nodeSetFocus: function(ctx, flag) {
|
2822
2948
|
ctx.node.debug("nodeSetFocus(" + flag + ")");
|
@@ -2861,7 +2987,7 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
2861
2987
|
/** (De)Select node, return new status (sync).
|
2862
2988
|
*
|
2863
2989
|
* @param {EventData} ctx
|
2864
|
-
* @param {
|
2990
|
+
* @param {boolean} [flag=true]
|
2865
2991
|
*/
|
2866
2992
|
nodeSetSelected: function(ctx, flag) {
|
2867
2993
|
var node = ctx.node,
|
@@ -3078,121 +3204,33 @@ Fancytree.prototype = /**@lends Fancytree*/{
|
|
3078
3204
|
this.$container.toggleClass("fancytree-treefocus", flag);
|
3079
3205
|
this._triggerTreeEvent(flag ? "focusTree" : "blurTree");
|
3080
3206
|
}
|
3081
|
-
},
|
3082
|
-
/** Re-fire beforeActivate and activate events. */
|
3083
|
-
reactivate: function(setFocus) {
|
3084
|
-
var node = this.activeNode;
|
3085
|
-
if( node ) {
|
3086
|
-
this.activeNode = null; // Force re-activating
|
3087
|
-
node.setActive();
|
3088
|
-
if( setFocus ){
|
3089
|
-
node.setFocus();
|
3090
|
-
}
|
3091
|
-
}
|
3092
|
-
},
|
3093
|
-
// TODO: redraw()
|
3094
|
-
/** Reload tree from source and return a promise.
|
3095
|
-
* @param source
|
3096
|
-
* @returns {$.Promise}
|
3097
|
-
*/
|
3098
|
-
reload: function(source) {
|
3099
|
-
this._callHook("treeClear", this);
|
3100
|
-
return this._callHook("treeLoad", this, source);
|
3101
|
-
},
|
3102
|
-
/**Render tree (i.e. all top-level nodes).
|
3103
|
-
* @param {Boolean} [force=false]
|
3104
|
-
* @param {Boolean} [deep=false]
|
3105
|
-
*/
|
3106
|
-
render: function(force, deep) {
|
3107
|
-
return this.rootNode.render(force, deep);
|
3108
|
-
},
|
3109
|
-
// TODO: selectKey: function(key, select)
|
3110
|
-
// TODO: serializeArray: function(stopOnParents)
|
3111
|
-
/**
|
3112
|
-
* @param {Boolean} [flag=true]
|
3113
|
-
*/
|
3114
|
-
setFocus: function(flag) {
|
3115
|
-
// _assert(false, "Not implemented");
|
3116
|
-
return this._callHook("treeSetFocus", this, flag);
|
3117
|
-
},
|
3118
|
-
/**
|
3119
|
-
* Return all nodes as nested list of {@link NodeData}.
|
3120
|
-
*
|
3121
|
-
* @param {Boolean} [includeRoot=false] Returns the hidden system root node (and it's children)
|
3122
|
-
* @param {function} [callback] Called for every node
|
3123
|
-
* @returns {Array | object}
|
3124
|
-
* @see FancytreeNode#toDict
|
3125
|
-
*/
|
3126
|
-
toDict: function(includeRoot, callback){
|
3127
|
-
var res = this.rootNode.toDict(true, callback);
|
3128
|
-
return includeRoot ? res : res.children;
|
3129
|
-
},
|
3130
|
-
/**Implicitly called for string conversions.
|
3131
|
-
* @returns {String}
|
3132
|
-
*/
|
3133
|
-
toString: function(){
|
3134
|
-
return "<Fancytree(#" + this._id + ")>";
|
3135
|
-
},
|
3136
|
-
/** _trigger a widget event with additional node ctx.
|
3137
|
-
* @see EventData
|
3138
|
-
*/
|
3139
|
-
_triggerNodeEvent: function(type, node, originalEvent, extra) {
|
3140
|
-
// this.debug("_trigger(" + type + "): '" + ctx.node.title + "'", ctx);
|
3141
|
-
var ctx = this._makeHookContext(node, originalEvent, extra),
|
3142
|
-
res = this.widget._trigger(type, originalEvent, ctx);
|
3143
|
-
if(res !== false && ctx.result !== undefined){
|
3144
|
-
return ctx.result;
|
3145
|
-
}
|
3146
|
-
return res;
|
3147
|
-
},
|
3148
|
-
/** _trigger a widget event with additional tree data. */
|
3149
|
-
_triggerTreeEvent: function(type, originalEvent) {
|
3150
|
-
// this.debug("_trigger(" + type + ")", ctx);
|
3151
|
-
var ctx = this._makeHookContext(this, originalEvent),
|
3152
|
-
res = this.widget._trigger(type, originalEvent, ctx);
|
3153
|
-
|
3154
|
-
if(res !== false && ctx.result !== undefined){
|
3155
|
-
return ctx.result;
|
3156
|
-
}
|
3157
|
-
return res;
|
3158
|
-
},
|
3159
|
-
/** Call fn(node) for all nodes.
|
3160
|
-
*
|
3161
|
-
* @param {function} fn the callback function.
|
3162
|
-
* Return false to stop iteration, return "skip" to skip this node and children only.
|
3163
|
-
* @returns {Boolean} false, if the iterator was stopped.
|
3164
|
-
*/
|
3165
|
-
visit: function(fn) {
|
3166
|
-
return this.rootNode.visit(fn, false);
|
3167
|
-
},
|
3168
|
-
/** Write warning to browser console (prepending tree info)
|
3169
|
-
*
|
3170
|
-
* @param {*} msg string or object or array of such
|
3171
|
-
*/
|
3172
|
-
warn: function(msg){
|
3173
|
-
Array.prototype.unshift.call(arguments, this.toString());
|
3174
|
-
consoleApply("warn", arguments);
|
3175
3207
|
}
|
3176
|
-
};
|
3208
|
+
});
|
3177
3209
|
|
3178
3210
|
|
3179
3211
|
/* ******************************************************************************
|
3180
3212
|
* jQuery UI widget boilerplate
|
3181
|
-
* @ name ui_fancytree
|
3182
|
-
* @ class The jQuery.ui.fancytree widget
|
3183
3213
|
*/
|
3184
|
-
|
3185
|
-
|
3186
|
-
|
3214
|
+
/**
|
3215
|
+
* This constructor is not called directly. Use `$(selector).fancytre({})`
|
3216
|
+
* to initialize the plugin instead.
|
3217
|
+
*
|
3218
|
+
* @class ui.fancytree
|
3219
|
+
* @classdesc The plugin (derrived from <a href=" http://api.jqueryui.com/jQuery.widget/">jQuery.Widget</a>).<br>
|
3220
|
+
* <pre class="sh_javascript sunlight-highlight-javascript">// Access instance methods and members:
|
3221
|
+
* var tree = $(selector).fancytree("getTree");
|
3222
|
+
* // Access static members:
|
3223
|
+
* alert($.ui.fancytree.version);
|
3224
|
+
* </pre>
|
3225
|
+
*/
|
3187
3226
|
$.widget("ui.fancytree",
|
3188
|
-
/** @lends
|
3227
|
+
/** @lends ui.fancytree# */
|
3189
3228
|
{
|
3190
3229
|
/**These options will be used as defaults
|
3191
3230
|
* @type {FancytreeOptions}
|
3192
3231
|
*/
|
3193
3232
|
options:
|
3194
3233
|
{
|
3195
|
-
/** @type {Boolean} Make sure, active nodes are visible (expanded). */
|
3196
3234
|
activeVisible: true,
|
3197
3235
|
ajax: {
|
3198
3236
|
type: "GET",
|
@@ -3225,6 +3263,7 @@ $.widget("ui.fancytree",
|
|
3225
3263
|
loadError: "Load error!"
|
3226
3264
|
},
|
3227
3265
|
tabbable: true,
|
3266
|
+
titlesTabbable: false,
|
3228
3267
|
_classNames: {
|
3229
3268
|
node: "fancytree-node",
|
3230
3269
|
folder: "fancytree-folder",
|
@@ -3439,7 +3478,7 @@ $.widget("ui.fancytree",
|
|
3439
3478
|
return this.tree.activeNode;
|
3440
3479
|
},
|
3441
3480
|
/**
|
3442
|
-
* @param {
|
3481
|
+
* @param {string} key
|
3443
3482
|
* @returns {FancytreeNode} the matching node or null
|
3444
3483
|
*/
|
3445
3484
|
getNodeByKey: function(key) {
|
@@ -3458,19 +3497,19 @@ $.widget("ui.fancytree",
|
|
3458
3497
|
// $.ui.fancytree was created by the widget factory. Create a local shortcut:
|
3459
3498
|
FT = $.ui.fancytree;
|
3460
3499
|
|
3461
|
-
|
3500
|
+
/*
|
3462
3501
|
* Static members in the `$.ui.fancytree` namespace.
|
3463
|
-
*
|
3502
|
+
*
|
3464
3503
|
* @example:
|
3465
3504
|
* alert(""version: " + $.ui.fancytree.version);
|
3466
|
-
* var node = $.ui.fancytree.()
|
3505
|
+
* var node = $.ui.fancytree.getNode(element);
|
3467
3506
|
*/
|
3468
3507
|
$.extend($.ui.fancytree,
|
3469
|
-
/** @lends
|
3508
|
+
/** @lends ui.fancytree */
|
3470
3509
|
{
|
3471
|
-
/** @type {
|
3472
|
-
version: "2.0.0-
|
3473
|
-
/** @type {
|
3510
|
+
/** @type {string} */
|
3511
|
+
version: "2.0.0-6",
|
3512
|
+
/** @type {string} */
|
3474
3513
|
buildType: "release",
|
3475
3514
|
/** @type {int} */
|
3476
3515
|
debugLevel: 1, // used by $.ui.fancytree.debug() and as default for tree.options.debugLevel
|
@@ -3503,7 +3542,7 @@ $.extend($.ui.fancytree,
|
|
3503
3542
|
*
|
3504
3543
|
* @static
|
3505
3544
|
* @param {Event} event Mouse event, e.g. click, ...
|
3506
|
-
* @returns {
|
3545
|
+
* @returns {string} 'title' | 'prefix' | 'expander' | 'checkbox' | 'icon' | undefined
|
3507
3546
|
*/
|
3508
3547
|
getEventTargetType: function(event){
|
3509
3548
|
return this.getEventTarget(event).type;
|
@@ -3678,11 +3717,12 @@ $.extend($.ui.fancytree,
|
|
3678
3717
|
},
|
3679
3718
|
/** Add Fancytree extension definition to the list of globally available extensions.
|
3680
3719
|
*
|
3681
|
-
* @param
|
3682
|
-
* @param definition
|
3720
|
+
* @param {Object} definition
|
3683
3721
|
*/
|
3684
|
-
registerExtension: function(
|
3685
|
-
|
3722
|
+
registerExtension: function(definition){
|
3723
|
+
_assert(definition.name != null, "extensions must have a `name` property.");
|
3724
|
+
_assert(definition.version != null, "extensions must have a `version` property.");
|
3725
|
+
$.ui.fancytree._extensions[definition.name] = definition;
|
3686
3726
|
},
|
3687
3727
|
warn: function(msg){
|
3688
3728
|
consoleApply("warn", arguments);
|
@@ -3714,168 +3754,19 @@ if( typeof define === "function" && define.amd ) {
|
|
3714
3754
|
*/
|
3715
3755
|
}(jQuery, window, document));
|
3716
3756
|
|
3717
|
-
/*!
|
3718
|
-
* jquery.fancytree.columnview.js
|
3719
|
-
*
|
3720
|
-
* Render tree like a Mac Finder's column view.
|
3721
|
-
* (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/)
|
3722
|
-
*
|
3723
|
-
* Copyright (c) 2013, Martin Wendt (http://wwWendt.de)
|
3724
|
-
*
|
3725
|
-
* Released under the MIT license
|
3726
|
-
* https://github.com/mar10/fancytree/wiki/LicenseInfo
|
3727
|
-
*
|
3728
|
-
* @version 2.0.0-5
|
3729
|
-
* @date 2014-01-04T16:42
|
3730
|
-
*/
|
3731
|
-
|
3732
|
-
;(function($, window, document, undefined) {
|
3733
|
-
|
3734
|
-
"use strict";
|
3735
|
-
|
3736
|
-
// prevent duplicate loading
|
3737
|
-
// if ( $.ui.fancytree && $.ui.fancytree.version ) {
|
3738
|
-
// $.ui.fancytree.warn("Fancytree: duplicate include");
|
3739
|
-
// return;
|
3740
|
-
// }
|
3741
|
-
|
3742
|
-
|
3743
|
-
/*******************************************************************************
|
3744
|
-
* Private functions and variables
|
3745
|
-
*/
|
3746
|
-
/*
|
3747
|
-
function _assert(cond, msg){
|
3748
|
-
msg = msg || "";
|
3749
|
-
if(!cond){
|
3750
|
-
$.error("Assertion failed " + msg);
|
3751
|
-
}
|
3752
|
-
}
|
3753
|
-
*/
|
3754
|
-
|
3755
|
-
/*******************************************************************************
|
3756
|
-
* Private functions and variables
|
3757
|
-
*/
|
3758
|
-
$.ui.fancytree.registerExtension("columnview", {
|
3759
|
-
version: "0.0.1",
|
3760
|
-
// Default options for this extension.
|
3761
|
-
options: {
|
3762
|
-
},
|
3763
|
-
// Overide virtual methods for this extension.
|
3764
|
-
// `this` : is this extension object
|
3765
|
-
// `this._base` : the Fancytree instance
|
3766
|
-
// `this._super`: the virtual function that was overriden (member of prev. extension or Fancytree)
|
3767
|
-
treeInit: function(ctx){
|
3768
|
-
var $tdFirst, $ul,
|
3769
|
-
tree = ctx.tree,
|
3770
|
-
$table = tree.widget.element;
|
3771
|
-
|
3772
|
-
tree.tr = $("tbody tr", $table)[0];
|
3773
|
-
tree.columnCount = $(">td", tree.tr).length;
|
3774
|
-
// Perform default behavior
|
3775
|
-
this._super(ctx);
|
3776
|
-
// Standard Fancytree created a root <ul>. Now move this into first table cell
|
3777
|
-
$ul = $(tree.rootNode.ul);
|
3778
|
-
$tdFirst = $(">td", tree.tr).eq(0);
|
3779
|
-
|
3780
|
-
$ul.removeClass("fancytree-container");
|
3781
|
-
$ul.removeAttr("tabindex");
|
3782
|
-
tree.$container = $table;
|
3783
|
-
$table.addClass("fancytree-container fancytree-ext-columnview");
|
3784
|
-
$table.attr("tabindex", "0");
|
3785
|
-
|
3786
|
-
$tdFirst.empty();
|
3787
|
-
$ul.detach().appendTo($tdFirst);
|
3788
|
-
|
3789
|
-
// Force some required options
|
3790
|
-
tree.widget.options.autoCollapse = true;
|
3791
|
-
// tree.widget.options.autoActivate = true;
|
3792
|
-
tree.widget.options.fx = false;
|
3793
|
-
tree.widget.options.clickFolderMode = 1;
|
3794
|
-
|
3795
|
-
// Make sure that only active path is expanded when a node is activated:
|
3796
|
-
$table.bind("fancytreeactivate", function(e, data){
|
3797
|
-
var i, tdList,
|
3798
|
-
node = data.node,
|
3799
|
-
tree = data.tree,
|
3800
|
-
level = node.getLevel();
|
3801
|
-
|
3802
|
-
tree._callHook("nodeCollapseSiblings", node);
|
3803
|
-
// Clear right neighbours
|
3804
|
-
if(level <= tree.columnCount){
|
3805
|
-
tdList = $(">td", tree.tr);
|
3806
|
-
for(i=level; i<tree.columnCount; i++){
|
3807
|
-
tdList.eq(i).empty();
|
3808
|
-
}
|
3809
|
-
}
|
3810
|
-
// Expand nodes on activate, so we populate the right neighbor cell
|
3811
|
-
if(!node.expanded && (node.children || node.lazy)) {
|
3812
|
-
node.setExpanded();
|
3813
|
-
}
|
3814
|
-
// Adjust keyboard behaviour:
|
3815
|
-
}).bind("fancytreekeydown", function(e, data){
|
3816
|
-
var next = null;
|
3817
|
-
switch(e.which){
|
3818
|
-
case $.ui.keyCode.DOWN:
|
3819
|
-
next = data.node.getNextSibling();
|
3820
|
-
if( next ){
|
3821
|
-
next.setFocus();
|
3822
|
-
}
|
3823
|
-
return false;
|
3824
|
-
case $.ui.keyCode.LEFT:
|
3825
|
-
next = data.node.getParent();
|
3826
|
-
if( next ){
|
3827
|
-
next.setFocus();
|
3828
|
-
}
|
3829
|
-
return false;
|
3830
|
-
case $.ui.keyCode.UP:
|
3831
|
-
next = data.node.getPrevSibling();
|
3832
|
-
if( next ){
|
3833
|
-
next.setFocus();
|
3834
|
-
}
|
3835
|
-
return false;
|
3836
|
-
}
|
3837
|
-
});
|
3838
|
-
},
|
3839
|
-
nodeRender: function(ctx, force, deep, collapsed, _recursive) {
|
3840
|
-
// Render standard nested <ul> - <li> hierarchy
|
3841
|
-
this._super(ctx, force, deep, collapsed, _recursive);
|
3842
|
-
// Remove expander and add a trailing triangle instead
|
3843
|
-
var level, $tdChild, $ul,
|
3844
|
-
tree = ctx.tree,
|
3845
|
-
node = ctx.node,
|
3846
|
-
$span = $(node.span);
|
3847
|
-
|
3848
|
-
$span.find("span.fancytree-expander").remove();
|
3849
|
-
if(node.hasChildren() !== false && !$span.find("span.fancytree-cv-right").length){
|
3850
|
-
$span.append($("<span class='fancytree-icon fancytree-cv-right'>"));
|
3851
|
-
}
|
3852
|
-
// Move <ul> with children into the appropriate <td>
|
3853
|
-
if(node.ul){
|
3854
|
-
node.ul.style.display = ""; // might be hidden if RIGHT was pressed
|
3855
|
-
level = node.getLevel();
|
3856
|
-
if(level < tree.columnCount){
|
3857
|
-
$tdChild = $(">td", tree.tr).eq(level);
|
3858
|
-
$ul = $(node.ul).detach();
|
3859
|
-
$tdChild.empty().append($ul);
|
3860
|
-
}
|
3861
|
-
}
|
3862
|
-
}
|
3863
|
-
});
|
3864
|
-
}(jQuery, window, document));
|
3865
|
-
|
3866
3757
|
/*!
|
3867
3758
|
* jquery.fancytree.dnd.js
|
3868
3759
|
*
|
3869
|
-
* Drag
|
3760
|
+
* Drag-and-drop support.
|
3870
3761
|
* (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/)
|
3871
3762
|
*
|
3872
|
-
* Copyright (c)
|
3763
|
+
* Copyright (c) 2014, Martin Wendt (http://wwWendt.de)
|
3873
3764
|
*
|
3874
3765
|
* Released under the MIT license
|
3875
3766
|
* https://github.com/mar10/fancytree/wiki/LicenseInfo
|
3876
3767
|
*
|
3877
|
-
* @version 2.0.0-
|
3878
|
-
* @date 2014-
|
3768
|
+
* @version 2.0.0-6
|
3769
|
+
* @date 2014-02-10T10:52
|
3879
3770
|
*/
|
3880
3771
|
|
3881
3772
|
;(function($, window, document, undefined) {
|
@@ -4068,12 +3959,10 @@ function _registerDnd() {
|
|
4068
3959
|
/* *****************************************************************************
|
4069
3960
|
*
|
4070
3961
|
*/
|
4071
|
-
|
4072
|
-
$.ui.fancytree.registerExtension(
|
4073
|
-
/** @scope ui_fancytree
|
4074
|
-
* @lends $.ui.fancytree.ext.dnd.prototype
|
4075
|
-
*/
|
3962
|
+
|
3963
|
+
$.ui.fancytree.registerExtension(
|
4076
3964
|
{
|
3965
|
+
name: "dnd",
|
4077
3966
|
version: "0.0.1",
|
4078
3967
|
// Default options for this extension.
|
4079
3968
|
options: {
|
@@ -4104,7 +3993,7 @@ $.ui.fancytree.registerExtension("dnd",
|
|
4104
3993
|
if( event.which === $.ui.keyCode.ESCAPE) {
|
4105
3994
|
this._local._cancelDrag();
|
4106
3995
|
}
|
4107
|
-
this._super(ctx);
|
3996
|
+
return this._super(ctx);
|
4108
3997
|
},
|
4109
3998
|
/* Display drop marker according to hitMode ('after', 'before', 'over', 'out', 'start', 'stop'). */
|
4110
3999
|
_setDndStatus: function(sourceNode, targetNode, helper, hitMode, accept) {
|
@@ -4402,19 +4291,339 @@ $.ui.fancytree.registerExtension("dnd",
|
|
4402
4291
|
});
|
4403
4292
|
}(jQuery, window, document));
|
4404
4293
|
|
4294
|
+
/*!
|
4295
|
+
* jquery.fancytree.edit.js
|
4296
|
+
*
|
4297
|
+
* Make node titles editable.
|
4298
|
+
* (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/)
|
4299
|
+
*
|
4300
|
+
* Copyright (c) 2014, Martin Wendt (http://wwWendt.de)
|
4301
|
+
*
|
4302
|
+
* Released under the MIT license
|
4303
|
+
* https://github.com/mar10/fancytree/wiki/LicenseInfo
|
4304
|
+
*
|
4305
|
+
* @version 2.0.0-6
|
4306
|
+
* @date 2014-02-10T10:52
|
4307
|
+
*/
|
4308
|
+
/**
|
4309
|
+
* @module fancytree/edit
|
4310
|
+
*/
|
4311
|
+
|
4312
|
+
;(function($, window, document, undefined) {
|
4313
|
+
|
4314
|
+
"use strict";
|
4315
|
+
|
4316
|
+
|
4317
|
+
/*******************************************************************************
|
4318
|
+
* Private functions and variables
|
4319
|
+
*/
|
4320
|
+
|
4321
|
+
var isMac = /Mac/.test(navigator.platform)
|
4322
|
+
// modifiers = {shift: "shiftKey", ctrl: "ctrlKey", alt: "altKey", meta: "metaKey"},
|
4323
|
+
// specialKeys = {
|
4324
|
+
// 8: "backspace", 9: "tab", 10: "return", 13: "return", 16: "shift", 17: "ctrl", 18: "alt", 19: "pause",
|
4325
|
+
// 20: "capslock", 27: "esc", 32: "space", 33: "pageup", 34: "pagedown", 35: "end", 36: "home",
|
4326
|
+
// 37: "left", 38: "up", 39: "right", 40: "down", 45: "insert", 46: "del",
|
4327
|
+
// 96: "0", 97: "1", 98: "2", 99: "3", 100: "4", 101: "5", 102: "6", 103: "7",
|
4328
|
+
// 104: "8", 105: "9", 106: "*", 107: "+", 109: "-", 110: ".", 111 : "/",
|
4329
|
+
// 112: "f1", 113: "f2", 114: "f3", 115: "f4", 116: "f5", 117: "f6", 118: "f7", 119: "f8",
|
4330
|
+
// 120: "f9", 121: "f10", 122: "f11", 123: "f12", 144: "numlock", 145: "scroll", 186: ";", 191: "/",
|
4331
|
+
// 220: "\\", 222: "'", 224: "meta"
|
4332
|
+
// },
|
4333
|
+
// shiftNums = {
|
4334
|
+
// "`": "~", "1": "!", "2": "@", "3": "#", "4": "$", "5": "%", "6": "^", "7": "&",
|
4335
|
+
// "8": "*", "9": "(", "0": ")", "-": "_", "=": "+", ";": ": ", "'": "\"", ",": "<",
|
4336
|
+
// ".": ">", "/": "?", "\\": "|"
|
4337
|
+
// }
|
4338
|
+
;
|
4339
|
+
|
4340
|
+
// $.ui.fancytree.isKeydownEvent = function(e, code){
|
4341
|
+
// var i, part, partmap, partlist = code.split("+"), len = parts.length;
|
4342
|
+
// var c = String.fromCharCode(e.which).toLowerCase();
|
4343
|
+
// for( i = 0; i < len; i++ ) {
|
4344
|
+
// }
|
4345
|
+
// alert (parts.unshift());
|
4346
|
+
// alert (parts.unshift());
|
4347
|
+
// alert (parts.unshift());
|
4348
|
+
// };
|
4349
|
+
|
4350
|
+
|
4351
|
+
/**
|
4352
|
+
* [ext-edit] Start inline editing of current node title.
|
4353
|
+
*
|
4354
|
+
* @alias FancytreeNode#editStart
|
4355
|
+
* @requires Fancytree
|
4356
|
+
*/
|
4357
|
+
$.ui.fancytree._FancytreeNodeClass.prototype.editStart = function(){
|
4358
|
+
var $input,
|
4359
|
+
node = this,
|
4360
|
+
tree = this.tree,
|
4361
|
+
local = tree.ext.edit,
|
4362
|
+
prevTitle = node.title,
|
4363
|
+
instOpts = tree.options.edit,
|
4364
|
+
$title = $(".fancytree-title", node.span),
|
4365
|
+
eventData = {node: node, tree: tree, options: tree.options};
|
4366
|
+
|
4367
|
+
if( instOpts.beforeEdit.call(node, {type: "beforeEdit"}, eventData) === false){
|
4368
|
+
return false;
|
4369
|
+
}
|
4370
|
+
// beforeEdit may want to modify the title before editing
|
4371
|
+
prevTitle = node.title;
|
4372
|
+
|
4373
|
+
node.debug("editStart");
|
4374
|
+
// Disable standard Fancytree mouse- and key handling
|
4375
|
+
tree.widget._unbind();
|
4376
|
+
// #116: ext-dnd prevents the blur event, so we have to catch outer clicks
|
4377
|
+
$(document).on("mousedown.fancytree-edit", function(event){
|
4378
|
+
if( ! $(event.target).hasClass("fancytree-edit-input") ){
|
4379
|
+
node.editEnd(true, event);
|
4380
|
+
}
|
4381
|
+
});
|
4382
|
+
|
4383
|
+
// Replace node with <input>
|
4384
|
+
$input = $("<input />", {
|
4385
|
+
"class": "fancytree-edit-input",
|
4386
|
+
value: prevTitle
|
4387
|
+
});
|
4388
|
+
if ( instOpts.adjustWidthOfs != null ) {
|
4389
|
+
$input.width($title.width() + instOpts.adjustWidthOfs);
|
4390
|
+
}
|
4391
|
+
if ( instOpts.inputCss != null ) {
|
4392
|
+
$input.css(instOpts.inputCss);
|
4393
|
+
}
|
4394
|
+
eventData.input = $input;
|
4395
|
+
|
4396
|
+
$title.html($input);
|
4397
|
+
|
4398
|
+
$.ui.fancytree.assert(!local.currentNode, "recursive edit");
|
4399
|
+
local.currentNode = this;
|
4400
|
+
// Focus <input> and bind keyboard handler
|
4401
|
+
$input
|
4402
|
+
.focus()
|
4403
|
+
.change(function(event){
|
4404
|
+
$input.addClass("fancytree-edit-dirty");
|
4405
|
+
}).keydown(function(event){
|
4406
|
+
switch( event.which ) {
|
4407
|
+
case $.ui.keyCode.ESCAPE:
|
4408
|
+
node.editEnd(false, event);
|
4409
|
+
break;
|
4410
|
+
case $.ui.keyCode.ENTER:
|
4411
|
+
node.editEnd(true, event);
|
4412
|
+
return false; // so we don't start editmode on Mac
|
4413
|
+
}
|
4414
|
+
}).blur(function(event){
|
4415
|
+
return node.editEnd(true, event);
|
4416
|
+
});
|
4417
|
+
|
4418
|
+
instOpts.edit.call(node, {type: "edit"}, eventData);
|
4419
|
+
};
|
4420
|
+
|
4421
|
+
|
4422
|
+
/**
|
4423
|
+
* [ext-edit] Stop inline editing.
|
4424
|
+
* @param {Boolean} [applyChanges=false]
|
4425
|
+
* @alias FancytreeNode#editEnd
|
4426
|
+
* @requires jquery.fancytree.edit.js
|
4427
|
+
*/
|
4428
|
+
$.ui.fancytree._FancytreeNodeClass.prototype.editEnd = function(applyChanges, _event){
|
4429
|
+
var node = this,
|
4430
|
+
tree = this.tree,
|
4431
|
+
local = tree.ext.edit,
|
4432
|
+
instOpts = tree.options.edit,
|
4433
|
+
$title = $(".fancytree-title", node.span),
|
4434
|
+
$input = $title.find("input.fancytree-edit-input"),
|
4435
|
+
newVal = $input.val(),
|
4436
|
+
dirty = $input.hasClass("fancytree-edit-dirty"),
|
4437
|
+
doSave = (applyChanges || (dirty && applyChanges !== false)) && (newVal !== node.title),
|
4438
|
+
eventData = {
|
4439
|
+
node: node, tree: tree, options: tree.options, originalEvent: _event,
|
4440
|
+
dirty: dirty,
|
4441
|
+
save: doSave,
|
4442
|
+
input: $input,
|
4443
|
+
value: newVal
|
4444
|
+
};
|
4445
|
+
|
4446
|
+
if( instOpts.beforeClose.call(node, {type: "beforeClose"}, eventData) === false){
|
4447
|
+
return false;
|
4448
|
+
}
|
4449
|
+
if( doSave && instOpts.save.call(node, {type: "save"}, eventData) === false){
|
4450
|
+
return false;
|
4451
|
+
}
|
4452
|
+
$input
|
4453
|
+
.removeClass("fancytree-edit-dirty")
|
4454
|
+
.unbind();
|
4455
|
+
// Unbind outer-click handler
|
4456
|
+
$(document).off(".fancytree-edit");
|
4457
|
+
|
4458
|
+
if( doSave ) {
|
4459
|
+
node.setTitle( newVal );
|
4460
|
+
}else{
|
4461
|
+
node.renderTitle();
|
4462
|
+
}
|
4463
|
+
// Re-enable mouse and keyboard handling
|
4464
|
+
tree.widget._bind();
|
4465
|
+
local.currentNode = null;
|
4466
|
+
node.setFocus();
|
4467
|
+
// Set keyboard focus, even if setFocus() claims 'nothing to do'
|
4468
|
+
$(tree.$container).focus();
|
4469
|
+
eventData.input = null;
|
4470
|
+
instOpts.close.call(node, {type: "close"}, eventData);
|
4471
|
+
return true;
|
4472
|
+
};
|
4473
|
+
|
4474
|
+
|
4475
|
+
$.ui.fancytree._FancytreeNodeClass.prototype.startEdit = function(){
|
4476
|
+
this.warn("FancytreeNode.startEdit() is deprecated. Use .editStart() instead.");
|
4477
|
+
return this.editStart.apply(this, arguments);
|
4478
|
+
};
|
4479
|
+
|
4480
|
+
|
4481
|
+
$.ui.fancytree._FancytreeNodeClass.prototype.endEdit = function(){
|
4482
|
+
this.warn("FancytreeNode.endEdit() is deprecated. Use .editEnd() instead.");
|
4483
|
+
return this.editEnd.apply(this, arguments);
|
4484
|
+
};
|
4485
|
+
|
4486
|
+
|
4487
|
+
///**
|
4488
|
+
// * Create a new child or sibling node.
|
4489
|
+
// *
|
4490
|
+
// * @param {String} [mode] 'before', 'after', or 'child'
|
4491
|
+
// * @lends FancytreeNode.prototype
|
4492
|
+
// * @requires jquery.fancytree.edit.js
|
4493
|
+
// */
|
4494
|
+
//$.ui.fancytree._FancytreeNodeClass.prototype.editCreateNode = function(mode){
|
4495
|
+
// var newNode,
|
4496
|
+
// node = this,
|
4497
|
+
// tree = this.tree,
|
4498
|
+
// local = tree.ext.edit,
|
4499
|
+
// instOpts = tree.options.edit,
|
4500
|
+
// $title = $(".fancytree-title", node.span),
|
4501
|
+
// $input = $title.find("input.fancytree-edit-input"),
|
4502
|
+
// newVal = $input.val(),
|
4503
|
+
// dirty = $input.hasClass("fancytree-edit-dirty"),
|
4504
|
+
// doSave = (applyChanges || (dirty && applyChanges !== false)) && (newVal !== node.title),
|
4505
|
+
// eventData = {
|
4506
|
+
// node: node, tree: tree, options: tree.options, originalEvent: _event,
|
4507
|
+
// dirty: dirty,
|
4508
|
+
// save: doSave,
|
4509
|
+
// input: $input,
|
4510
|
+
// value: newVal
|
4511
|
+
// };
|
4512
|
+
//
|
4513
|
+
// node.debug("editCreate");
|
4514
|
+
//
|
4515
|
+
// if( instOpts.beforeEdit.call(node, {type: "beforeCreateNode"}, eventData) === false){
|
4516
|
+
// return false;
|
4517
|
+
// }
|
4518
|
+
// newNode = this.addNode({title: "Neuer Knoten"}, mode);
|
4519
|
+
//
|
4520
|
+
// newNode.editStart();
|
4521
|
+
//};
|
4522
|
+
|
4523
|
+
|
4524
|
+
/**
|
4525
|
+
* [ext-edit] Check if any node in this tree in edit mode.
|
4526
|
+
*
|
4527
|
+
* @returns {FancytreeNode | null}
|
4528
|
+
* @lends Fancytree.prototype
|
4529
|
+
* @requires jquery.fancytree.edit.js
|
4530
|
+
*/
|
4531
|
+
$.ui.fancytree._FancytreeClass.prototype.isEditing = function(){
|
4532
|
+
return this.ext.edit.currentNode;
|
4533
|
+
};
|
4534
|
+
|
4535
|
+
|
4536
|
+
/**
|
4537
|
+
* [ext-edit] Check if this node is in edit mode.
|
4538
|
+
* @returns {Boolean} true if node is currently beeing edited
|
4539
|
+
* @lends FancytreeNode.prototype
|
4540
|
+
* @requires jquery.fancytree.edit.js
|
4541
|
+
*/
|
4542
|
+
$.ui.fancytree._FancytreeNodeClass.prototype.isEditing = function(){
|
4543
|
+
return this.tree.ext.edit.currentNode === this;
|
4544
|
+
};
|
4545
|
+
|
4546
|
+
|
4547
|
+
/*******************************************************************************
|
4548
|
+
* Extension code
|
4549
|
+
*/
|
4550
|
+
$.ui.fancytree.registerExtension({
|
4551
|
+
name: "edit",
|
4552
|
+
version: "0.1.0",
|
4553
|
+
// Default options for this extension.
|
4554
|
+
options: {
|
4555
|
+
adjustWidthOfs: 4, // null: don't adjust input size to content
|
4556
|
+
inputCss: {minWidth: "3em"},
|
4557
|
+
triggerCancel: ["esc", "tab", "click"],
|
4558
|
+
// triggerStart: ["f2", "dblclick", "shift+click", "mac+enter"],
|
4559
|
+
triggerStart: ["f2", "shift+click", "mac+enter"],
|
4560
|
+
beforeClose: $.noop, // Return false to prevent cancel/save (data.input is available)
|
4561
|
+
beforeEdit: $.noop, // Return false to prevent edit mode
|
4562
|
+
close: $.noop, // Editor was removed
|
4563
|
+
edit: $.noop, // Editor was opened (available as data.input)
|
4564
|
+
// keypress: $.noop, // Not yet implemented
|
4565
|
+
save: $.noop // Save data.input.val() or return false to keep editor open
|
4566
|
+
},
|
4567
|
+
// Local attributes
|
4568
|
+
currentNode: null,
|
4569
|
+
|
4570
|
+
// Override virtual methods for this extension.
|
4571
|
+
// `this` : the Fancytree instance
|
4572
|
+
// `this._local`: the namespace that contains extension attributes and private methods (same as this.ext.EXTNAME)
|
4573
|
+
// `this._super`: the virtual function that was overridden (member of previous extension or Fancytree)
|
4574
|
+
treeInit: function(ctx){
|
4575
|
+
this._super(ctx);
|
4576
|
+
this.$container.addClass("fancytree-ext-edit");
|
4577
|
+
},
|
4578
|
+
nodeClick: function(ctx) {
|
4579
|
+
if( $.inArray("shift+click", ctx.options.edit.triggerStart) >= 0 ){
|
4580
|
+
if( ctx.originalEvent.shiftKey ){
|
4581
|
+
ctx.node.editStart();
|
4582
|
+
return false;
|
4583
|
+
}
|
4584
|
+
}
|
4585
|
+
this._super(ctx);
|
4586
|
+
},
|
4587
|
+
nodeDblclick: function(ctx) {
|
4588
|
+
if( $.inArray("dblclick", ctx.options.edit.triggerStart) >= 0 ){
|
4589
|
+
ctx.node.editStart();
|
4590
|
+
return false;
|
4591
|
+
}
|
4592
|
+
return this._super(ctx);
|
4593
|
+
},
|
4594
|
+
nodeKeydown: function(ctx) {
|
4595
|
+
switch( ctx.originalEvent.which ) {
|
4596
|
+
case 113: // [F2]
|
4597
|
+
if( $.inArray("f2", ctx.options.edit.triggerStart) >= 0 ){
|
4598
|
+
ctx.node.editStart();
|
4599
|
+
return false;
|
4600
|
+
}
|
4601
|
+
break;
|
4602
|
+
case $.ui.keyCode.ENTER:
|
4603
|
+
if( $.inArray("mac+enter", ctx.options.edit.triggerStart) >= 0 && isMac ){
|
4604
|
+
ctx.node.editStart();
|
4605
|
+
return false;
|
4606
|
+
}
|
4607
|
+
break;
|
4608
|
+
}
|
4609
|
+
return this._super(ctx);
|
4610
|
+
}
|
4611
|
+
});
|
4612
|
+
}(jQuery, window, document));
|
4613
|
+
|
4405
4614
|
/*!
|
4406
4615
|
* jquery.fancytree.filter.js
|
4407
4616
|
*
|
4408
4617
|
* Remove or highlight tree nodes, based on a filter.
|
4409
4618
|
* (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/)
|
4410
4619
|
*
|
4411
|
-
* Copyright (c)
|
4620
|
+
* Copyright (c) 2014, Martin Wendt (http://wwWendt.de)
|
4412
4621
|
*
|
4413
4622
|
* Released under the MIT license
|
4414
4623
|
* https://github.com/mar10/fancytree/wiki/LicenseInfo
|
4415
4624
|
*
|
4416
|
-
* @version 2.0.0-
|
4417
|
-
* @date 2014-
|
4625
|
+
* @version 2.0.0-6
|
4626
|
+
* @date 2014-02-10T10:52
|
4418
4627
|
*/
|
4419
4628
|
|
4420
4629
|
;(function($, window, document, undefined) {
|
@@ -4499,7 +4708,8 @@ $.ui.fancytree._FancytreeClass.prototype.clearFilter = function(){
|
|
4499
4708
|
/*******************************************************************************
|
4500
4709
|
* Extension code
|
4501
4710
|
*/
|
4502
|
-
$.ui.fancytree.registerExtension(
|
4711
|
+
$.ui.fancytree.registerExtension({
|
4712
|
+
name: "filter",
|
4503
4713
|
version: "0.0.1",
|
4504
4714
|
// Default options for this extension.
|
4505
4715
|
options: {
|
@@ -4558,157 +4768,143 @@ $.ui.fancytree.registerExtension("filter", {
|
|
4558
4768
|
}(jQuery, window, document));
|
4559
4769
|
|
4560
4770
|
/*!
|
4561
|
-
* jquery.fancytree.
|
4771
|
+
* jquery.fancytree.gridnav.js
|
4562
4772
|
*
|
4563
|
-
*
|
4773
|
+
* Support keyboard navigation for trees with embedded input controls.
|
4564
4774
|
* (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/)
|
4565
4775
|
*
|
4566
|
-
*
|
4567
|
-
*
|
4568
|
-
* Copyright (c) 2013, Martin Wendt (http://wwWendt.de)
|
4776
|
+
* Copyright (c) 2014, Martin Wendt (http://wwWendt.de)
|
4569
4777
|
*
|
4570
4778
|
* Released under the MIT license
|
4571
4779
|
* https://github.com/mar10/fancytree/wiki/LicenseInfo
|
4572
4780
|
*
|
4573
|
-
* @version 2.0.0-
|
4574
|
-
* @date 2014-
|
4781
|
+
* @version 2.0.0-6
|
4782
|
+
* @date 2014-02-10T10:52
|
4575
4783
|
*/
|
4576
4784
|
|
4577
4785
|
;(function($, window, document, undefined) {
|
4578
4786
|
|
4579
4787
|
"use strict";
|
4580
4788
|
|
4581
|
-
// prevent duplicate loading
|
4582
|
-
// if ( $.ui.fancytree && $.ui.fancytree.version ) {
|
4583
|
-
// $.ui.fancytree.warn("Fancytree: duplicate include");
|
4584
|
-
// return;
|
4585
|
-
// }
|
4586
4789
|
|
4587
|
-
|
4790
|
+
/*******************************************************************************
|
4791
|
+
* Private functions and variables
|
4792
|
+
*/
|
4793
|
+
|
4794
|
+
// Allow these navigation keys even when input controls are focused
|
4795
|
+
|
4796
|
+
var KC = $.ui.keyCode,
|
4797
|
+
// which keys are *not* handled by embedded control, but passed to tree
|
4798
|
+
// navigation handler:
|
4799
|
+
NAV_KEYS = {
|
4800
|
+
"text": [KC.UP, KC.DOWN],
|
4801
|
+
"checkbox": [KC.UP, KC.DOWN, KC.LEFT, KC.RIGHT],
|
4802
|
+
"radiobutton": [KC.UP, KC.DOWN, KC.LEFT, KC.RIGHT],
|
4803
|
+
"select-one": [KC.LEFT, KC.RIGHT],
|
4804
|
+
"select-multiple": [KC.LEFT, KC.RIGHT]
|
4805
|
+
};
|
4806
|
+
|
4807
|
+
|
4808
|
+
function findNeighbourTd($target, keyCode){
|
4809
|
+
var $td = $target.closest("td");
|
4810
|
+
switch( keyCode ){
|
4811
|
+
case KC.LEFT:
|
4812
|
+
return $td.prev();
|
4813
|
+
case KC.RIGHT:
|
4814
|
+
return $td.next();
|
4815
|
+
case KC.UP:
|
4816
|
+
return $td.parent().prevAll(":visible").first().find("td").eq($td.index());
|
4817
|
+
case KC.DOWN:
|
4818
|
+
return $td.parent().nextAll(":visible").first().find("td").eq($td.index());
|
4819
|
+
}
|
4820
|
+
return null;
|
4821
|
+
}
|
4822
|
+
|
4823
|
+
/*******************************************************************************
|
4824
|
+
* Extension code
|
4825
|
+
*/
|
4826
|
+
$.ui.fancytree.registerExtension({
|
4827
|
+
name: "gridnav",
|
4588
4828
|
version: "0.0.1",
|
4589
4829
|
// Default options for this extension.
|
4590
4830
|
options: {
|
4591
|
-
|
4592
|
-
|
4593
|
-
position: {}, //
|
4594
|
-
// Events:
|
4595
|
-
create: $.noop, //
|
4596
|
-
beforeOpen: $.noop, //
|
4597
|
-
open: $.noop, //
|
4598
|
-
focus: $.noop, //
|
4599
|
-
select: $.noop, //
|
4600
|
-
close: $.noop //
|
4831
|
+
autofocusInput: false, // Focus first embedded input if node gets activated
|
4832
|
+
handleCursorKeys: true // Allow UP/DOWN in inputs to move to prev/next node
|
4601
4833
|
},
|
4602
|
-
// Override virtual methods for this extension.
|
4603
|
-
// `this` : is this extension object
|
4604
|
-
// `this._base` : the Fancytree instance
|
4605
|
-
// `this._super`: the virtual function that was overridden (member of prev. extension or Fancytree)
|
4606
|
-
treeInit: function(ctx){
|
4607
|
-
var opts = ctx.options,
|
4608
|
-
tree = ctx.tree;
|
4609
4834
|
|
4835
|
+
treeInit: function(ctx){
|
4836
|
+
// gridnav requires the table extension to be loaded before itself
|
4837
|
+
this._requireExtension("table", true, true);
|
4610
4838
|
this._super(ctx);
|
4611
4839
|
|
4612
|
-
|
4613
|
-
tree.ext.menu.data = {
|
4614
|
-
tree: tree,
|
4615
|
-
node: null,
|
4616
|
-
$menu: null,
|
4617
|
-
menuId: null
|
4618
|
-
};
|
4840
|
+
this.$container.addClass("fancytree-ext-gridnav");
|
4619
4841
|
|
4620
|
-
//
|
4621
|
-
|
4622
|
-
|
4623
|
-
|
4624
|
-
ctx = {node: node, tree: node.tree, originalEvent: event, options: tree.options};
|
4625
|
-
tree.ext.menu._openMenu(ctx);
|
4626
|
-
return false;
|
4627
|
-
});
|
4842
|
+
// Activate node if embedded input gets focus (due to a click)
|
4843
|
+
this.$container.on("focusin", function(event){
|
4844
|
+
var ctx2,
|
4845
|
+
node = $.ui.fancytree.getNode(event.target);
|
4628
4846
|
|
4629
|
-
|
4630
|
-
|
4631
|
-
|
4632
|
-
tree.
|
4633
|
-
var data = $.extend({}, tree.ext.menu.data);
|
4634
|
-
opts.menu.create.call(tree, event, data);
|
4635
|
-
},
|
4636
|
-
focus: function(event, ui){
|
4637
|
-
var data = $.extend({}, tree.ext.menu.data, {
|
4638
|
-
menuItem: ui.item,
|
4639
|
-
menuId: ui.item.find(">a").attr("href")
|
4640
|
-
});
|
4641
|
-
opts.menu.focus.call(tree, event, data);
|
4642
|
-
},
|
4643
|
-
select: function(event, ui){
|
4644
|
-
var data = $.extend({}, tree.ext.menu.data, {
|
4645
|
-
menuItem: ui.item,
|
4646
|
-
menuId: ui.item.find(">a").attr("href")
|
4647
|
-
});
|
4648
|
-
if( opts.menu.select.call(tree, event, data) !== false){
|
4649
|
-
tree.ext.menu._closeMenu(ctx);
|
4650
|
-
}
|
4847
|
+
if( node && !node.isActive() ){
|
4848
|
+
// Call node.setActive(), but also pass the event
|
4849
|
+
ctx2 = ctx.tree._makeHookContext(node, event);
|
4850
|
+
ctx.tree._callHook("nodeSetActive", ctx2, true);
|
4651
4851
|
}
|
4652
|
-
})
|
4653
|
-
},
|
4654
|
-
treeDestroy: function(ctx){
|
4655
|
-
this._super(ctx);
|
4852
|
+
});
|
4656
4853
|
},
|
4657
|
-
|
4658
|
-
var
|
4659
|
-
|
4660
|
-
|
4661
|
-
|
4854
|
+
nodeSetActive: function(ctx, flag) {
|
4855
|
+
var $outer,
|
4856
|
+
opts = ctx.options.gridnav,
|
4857
|
+
node = ctx.node,
|
4858
|
+
event = ctx.originalEvent || {},
|
4859
|
+
triggeredByInput = $(event.target).is(":input");
|
4662
4860
|
|
4663
|
-
|
4664
|
-
data = $.extend({}, tree.ext.menu.data);
|
4861
|
+
flag = (flag !== false);
|
4665
4862
|
|
4666
|
-
|
4667
|
-
return;
|
4668
|
-
}
|
4863
|
+
this._super(ctx, flag);
|
4669
4864
|
|
4670
|
-
|
4671
|
-
if(
|
4672
|
-
|
4673
|
-
|
4674
|
-
|
4675
|
-
|
4676
|
-
|
4677
|
-
tree.
|
4865
|
+
if( flag ){
|
4866
|
+
if( ctx.options.titlesTabbable ){
|
4867
|
+
if( !triggeredByInput ) {
|
4868
|
+
$(node.span).find("span.fancytree-title").focus();
|
4869
|
+
node.setFocus();
|
4870
|
+
}
|
4871
|
+
// If one node is tabbable, the container no longer needs to be
|
4872
|
+
ctx.tree.$container.attr("tabindex", "-1");
|
4873
|
+
// ctx.tree.$container.removeAttr("tabindex");
|
4874
|
+
} else if( opts.autofocusInput && !triggeredByInput ){
|
4875
|
+
// Set focus to input sub input (if node was clicked, but not
|
4876
|
+
// when TAB was pressed )
|
4877
|
+
$outer = $(node.tr || node.span);
|
4878
|
+
$outer.find(":input:enabled:first").focus();
|
4678
4879
|
}
|
4679
|
-
}
|
4680
|
-
// $menu.position($.extend({my: "left top", at: "left bottom", of: event}, opts.menu.position));
|
4681
|
-
$menu
|
4682
|
-
.css("position", "absolute")
|
4683
|
-
.show()
|
4684
|
-
.position({my: "left top", at: "right top", of: ctx.originalEvent, collision: "fit"})
|
4685
|
-
.focus();
|
4686
|
-
|
4687
|
-
opts.menu.open.call(tree, ctx.originalEvent, data);
|
4880
|
+
}
|
4688
4881
|
},
|
4689
|
-
|
4690
|
-
var $
|
4691
|
-
|
4692
|
-
|
4693
|
-
|
4694
|
-
|
4695
|
-
|
4882
|
+
nodeKeydown: function(ctx) {
|
4883
|
+
var inputType, handleKeys, $td,
|
4884
|
+
opts = ctx.options.gridnav,
|
4885
|
+
event = ctx.originalEvent,
|
4886
|
+
$target = $(event.target);
|
4887
|
+
|
4888
|
+
// jQuery
|
4889
|
+
inputType = $target.is(":input:enabled") ? $target.prop("type") : null;
|
4890
|
+
ctx.tree.debug("ext-gridnav nodeKeydown", event, inputType);
|
4891
|
+
|
4892
|
+
if( inputType && opts.handleCursorKeys ){
|
4893
|
+
handleKeys = NAV_KEYS[inputType];
|
4894
|
+
if( handleKeys && $.inArray(event.which, handleKeys) >= 0 ){
|
4895
|
+
$td = findNeighbourTd($target, event.which);
|
4896
|
+
// ctx.node.debug("ignore keydown in input", event.which, handleKeys);
|
4897
|
+
if( $td && $td.length ) {
|
4898
|
+
$td.find(":input:enabled").focus();
|
4899
|
+
// Prevent Fancytree default navigation
|
4900
|
+
return false;
|
4901
|
+
}
|
4902
|
+
}
|
4903
|
+
return true;
|
4696
4904
|
}
|
4697
|
-
|
4698
|
-
|
4699
|
-
$menu.hide();
|
4700
|
-
tree.ext.menu.data.node = null;
|
4905
|
+
ctx.tree.debug("ext-gridnav NOT HANDLED", event, inputType);
|
4906
|
+
return this._super(ctx);
|
4701
4907
|
}
|
4702
|
-
// ,
|
4703
|
-
// nodeClick: function(ctx) {
|
4704
|
-
// var event = ctx.originalEvent;
|
4705
|
-
// if(event.which === 2 || (event.which === 1 && event.ctrlKey)){
|
4706
|
-
// event.preventDefault();
|
4707
|
-
// ctx.tree.ext.menu._openMenu(ctx);
|
4708
|
-
// return false;
|
4709
|
-
// }
|
4710
|
-
// this._super(ctx);
|
4711
|
-
// }
|
4712
4908
|
});
|
4713
4909
|
}(jQuery, window, document));
|
4714
4910
|
|
@@ -4720,13 +4916,13 @@ $.ui.fancytree.registerExtension("menu", {
|
|
4720
4916
|
*
|
4721
4917
|
* @depends: jquery.cookie.js
|
4722
4918
|
*
|
4723
|
-
* Copyright (c)
|
4919
|
+
* Copyright (c) 2014, Martin Wendt (http://wwWendt.de)
|
4724
4920
|
*
|
4725
4921
|
* Released under the MIT license
|
4726
4922
|
* https://github.com/mar10/fancytree/wiki/LicenseInfo
|
4727
4923
|
*
|
4728
|
-
* @version 2.0.0-
|
4729
|
-
* @date 2014-
|
4924
|
+
* @version 2.0.0-6
|
4925
|
+
* @date 2014-02-10T10:52
|
4730
4926
|
*/
|
4731
4927
|
|
4732
4928
|
;(function($, window, document, undefined) {
|
@@ -4803,7 +4999,8 @@ $.ui.fancytree._FancytreeClass.prototype.getPersistData = function(){
|
|
4803
4999
|
/* *****************************************************************************
|
4804
5000
|
* Extension code
|
4805
5001
|
*/
|
4806
|
-
$.ui.fancytree.registerExtension(
|
5002
|
+
$.ui.fancytree.registerExtension({
|
5003
|
+
name: "persist",
|
4807
5004
|
version: "0.0.1",
|
4808
5005
|
// Default options for this extension.
|
4809
5006
|
options: {
|
@@ -4927,11 +5124,11 @@ $.ui.fancytree.registerExtension("persist", {
|
|
4927
5124
|
// treeDestroy: function(ctx){
|
4928
5125
|
// this._super(ctx);
|
4929
5126
|
// },
|
4930
|
-
nodeSetActive: function(ctx, flag) {
|
5127
|
+
nodeSetActive: function(ctx, flag, opts) {
|
4931
5128
|
var instData = this._local,
|
4932
5129
|
instOpts = this.options.persist;
|
4933
5130
|
|
4934
|
-
this._super(ctx, flag);
|
5131
|
+
this._super(ctx, flag, opts);
|
4935
5132
|
|
4936
5133
|
if(instData.storeActive){
|
4937
5134
|
$.cookie(instData.cookiePrefix + ACTIVE,
|
@@ -4939,15 +5136,17 @@ $.ui.fancytree.registerExtension("persist", {
|
|
4939
5136
|
instOpts.cookie);
|
4940
5137
|
}
|
4941
5138
|
},
|
4942
|
-
nodeSetExpanded: function(ctx, flag) {
|
4943
|
-
var
|
5139
|
+
nodeSetExpanded: function(ctx, flag, opts) {
|
5140
|
+
var res,
|
5141
|
+
node = ctx.node,
|
4944
5142
|
instData = this._local;
|
4945
5143
|
|
4946
|
-
this._super(ctx, flag);
|
5144
|
+
res = this._super(ctx, flag, opts);
|
4947
5145
|
|
4948
5146
|
if(instData.storeExpanded){
|
4949
5147
|
instData._setKey(EXPANDED, node.key, flag);
|
4950
5148
|
}
|
5149
|
+
return res;
|
4951
5150
|
},
|
4952
5151
|
nodeSetFocus: function(ctx) {
|
4953
5152
|
var instData = this._local,
|
@@ -4980,13 +5179,13 @@ $.ui.fancytree.registerExtension("persist", {
|
|
4980
5179
|
* Render tree as table (aka 'treegrid', 'tabletree').
|
4981
5180
|
* (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/)
|
4982
5181
|
*
|
4983
|
-
* Copyright (c)
|
5182
|
+
* Copyright (c) 2014, Martin Wendt (http://wwWendt.de)
|
4984
5183
|
*
|
4985
5184
|
* Released under the MIT license
|
4986
5185
|
* https://github.com/mar10/fancytree/wiki/LicenseInfo
|
4987
5186
|
*
|
4988
|
-
* @version 2.0.0-
|
4989
|
-
* @date 2014-
|
5187
|
+
* @version 2.0.0-6
|
5188
|
+
* @date 2014-02-10T10:52
|
4990
5189
|
*/
|
4991
5190
|
|
4992
5191
|
;(function($, window, document, undefined) {
|
@@ -5047,8 +5246,9 @@ function findPrevRowNode(node){
|
|
5047
5246
|
}
|
5048
5247
|
|
5049
5248
|
|
5050
|
-
$.ui.fancytree.registerExtension(
|
5051
|
-
|
5249
|
+
$.ui.fancytree.registerExtension({
|
5250
|
+
name: "table",
|
5251
|
+
version: "0.1.0",
|
5052
5252
|
// Default options for this extension.
|
5053
5253
|
options: {
|
5054
5254
|
indentation: 16, // indent every node level by 16px
|
@@ -5132,16 +5332,16 @@ $.ui.fancytree.registerExtension("table", {
|
|
5132
5332
|
node = ctx.node,
|
5133
5333
|
opts = ctx.options,
|
5134
5334
|
isRootNode = !node.parent;
|
5135
|
-
|
5335
|
+
|
5136
5336
|
if( !_recursive ){
|
5137
5337
|
ctx.hasCollapsedParents = node.parent && !node.parent.expanded;
|
5138
5338
|
}
|
5339
|
+
$.ui.fancytree.debug("*** nodeRender " + node + ", isRoot=" + isRootNode);
|
5139
5340
|
if( !isRootNode ){
|
5140
5341
|
if(!node.tr){
|
5141
5342
|
// Create new <tr> after previous row
|
5142
5343
|
newRow = tree.rowFragment.firstChild.cloneNode(true);
|
5143
5344
|
prevNode = findPrevRowNode(node);
|
5144
|
-
// firstTime = true;
|
5145
5345
|
// $.ui.fancytree.debug("*** nodeRender " + node + ": prev: " + prevNode.key);
|
5146
5346
|
_assert(prevNode);
|
5147
5347
|
if(collapsed === true && _recursive){
|
@@ -5178,7 +5378,7 @@ $.ui.fancytree.registerExtension("table", {
|
|
5178
5378
|
}
|
5179
5379
|
} else {
|
5180
5380
|
// Set icon, link, and title (normally this is only required on initial render)
|
5181
|
-
this.nodeRenderTitle(ctx);
|
5381
|
+
//this.nodeRenderTitle(ctx);
|
5182
5382
|
}
|
5183
5383
|
}
|
5184
5384
|
// Allow tweaking after node state was rendered
|
@@ -5203,10 +5403,10 @@ $.ui.fancytree.registerExtension("table", {
|
|
5203
5403
|
// Iterate over all descendants
|
5204
5404
|
node.visit(function(n){
|
5205
5405
|
if(n.tr){
|
5206
|
-
if(!
|
5207
|
-
// fix after a node was dropped over a
|
5208
|
-
// In this case it must be hidden
|
5406
|
+
if(!n.parent.expanded && n.tr.style.display !== "none"){
|
5407
|
+
// fix after a node was dropped over a collapsed
|
5209
5408
|
n.tr.style.display = "none";
|
5409
|
+
setChildRowVisibility(n, false);
|
5210
5410
|
}
|
5211
5411
|
if(n.tr.previousSibling !== prevTr){
|
5212
5412
|
node.debug("_fixOrder: mismatch at node: " + n);
|
@@ -5221,12 +5421,6 @@ $.ui.fancytree.registerExtension("table", {
|
|
5221
5421
|
if(!isRootNode){
|
5222
5422
|
this.nodeRenderStatus(ctx);
|
5223
5423
|
}
|
5224
|
-
// Finally add the whole structure to the DOM, so the browser can render
|
5225
|
-
// if(firstTime){
|
5226
|
-
// parent.ul.appendChild(node.li);
|
5227
|
-
// }
|
5228
|
-
// TODO: just for debugging
|
5229
|
-
// this._super(ctx);
|
5230
5424
|
},
|
5231
5425
|
nodeRenderTitle: function(ctx, title) {
|
5232
5426
|
var $cb,
|
@@ -5234,12 +5428,12 @@ $.ui.fancytree.registerExtension("table", {
|
|
5234
5428
|
opts = ctx.options;
|
5235
5429
|
|
5236
5430
|
this._super(ctx);
|
5237
|
-
|
5431
|
+
// Move checkbox to custom column
|
5238
5432
|
if(opts.checkbox && opts.table.checkboxColumnIdx != null){
|
5239
5433
|
$cb = $("span.fancytree-checkbox", node.span).detach();
|
5240
5434
|
$(node.tr).find("td:first").html($cb);
|
5241
5435
|
}
|
5242
|
-
//
|
5436
|
+
// Let user code write column content
|
5243
5437
|
// ctx.tree._triggerNodeEvent("renderColumns", node);
|
5244
5438
|
if ( opts.renderColumns ){
|
5245
5439
|
opts.renderColumns.call(ctx.tree, {type: "renderColumns"}, ctx);
|
@@ -5251,16 +5445,15 @@ $.ui.fancytree.registerExtension("table", {
|
|
5251
5445
|
opts = ctx.options;
|
5252
5446
|
|
5253
5447
|
this._super(ctx);
|
5448
|
+
|
5254
5449
|
$(node.tr).removeClass("fancytree-node");
|
5255
5450
|
// indent
|
5256
5451
|
indent = (node.getLevel() - 1) * opts.table.indentation;
|
5257
|
-
|
5258
|
-
$(node.span).css({marginLeft: indent + "px"});
|
5259
|
-
}
|
5452
|
+
$(node.span).css({marginLeft: indent + "px"});
|
5260
5453
|
},
|
5261
5454
|
/* Expand node, return Deferred.promise. */
|
5262
|
-
nodeSetExpanded: function(ctx, flag) {
|
5263
|
-
return this._super(ctx, flag).always(function () {
|
5455
|
+
nodeSetExpanded: function(ctx, flag, opts) {
|
5456
|
+
return this._super(ctx, flag, opts).always(function () {
|
5264
5457
|
flag = (flag !== false);
|
5265
5458
|
setChildRowVisibility(ctx.node, flag);
|
5266
5459
|
});
|
@@ -5291,13 +5484,13 @@ $.ui.fancytree.registerExtension("table", {
|
|
5291
5484
|
*
|
5292
5485
|
* @see http://jqueryui.com/themeroller/
|
5293
5486
|
*
|
5294
|
-
* Copyright (c)
|
5487
|
+
* Copyright (c) 2014, Martin Wendt (http://wwWendt.de)
|
5295
5488
|
*
|
5296
5489
|
* Released under the MIT license
|
5297
5490
|
* https://github.com/mar10/fancytree/wiki/LicenseInfo
|
5298
5491
|
*
|
5299
|
-
* @version 2.0.0-
|
5300
|
-
* @date 2014-
|
5492
|
+
* @version 2.0.0-6
|
5493
|
+
* @date 2014-02-10T10:52
|
5301
5494
|
*/
|
5302
5495
|
|
5303
5496
|
;(function($, window, document, undefined) {
|
@@ -5307,7 +5500,8 @@ $.ui.fancytree.registerExtension("table", {
|
|
5307
5500
|
/*******************************************************************************
|
5308
5501
|
* Extension code
|
5309
5502
|
*/
|
5310
|
-
$.ui.fancytree.registerExtension(
|
5503
|
+
$.ui.fancytree.registerExtension({
|
5504
|
+
name: "themeroller",
|
5311
5505
|
version: "0.0.1",
|
5312
5506
|
// Default options for this extension.
|
5313
5507
|
options: {
|