Non-initialized variable fix.
[openlib.git] / www / js / jquery.sortElements.js
1 /**\r
2  * jQuery.fn.sortElements\r
3  * --------------\r
4  * @author James Padolsey (http://james.padolsey.com)\r
5  * @version 0.11\r
6  * @updated 18-MAR-2010\r
7  * --------------\r
8  * @param Function comparator:\r
9  *   Exactly the same behaviour as [1,2,3].sort(comparator)\r
10  *   \r
11  * @param Function getSortable\r
12  *   A function that should return the element that is\r
13  *   to be sorted. The comparator will run on the\r
14  *   current collection, but you may want the actual\r
15  *   resulting sort to occur on a parent or another\r
16  *   associated element.\r
17  *   \r
18  *   E.g. $('td').sortElements(comparator, function(){\r
19  *      return this.parentNode; \r
20  *   })\r
21  *   \r
22  *   The <td>'s parent (<tr>) will be sorted instead\r
23  *   of the <td> itself.\r
24  */\r
25 jQuery.fn.sortElements = (function(){\r
26     \r
27     var sort = [].sort;\r
28     \r
29     return function(comparator, getSortable) {\r
30         \r
31         getSortable = getSortable || function(){return this;};\r
32         \r
33         var placements = this.map(function(){\r
34             \r
35             var sortElement = getSortable.call(this),\r
36                 parentNode = sortElement.parentNode,\r
37                 \r
38                 // Since the element itself will change position, we have\r
39                 // to have some way of storing it's original position in\r
40                 // the DOM. The easiest way is to have a 'flag' node:\r
41                 nextSibling = parentNode.insertBefore(\r
42                     document.createTextNode(''),\r
43                     sortElement.nextSibling\r
44                 );\r
45             \r
46             return function() {\r
47                 \r
48                 if (parentNode === this) {\r
49                     throw new Error(\r
50                         "You can't sort elements if any one is a descendant of another."\r
51                     );\r
52                 }\r
53                 \r
54                 // Insert before flag:\r
55                 parentNode.insertBefore(this, nextSibling);\r
56                 // Remove flag:\r
57                 parentNode.removeChild(nextSibling);\r
58                 \r
59             };\r
60             \r
61         });\r
62        \r
63         return sort.call(this, comparator).each(function(i){\r
64             placements[i].call(getSortable.call(this));\r
65         });\r
66         \r
67     };\r
68     \r
69 })();