sortabletable.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. /*----------------------------------------------------------------------------\
  2. | Sortable Table 1.03 |
  3. |-----------------------------------------------------------------------------|
  4. | Created by Erik Arvidsson |
  5. | (http://webfx.eae.net/contact.html#erik) |
  6. | For WebFX (http://webfx.eae.net/) |
  7. |-----------------------------------------------------------------------------|
  8. | A DOM 1 based script that allows an ordinary HTML table to be sortable. |
  9. |-----------------------------------------------------------------------------|
  10. | Copyright (c) 1998 - 2002 Erik Arvidsson |
  11. |-----------------------------------------------------------------------------|
  12. | This software is provided "as is", without warranty of any kind, express or |
  13. | implied, including but not limited to the warranties of merchantability, |
  14. | fitness for a particular purpose and noninfringement. In no event shall the |
  15. | authors or copyright holders be liable for any claim, damages or other |
  16. | liability, whether in an action of contract, tort or otherwise, arising |
  17. | from, out of or in connection with the software or the use or other |
  18. | dealings in the software. |
  19. | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
  20. | This software is available under the three different licenses mentioned |
  21. | below. To use this software you must chose, and qualify, for one of those. |
  22. | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
  23. | The WebFX Non-Commercial License http://webfx.eae.net/license.html |
  24. | Permits anyone the right to use the software in a non-commercial context |
  25. | free of charge. |
  26. | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
  27. | The WebFX Commercial license http://webfx.eae.net/commercial.html |
  28. | Permits the license holder the right to use the software in a commercial |
  29. | context. Such license must be specifically obtained, however it's valid for |
  30. | any number of implementations of the licensed software. |
  31. | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
  32. | GPL - The GNU General Public License http://www.gnu.org/licenses/gpl.txt |
  33. | Permits anyone the right to use and modify the software without limitations |
  34. | as long as proper credits are given and the original and modified source |
  35. | code are included. Requires that the final product, software derivate from |
  36. | the original source or any software utilizing a GPL component, such as |
  37. | this, is also licensed under the GPL license. |
  38. |-----------------------------------------------------------------------------|
  39. | 2003-01-10 | First version |
  40. | 2003-01-19 | Minor changes to the date parsing |
  41. | 2003-01-28 | JScript 5.0 fixes (no support for 'in' operator) |
  42. | 2003-02-01 | Sloppy typo like error fixed in getInnerText |
  43. |-----------------------------------------------------------------------------|
  44. | Created 2003-01-10 | All changes are in the log above. | Updated 2003-02-01 |
  45. \----------------------------------------------------------------------------*/
  46. function SortableTable(oTable, oSortTypes) {
  47. // alert("oTable="+oTable.id);
  48. for (i = 0; i < oTable.rows.length; i++) {
  49. for (j = 0; j < oTable.rows(i).cells.length; j++) {
  50. // document.all.oTable.rows(i).cells(j).innerText = count;
  51. // alert(document.all.oTable.rows(i).cells(j).innerText);
  52. if (i > 0)
  53. oTable.rows(i).cells(j).style.borderBottom = '0.1mm inset #C3D6EA';
  54. }
  55. }
  56. this.element = oTable;
  57. // var e= this.element;
  58. // alert("this.element="+this.element);
  59. this.tHead = oTable.tHead;
  60. this.tBody = oTable.tBodies[0];
  61. this.document = oTable.ownerDocument || oTable.document;
  62. this.sortColumn = null;
  63. this.descending = null;
  64. var oThis = this;
  65. // alert("why");//alert("after chuanru="+e.id);
  66. this._headerOnclick = function(e) {
  67. oThis.headerOnclick(e);
  68. };
  69. // only IE needs this
  70. var win = this.document.defaultView || this.document.parentWindow;
  71. this._onunload = function() {
  72. oThis.destroy();
  73. };
  74. if (win && typeof win.attachEvent != "undefined") {
  75. win.attachEvent("onunload", this._onunload);
  76. }
  77. this.initHeader(oSortTypes || []);
  78. }
  79. SortableTable.gecko = navigator.product == "Gecko";
  80. SortableTable.msie = /msie/i.test(navigator.userAgent);
  81. // Mozilla is faster when doing the DOM manipulations on
  82. // an orphaned element. MSIE is not
  83. SortableTable.removeBeforeSort = SortableTable.gecko;
  84. SortableTable.prototype.onsort = function() {
  85. };
  86. // adds arrow containers and events
  87. // also binds sort type to the header cells so that reordering columns does
  88. // not break the sort types
  89. SortableTable.prototype.initHeader = function(oSortTypes) {
  90. var cells = this.tHead.rows[0].cells;
  91. var l = cells.length;
  92. var img, c;
  93. for (var i = 0; i < l; i++) {
  94. c = cells[i];
  95. img = this.document.createElement("IMG");
  96. img.src = "/GDZJ/images/button/blank.png";
  97. c.appendChild(img);
  98. if (oSortTypes[i] != null) {
  99. c._sortType = oSortTypes[i];
  100. }
  101. // alert("c.addEventListener="+c.addEventListener)
  102. if (typeof c.addEventListener != "undefined") {
  103. c.addEventListener("click", this._headerOnclick, false);
  104. // c.addEventListener("dblclick", this._headerOnclick, false);
  105. } else if (typeof c.attachEvent != "undefined")
  106. c.attachEvent("onclick", this._headerOnclick);
  107. }
  108. this.updateHeaderArrows();
  109. };
  110. // remove arrows and events
  111. SortableTable.prototype.uninitHeader = function() {
  112. var cells = this.tHead.rows[0].cells;
  113. var l = cells.length;
  114. var c;
  115. for (var i = 0; i < l; i++) {
  116. c = cells[i];
  117. c.removeChild(c.lastChild);
  118. // alert("c.removeEventListener="+c.removeEventListener)
  119. if (typeof c.removeEventListener != "undefined") {
  120. c.removeEventListener("click", this._headerOnclick, false);
  121. // c.removeEventListener("dblclick", this._headerOnclick, false);
  122. } else if (typeof c.detachEvent != "undefined")
  123. c.detachEvent("onclick", this._headerOnclick);
  124. }
  125. };
  126. SortableTable.prototype.updateHeaderArrows = function() {
  127. var cells = this.tHead.rows[0].cells;
  128. var l = cells.length;
  129. var img;
  130. for (var i = 0; i < l; i++) {
  131. img = cells[i].lastChild;
  132. if (i == this.sortColumn)
  133. img.className = "sort-arrow "
  134. + (this.descending ? "descending" : "ascending");
  135. else
  136. img.className = "sort-arrowblank";
  137. }
  138. };
  139. SortableTable.prototype.headerOnclick = function(e) {
  140. // find TD element
  141. var el = e.target || e.srcElement;
  142. // alert("alert(el.tagName);="+el.parentNode.tagName);
  143. // alert("el.id="+el.id);
  144. // alert("e.srcElement="+e.srcElement.tagName);
  145. while (el.tagName != "TD") {
  146. // alert(el.tagName);
  147. el = el.parentNode;
  148. }
  149. this.sort(el.cellIndex);
  150. };
  151. SortableTable.prototype.getSortType = function(nColumn) {
  152. var cell = this.tHead.rows[0].cells[nColumn];
  153. var val = cell._sortType;
  154. if (val != "")
  155. return val;
  156. return "String";
  157. };
  158. // only nColumn is required
  159. // if bDescending is left out the old value is taken into account
  160. // if sSortType is left out the sort type is found from the sortTypes array
  161. // Array.prototype.del=function(n) {
  162. // return this.slice(0,n).concat(this.slice(n+1,this.length));
  163. // }
  164. SortableTable.prototype.sort = function(nColumn, bDescending, sSortType) {
  165. if (sSortType == null)
  166. sSortType = this.getSortType(nColumn);
  167. // exit if None
  168. if (sSortType == "None")
  169. return;
  170. if (bDescending == null) {
  171. if (this.sortColumn != nColumn)
  172. this.descending = true;
  173. else
  174. this.descending = !this.descending;
  175. }
  176. this.sortColumn = nColumn;
  177. if (typeof this.onbeforesort == "function")
  178. this.onbeforesort();
  179. // alert("sSortType, nColumn"+sSortType+","+nColumn);
  180. if (sSortType == null) {
  181. return;
  182. }
  183. var f = this.getSortFunction(sSortType, nColumn);
  184. var a = this.getCache(sSortType, nColumn);
  185. var tBody = this.tBody;
  186. a.sort(f);
  187. if (this.descending)
  188. a.reverse();
  189. if (SortableTable.removeBeforeSort) {
  190. // remove from doc
  191. var nextSibling = tBody.nextSibling;
  192. var p = tBody.parentNode;
  193. p.removeChild(tBody);
  194. }
  195. // insert in the new order
  196. var l = a.length;
  197. for (var i = 0; i < l; i++)
  198. tBody.appendChild(a[i].element);
  199. if (SortableTable.removeBeforeSort) {
  200. // insert into doc
  201. p.insertBefore(tBody, nextSibling);
  202. }
  203. this.updateHeaderArrows();
  204. this.destroyCache(a);
  205. if (typeof this.onsort == "function")
  206. this.onsort();
  207. };
  208. SortableTable.prototype.asyncSort = function(nColumn, bDescending, sSortType) {
  209. var oThis = this;
  210. this._asyncsort = function() {
  211. oThis.sort(nColumn, bDescending, sSortType);
  212. };
  213. window.setTimeout(this._asyncsort, 1);
  214. };
  215. SortableTable.prototype.getCache = function(sType, nColumn) {
  216. var rows = this.tBody.rows;
  217. var l = rows.length;
  218. var a = new Array(l);
  219. var r;
  220. for (var i = 0; i < l; i++) {
  221. r = rows[i];
  222. a[i] = {
  223. value : this.getRowValue(r, sType, nColumn),
  224. element : r
  225. };
  226. };
  227. return a;
  228. };
  229. SortableTable.prototype.destroyCache = function(oArray) {
  230. var l = oArray.length;
  231. for (var i = 0; i < l; i++) {
  232. oArray[i].value = null;
  233. oArray[i].element = null;
  234. oArray[i] = null;
  235. }
  236. }
  237. SortableTable.prototype.getRowValue = function(oRow, sType, nColumn) {
  238. var s;
  239. // alert("oRow.cells.length="+oRow.cells.length+"sType="+sType+"nColumn="+nColumn);
  240. if (oRow.cells.length > nColumn) {
  241. var c = oRow.cells[nColumn];
  242. if (typeof c.innerText != "undefined") {
  243. // alert("c.innerText="+c.innerText);
  244. // if(c.innerText!="undefined")
  245. s = c.innerText;
  246. return this.getValueFromString(s, sType);
  247. } else {
  248. return false;
  249. // alert("getInnerText=");
  250. // s = SortableTable.getInnerText(c);
  251. return this.getValueFromString(s, sType);
  252. }
  253. }
  254. };
  255. SortableTable.getInnerText = function(oNode) {
  256. // alert("ffffffffffffff");
  257. var s = "";
  258. var cs = oNode.childNodes;
  259. var l = cs.length;
  260. for (var i = 0; i < l; i++) {
  261. switch (cs[i].nodeType) {
  262. case 1 :
  263. // ELEMENT_NODE
  264. s += SortableTable.getInnerText(cs[i]);
  265. break;
  266. case 3 : // TEXT_NODE
  267. s += cs[i].nodeValue;
  268. break;
  269. }
  270. }
  271. return s;
  272. }
  273. SortableTable.prototype.getValueFromString = function(sText, sType) {
  274. switch (sType) {
  275. case "Number" :
  276. return Number(sText);
  277. case "CaseInsensitiveString" :
  278. return sText.toUpperCase();
  279. case "Date" :
  280. var parts = sText.split("-");
  281. var d = new Date(0);
  282. d.setFullYear(parts[0]);
  283. d.setDate(parts[2]);
  284. d.setMonth(parts[1] - 1);
  285. return d.valueOf();
  286. }
  287. return sText;
  288. };
  289. SortableTable.prototype.getSortFunction = function(sType, nColumn) {
  290. return function compare(n1, n2) {
  291. if (n1.value < n2.value)
  292. return -1;
  293. if (n2.value < n1.value)
  294. return 1;
  295. return 0;
  296. };
  297. };
  298. SortableTable.prototype.destroy = function() {
  299. this.uninitHeader();
  300. var win = this.document.parentWindow;
  301. if (win && typeof win.detachEvent != "undefined") { // only IE needs this
  302. win.detachEvent("onunload", this._onunload);
  303. }
  304. this._onunload = null;
  305. this.element = null;
  306. this.tHead = null;
  307. this.tBody = null;
  308. this.document = null;
  309. this._headerOnclick = null;
  310. this.sortTypes = null;
  311. this._asyncsort = null;
  312. this.onsort = null;
  313. };