merged cont.
[opensuse:yast-rest-service.git] / webservice / public / javascripts / jquery.tinysort.js
1 /*\r
2 * jQuery TinySort - A plugin to sort child nodes by (sub) contents or attributes.\r
3 *\r
4 * Version: 1.0.4\r
5 *\r
6 * Copyright (c) 2008 Ron Valstar\r
7 *\r
8 * Dual licensed under the MIT and GPL licenses:\r
9 *   http://www.opensource.org/licenses/mit-license.php\r
10 *   http://www.gnu.org/licenses/gpl.html\r
11 *\r
12 * description\r
13 *   - A plugin to sort child nodes by (sub) contents or attributes.\r
14 *\r
15 * Usage:\r
16 *   $("ul#people>li").tsort();\r
17 *   $("ul#people>li").tsort("span.surname");\r
18 *   $("ul#people>li").tsort("span.surname",{order:"desc"});\r
19 *   $("ul#people>li").tsort({place:"end"});\r
20 *\r
21 * Change default like so:\r
22 *   $.tinysort.defaults.order = "desc";\r
23 *\r
24 * in this update:\r
25 *       - changed setArray to pushStack\r
26 *\r
27 * in last update:\r
28 *       - tested with jQuery 1.4.1\r
29 *       - correct isNum return\r
30 *\r
31 * Todos\r
32 *   - fix mixed literal/numeral values\r
33 *   - determine if I have to use pushStack or pushStack\r
34 *\r
35 */\r
36 ;(function($) {\r
37         // default settings\r
38         $.tinysort = {\r
39                  id: "TinySort"\r
40                 ,version: "1.0.4"\r
41                 ,defaults: {\r
42                          order: "asc"   // order: asc, desc or rand\r
43                         ,attr: ""               // order by attribute value\r
44                         ,place: "start" // place ordered elements at position: start, end, org (original position), first\r
45                         ,returns: false // return all elements or only the sorted ones (true/false)\r
46                 }\r
47         };\r
48         $.fn.extend({\r
49                 tinysort: function(_find,_settings) {\r
50                         if (_find&&typeof(_find)!="string") {\r
51                                 _settings = _find;\r
52                                 _find = null;\r
53                         }\r
54 \r
55                         var oSettings = $.extend({}, $.tinysort.defaults, _settings);\r
56 \r
57                         var oElements = {}; // contains sortable- and non-sortable list per parent\r
58                         this.each(function(i) {\r
59                                 // element or sub selection\r
60                                 var mElm = (!_find||_find=="")?$(this):$(this).find(_find);\r
61                                 // text or attribute value\r
62                                 var sSort = oSettings.order=="rand"?""+Math.random():(oSettings.attr==""?mElm.text():mElm.attr(oSettings.attr));\r
63                                 // to sort or not to sort\r
64                                 var mParent = $(this).parent();\r
65                                 if (!oElements[mParent]) oElements[mParent] = {s:[],n:[]};      // s: sort, n: not sort\r
66                                 if (mElm.length>0)      oElements[mParent].s.push({s:sSort,e:$(this),n:i}); // s:string, e:element, n:number\r
67                                 else                            oElements[mParent].n.push({e:$(this),n:i});\r
68                         });\r
69                         //\r
70                         // sort\r
71                         for (var sParent in oElements) {\r
72                                 var oParent = oElements[sParent];\r
73                                 oParent.s.sort(\r
74                                         function zeSort(a,b) {\r
75                                                 var x = a.s.toLowerCase?a.s.toLowerCase():a.s;\r
76                                                 var y = b.s.toLowerCase?b.s.toLowerCase():b.s;\r
77                                                 if (isNum(a.s)&&isNum(b.s)) {\r
78                                                         x = parseFloat(a.s);\r
79                                                         y = parseFloat(b.s);\r
80                                                 }\r
81                                                 return (oSettings.order=="asc"?1:-1)*(x<y?-1:(x>y?1:0));\r
82                                         }\r
83                                 );\r
84                         }\r
85                         //\r
86                         // order elements and fill new order\r
87                         var aNewOrder = [];\r
88                         for (var sParent in oElements) {\r
89                                 var oParent = oElements[sParent];\r
90                                 var aOrg = []; // list for original position\r
91                                 var iLow = $(this).length;\r
92                                 switch (oSettings.place) {\r
93                                         case "first": $.each(oParent.s,function(i,obj) { iLow = Math.min(iLow,obj.n) }); break;\r
94                                         case "org": $.each(oParent.s,function(i,obj) { aOrg.push(obj.n) }); break;\r
95                                         case "end": iLow = oParent.n.length; break;\r
96                                         default: iLow = 0;\r
97                                 }\r
98                                 var aCnt = [0,0]; // count how much we've sorted for retreival from either the sort list or the non-sort list (oParent.s/oParent.n)\r
99                                 for (var i=0;i<$(this).length;i++) {\r
100                                         var bSList = i>=iLow&&i<iLow+oParent.s.length;\r
101                                         if (contains(aOrg,i)) bSList = true;\r
102                                         var mEl = (bSList?oParent.s:oParent.n)[aCnt[bSList?0:1]].e;\r
103                                         mEl.parent().append(mEl);\r
104                                         if (bSList||!oSettings.returns) aNewOrder.push(mEl.get(0));\r
105                                         aCnt[bSList?0:1]++;\r
106                                 }\r
107                         }\r
108                         //\r
109                         return this.pushStack(aNewOrder); // pushStack or pushStack?\r
110                 }\r
111         });\r
112         // is numeric\r
113         function isNum(n) {\r
114                 var x = /^\s*?[\+-]?(\d*\.?\d*?)\s*?$/.exec(n);\r
115                 return x&&x.length>0?x[1]:false;\r
116         };\r
117         // array contains\r
118         function contains(a,n) {\r
119                 var bInside = false;\r
120                 $.each(a,function(i,m) {\r
121                         if (!bInside) bInside = m==n;\r
122                 });\r
123                 return bInside;\r
124         };\r
125         // set functions\r
126         $.fn.TinySort = $.fn.Tinysort = $.fn.tsort = $.fn.tinysort;\r
127 })(jQuery);