X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/25ef3491bd9ae007ff1fc2b0d7943e6eaaccf775..6e39d509471fe9b4e2660e0d1631b350d0c66f40:/examples/ux/treegrid/TreeGridSorter.js diff --git a/examples/ux/treegrid/TreeGridSorter.js b/examples/ux/treegrid/TreeGridSorter.js new file mode 100644 index 00000000..6d2f62fe --- /dev/null +++ b/examples/ux/treegrid/TreeGridSorter.js @@ -0,0 +1,116 @@ +/*! + * Ext JS Library 3.1.0 + * Copyright(c) 2006-2009 Ext JS, LLC + * licensing@extjs.com + * http://www.extjs.com/license + */ +Ext.ns('Ext.ux.tree'); + +/** + * @class Ext.ux.tree.TreeGridSorter + * @extends Ext.tree.TreeSorter + */ +Ext.ux.tree.TreeGridSorter = Ext.extend(Ext.tree.TreeSorter, { + /** + * @cfg {Array} sortClasses The CSS classes applied to a header when it is sorted. (defaults to ['sort-asc', 'sort-desc']) + */ + sortClasses : ['sort-asc', 'sort-desc'], + /** + * @cfg {String} sortAscText The text displayed in the 'Sort Ascending' menu item (defaults to 'Sort Ascending') + */ + sortAscText : 'Sort Ascending', + /** + * @cfg {String} sortDescText The text displayed in the 'Sort Descending' menu item (defaults to 'Sort Descending') + */ + sortDescText : 'Sort Descending', + + constructor : function(tree, config) { + if(!Ext.isObject(config)) { + config = { + property: tree.columns[0].dataIndex || 'text', + folderSort: true + } + } + + Ext.ux.tree.TreeGridSorter.superclass.constructor.apply(this, arguments); + + this.tree = tree; + tree.on('headerclick', this.onHeaderClick, this); + tree.ddAppendOnly = true; + + me = this; + this.defaultSortFn = function(n1, n2){ + + var dsc = me.dir && me.dir.toLowerCase() == 'desc'; + var p = me.property || 'text'; + var sortType = me.sortType; + var fs = me.folderSort; + var cs = me.caseSensitive === true; + var leafAttr = me.leafAttr || 'leaf'; + + if(fs){ + if(n1.attributes[leafAttr] && !n2.attributes[leafAttr]){ + return 1; + } + if(!n1.attributes[leafAttr] && n2.attributes[leafAttr]){ + return -1; + } + } + var v1 = sortType ? sortType(n1.attributes[p]) : (cs ? n1.attributes[p] : n1.attributes[p].toUpperCase()); + var v2 = sortType ? sortType(n2.attributes[p]) : (cs ? n2.attributes[p] : n2.attributes[p].toUpperCase()); + if(v1 < v2){ + return dsc ? +1 : -1; + }else if(v1 > v2){ + return dsc ? -1 : +1; + }else{ + return 0; + } + }; + + tree.on('afterrender', this.onAfterTreeRender, this, {single: true}); + tree.on('headermenuclick', this.onHeaderMenuClick, this); + }, + + onAfterTreeRender : function() { + var hmenu = this.tree.hmenu; + hmenu.insert(0, + {itemId:'asc', text: this.sortAscText, cls: 'xg-hmenu-sort-asc'}, + {itemId:'desc', text: this.sortDescText, cls: 'xg-hmenu-sort-desc'} + ); + this.updateSortIcon(0, 'asc'); + }, + + onHeaderMenuClick : function(c, id, index) { + if(id === 'asc' || id === 'desc') { + this.onHeaderClick(c, null, index); + return false; + } + }, + + onHeaderClick : function(c, el, i) { + if(c && !this.tree.headersDisabled){ + var me = this; + + me.property = c.dataIndex; + me.dir = c.dir = (c.dir === 'desc' ? 'asc' : 'desc'); + me.sortType = c.sortType; + me.caseSensitive === Ext.isBoolean(c.caseSensitive) ? c.caseSensitive : this.caseSensitive; + me.sortFn = c.sortFn || this.defaultSortFn; + + this.tree.root.cascade(function(n) { + if(!n.isLeaf()) { + me.updateSort(me.tree, n); + } + }); + + this.updateSortIcon(i, c.dir); + } + }, + + // private + updateSortIcon : function(col, dir){ + var sc = this.sortClasses; + var hds = this.tree.innerHd.select('td').removeClass(sc); + hds.item(col).addClass(sc[dir == 'desc' ? 1 : 0]); + } +}); \ No newline at end of file