2466f9002e76b6a8b1d8cfffcabc17f12081c0ab
3 On page load, the SortableManager:
5 - Finds the table by its id (sortable_table).
6 - Parses its thead for columns with a "mochi:format" attribute.
7 - Parses the data out of the tbody based upon information given in the
8 "mochi:format" attribute, and clones the tr elements for later re-use.
9 - Clones the column header th elements for use as a template when drawing
11 - Stores away a reference to the tbody, as it will be replaced on each sort.
12 - Performs the first sort.
17 - Sorts the data based on the given key and direction
18 - Creates a new tbody from the rows in the new ordering
19 - Replaces the column header th elements with clickable versions, adding an
20 indicator (↑ or ↓) to the most recently sorted column.
24 SortableManager
= function () {
33 mouseOverFunc
= function () {
34 addElementClass(this, "over");
37 mouseOutFunc
= function () {
38 removeElementClass(this, "over");
41 ignoreEvent
= function (ev
) {
42 if (ev
&& ev
.preventDefault
) {
45 } else if (typeof(event
) != 'undefined') {
46 event
.cancelBubble
= false;
47 event
.returnValue
= false;
52 update(SortableManager
.prototype, {
54 "initWithTable": function (table
) {
57 Initialize the SortableManager with a table object
60 // Ensure that it's a DOM element
61 table
= getElement(table
);
63 this.thead
= table
.getElementsByTagName('thead')[0];
64 // get the mochi:format key and contents for each column header
65 var cols
= this.thead
.getElementsByTagName('th');
66 for (var i
= 0; i
< cols
.length
; i
++) {
70 attr
= node
.getAttribute("mochi:format");
74 var o
= node
.childNodes
;
78 "proto": node
.cloneNode(true)
81 // scrape the tbody for data
82 this.tbody
= table
.getElementsByTagName('tbody')[0];
84 var rows
= this.tbody
.getElementsByTagName('tr');
85 for (var i
= 0; i
< rows
.length
; i
++) {
88 var cols
= row
.getElementsByTagName('td');
90 for (var j
= 0; j
< cols
.length
; j
++) {
91 // scrape the text and build the appropriate object out of it
93 var obj
= scrapeText(cell
);
94 switch (this.columns
[j
].format
) {
101 obj
= obj
.toLowerCase();
103 // cases for numbers, etc. could be here
109 // stow away a reference to the TR and save it
110 rowData
.row
= row
.cloneNode(true);
111 this.rows
.push(rowData
);
115 // do initial sort on first column
116 this.drawSortedRows(this.sortkey
, true, false);
120 "onSortClick": function (name
) {
123 Return a sort function for click events
126 return method(this, function () {
127 log('onSortClick', name
);
128 var order
= this.sortState
[name
];
131 } else if (name
== this.sortkey
) {
134 this.drawSortedRows(name
, order
, true);
138 "drawSortedRows": function (key
, forward
, clicked
) {
141 Draw the new sorted table body, and modify the column headers
145 log('drawSortedRows', key
, forward
);
147 // sort based on the state given (forward or reverse)
148 var cmp
= (forward
? keyComparator
: reverseKeyComparator
);
149 this.rows
.sort(cmp(key
));
150 // save it so we can flip next time
151 this.sortState
[key
] = forward
;
152 // get every "row" element from this.rows and make a new tbody
153 var newBody
= TBODY(null, map(itemgetter("row"), this.rows
));
154 // swap in the new tbody
155 this.tbody
= swapDOM(this.tbody
, newBody
);
156 for (var i
= 0; i
< this.columns
.length
; i
++) {
157 var col
= this.columns
[i
];
158 var node
= col
.proto
.cloneNode(true);
159 // remove the existing events to minimize IE leaks
160 col
.element
.onclick
= null;
161 col
.element
.onmousedown
= null;
162 col
.element
.onmouseover
= null;
163 col
.element
.onmouseout
= null;
164 // set new events for the new node
165 node
.onclick
= this.onSortClick(i
);
166 node
.onmousedown
= ignoreEvent
;
167 node
.onmouseover
= mouseOverFunc
;
168 node
.onmouseout
= mouseOutFunc
;
169 // if this is the sorted column
171 // \u2193 is down arrow, \u2191 is up arrow
172 // forward sorts mean the rows get bigger going down
173 var arrow
= (forward
? "\u2193" : "\u2191");
174 // add the character to the column header
175 node
.appendChild(SPAN(null, arrow
));
181 // swap in the new th
182 col
.element
= swapDOM(col
.element
, node
);
187 sortableManager
= new SortableManager();
189 addLoadEvent(function () {
190 sortableManager
.initWithTable('sortable_table');
193 // rewrite the view-source links
194 addLoadEvent(function () {
195 var elems
= getElementsByTagAndClassName("A", "view-source");
196 var page
= "sortable_tables/";
197 for (var i
= 0; i
< elems
.length
; i
++) {
199 var href
= elem
.href
.split(/\//).pop();
200 elem
.target
= "_blank";
201 elem
.href
= "../view-source/view-source.html#" + page
+ href
;