Upgrade to ExtJS 3.3.1 - Released 11/30/2010
[extjs.git] / examples / docs / source / TreeGridSorter.html
1 <html>
2 <head>
3   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    
4   <title>The source code</title>
5     <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
6     <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
7 </head>
8 <body  onload="prettyPrint();">
9     <pre class="prettyprint lang-js">/*!
10  * Ext JS Library 3.3.1
11  * Copyright(c) 2006-2010 Sencha Inc.
12  * licensing@sencha.com
13  * http://www.sencha.com/license
14  */
15 Ext.ns('Ext.ux.tree');
16
17 <div id="cls-Ext.ux.tree.TreeGridSorter"></div>/**
18  * @class Ext.ux.tree.TreeGridSorter
19  * @extends Ext.tree.TreeSorter
20  * Provides sorting of nodes in a {@link Ext.ux.tree.TreeGrid}.  The TreeGridSorter automatically monitors events on the
21  * associated TreeGrid that might affect the tree's sort order (beforechildrenrendered, append, insert and textchange).
22  * Example usage:<br />
23  * <pre><code>
24  new Ext.ux.tree.TreeGridSorter(myTreeGrid, {
25      folderSort: true,
26      dir: "desc",
27      sortType: function(node) {
28          // sort by a custom, typed attribute:
29          return parseInt(node.id, 10);
30      }
31  });
32  </code></pre>
33  * @constructor
34  * @param {TreeGrid} tree
35  * @param {Object} config
36  */
37 Ext.ux.tree.TreeGridSorter = Ext.extend(Ext.tree.TreeSorter, {
38     <div id="cfg-Ext.ux.tree.TreeGridSorter-sortClasses"></div>/**
39      * @cfg {Array} sortClasses The CSS classes applied to a header when it is sorted. (defaults to <tt>['sort-asc', 'sort-desc']</tt>)
40      */
41     sortClasses : ['sort-asc', 'sort-desc'],
42     <div id="cfg-Ext.ux.tree.TreeGridSorter-sortAscText"></div>/**
43      * @cfg {String} sortAscText The text displayed in the 'Sort Ascending' menu item (defaults to <tt>'Sort Ascending'</tt>)
44      */
45     sortAscText : 'Sort Ascending',
46     <div id="cfg-Ext.ux.tree.TreeGridSorter-sortDescText"></div>/**
47      * @cfg {String} sortDescText The text displayed in the 'Sort Descending' menu item (defaults to <tt>'Sort Descending'</tt>)
48      */
49     sortDescText : 'Sort Descending',
50
51     constructor : function(tree, config) {
52         if(!Ext.isObject(config)) {
53             config = {
54                 property: tree.columns[0].dataIndex || 'text',
55                 folderSort: true
56             }
57         }
58
59         Ext.ux.tree.TreeGridSorter.superclass.constructor.apply(this, arguments);
60
61         this.tree = tree;
62         tree.on('headerclick', this.onHeaderClick, this);
63         tree.ddAppendOnly = true;
64
65         var me = this;
66         this.defaultSortFn = function(n1, n2){
67
68             var desc = me.dir && me.dir.toLowerCase() == 'desc',
69                 prop = me.property || 'text',
70                 sortType = me.sortType,
71                 caseSensitive = me.caseSensitive === true,
72                 leafAttr = me.leafAttr || 'leaf',
73                 attr1 = n1.attributes,
74                 attr2 = n2.attributes;
75
76             if(me.folderSort){
77                 if(attr1[leafAttr] && !attr2[leafAttr]){
78                     return 1;
79                 }
80                 if(!attr1[leafAttr] && attr2[leafAttr]){
81                     return -1;
82                 }
83             }
84             var prop1 = attr1[prop],
85                 prop2 = attr2[prop],
86                 v1 = sortType ? sortType(prop1) : (caseSensitive ? prop1 : prop1.toUpperCase());
87                 v2 = sortType ? sortType(prop2) : (caseSensitive ? prop2 : prop2.toUpperCase());
88                 
89             if(v1 < v2){
90                 return desc ? +1 : -1;
91             }else if(v1 > v2){
92                 return desc ? -1 : +1;
93             }else{
94                 return 0;
95             }
96         };
97
98         tree.on('afterrender', this.onAfterTreeRender, this, {single: true});
99         tree.on('headermenuclick', this.onHeaderMenuClick, this);
100     },
101
102     onAfterTreeRender : function() {
103         if(this.tree.hmenu){
104             this.tree.hmenu.insert(0,
105                 {itemId:'asc', text: this.sortAscText, cls: 'xg-hmenu-sort-asc'},
106                 {itemId:'desc', text: this.sortDescText, cls: 'xg-hmenu-sort-desc'}
107             );
108         }
109         this.updateSortIcon(0, 'asc');
110     },
111
112     onHeaderMenuClick : function(c, id, index) {
113         if(id === 'asc' || id === 'desc') {
114             this.onHeaderClick(c, null, index);
115             return false;
116         }
117     },
118
119     onHeaderClick : function(c, el, i) {
120         if(c && !this.tree.headersDisabled){
121             var me = this;
122
123             me.property = c.dataIndex;
124             me.dir = c.dir = (c.dir === 'desc' ? 'asc' : 'desc');
125             me.sortType = c.sortType;
126             me.caseSensitive === Ext.isBoolean(c.caseSensitive) ? c.caseSensitive : this.caseSensitive;
127             me.sortFn = c.sortFn || this.defaultSortFn;
128
129             this.tree.root.cascade(function(n) {
130                 if(!n.isLeaf()) {
131                     me.updateSort(me.tree, n);
132                 }
133             });
134
135             this.updateSortIcon(i, c.dir);
136         }
137     },
138
139     // private
140     updateSortIcon : function(col, dir){
141         var sc = this.sortClasses,
142             hds = this.tree.innerHd.select('td').removeClass(sc);
143         hds.item(col).addClass(sc[dir == 'desc' ? 1 : 0]);
144     }
145 });</pre>    
146 </body>
147 </html>