3 * Copyright(c) 2006-2010 Sencha Inc.
5 * http://www.sencha.com/license
8 * @class Ext.tree.TreeSorter
9 * Provides sorting of nodes in a {@link Ext.tree.TreePanel}. The TreeSorter automatically monitors events on the
10 * associated TreePanel that might affect the tree's sort order (beforechildrenrendered, append, insert and textchange).
11 * Example usage:<br />
13 new Ext.tree.TreeSorter(myTree, {
16 sortType: function(node) {
17 // sort by a custom, typed attribute:
18 return parseInt(node.id, 10);
23 * @param {TreePanel} tree
24 * @param {Object} config
26 Ext.tree.TreeSorter = Ext.extend(Object, {
28 constructor: function(tree, config){
30 * @cfg {Boolean} folderSort True to sort leaf nodes under non-leaf nodes (defaults to false)
33 * @cfg {String} property The named attribute on the node to sort by (defaults to "text"). Note that this
34 * property is only used if no {@link #sortType} function is specified, otherwise it is ignored.
37 * @cfg {String} dir The direction to sort ("asc" or "desc," case-insensitive, defaults to "asc")
40 * @cfg {String} leafAttr The attribute used to determine leaf nodes when {@link #folderSort} = true (defaults to "leaf")
43 * @cfg {Boolean} caseSensitive true for case-sensitive sort (defaults to false)
46 * @cfg {Function} sortType A custom "casting" function used to convert node values before sorting. The function
47 * will be called with a single parameter (the {@link Ext.tree.TreeNode} being evaluated) and is expected to return
48 * the node's sort value cast to the specific data type required for sorting. This could be used, for example, when
49 * a node's text (or other attribute) should be sorted as a date or numeric value. See the class description for
50 * example usage. Note that if a sortType is specified, any {@link #property} config will be ignored.
53 Ext.apply(this, config);
56 beforechildrenrendered: this.doSort,
57 append: this.updateSort,
58 insert: this.updateSort,
59 textchange: this.updateSortParent
62 var desc = this.dir && this.dir.toLowerCase() == 'desc',
63 prop = this.property || 'text';
64 sortType = this.sortType;
65 folderSort = this.folderSort;
66 caseSensitive = this.caseSensitive === true;
67 leafAttr = this.leafAttr || 'leaf';
69 if(Ext.isString(sortType)){
70 sortType = Ext.data.SortTypes[sortType];
72 this.sortFn = function(n1, n2){
73 var attr1 = n1.attributes,
74 attr2 = n2.attributes;
77 if(attr1[leafAttr] && !attr2[leafAttr]){
80 if(!attr1[leafAttr] && attr2[leafAttr]){
84 var prop1 = attr1[prop],
86 v1 = sortType ? sortType(prop1) : (caseSensitive ? prop1 : prop1.toUpperCase());
87 v2 = sortType ? sortType(prop2) : (caseSensitive ? prop2 : prop2.toUpperCase());
98 doSort : function(node){
99 node.sort(this.sortFn);
102 updateSort : function(tree, node){
103 if(node.childrenRendered){
104 this.doSort.defer(1, this, [node]);
108 updateSortParent : function(node){
109 var p = node.parentNode;
110 if(p && p.childrenRendered){
111 this.doSort.defer(1, this, [p]);