5a920362 |
1 | |
2 | /* - table_sorter.js - */ |
3 | |
4 | /********* Table sorter script *************/ |
5 | /* |
6 | * For all table elements with 'listing' class, |
7 | * when user clicks on a th without 'nosort' class, |
8 | * it sort table values using the td class with 'sortabledata-mydata' name, |
9 | * or the td text content |
10 | * |
11 | */ |
12 | (function($) { |
13 | |
14 | function sortabledataclass(cell){ |
15 | var re = new RegExp("sortabledata-([^ ]*)","g"); |
16 | var matches = re.exec(cell.attr('class')); |
17 | if(matches) return matches[1] |
18 | else return null |
19 | } |
20 | |
21 | function sortable(cell) { |
22 | // convert a cell a to something sortable |
23 | |
24 | // use sortabledata-xxx cell class if it is defined |
25 | var text = sortabledataclass(cell); |
26 | if(text == null) text = cell.text(); |
27 | |
28 | // A number, but not a date? |
29 | if (text.charAt(4) != '-' && text.charAt(7) != '-' && !isNaN(parseFloat(text))) |
30 | return parseFloat(text); |
31 | return text.toLowerCase(); |
32 | } |
33 | |
34 | function sort() { |
35 | var th = $(this).closest('th'); |
36 | var colnum = $('th', $(this).closest('thead')).index(th); |
37 | var table = $(this).parents('table:first'); |
38 | var tbody = table.find('tbody:first'); |
39 | var reverse = table.attr('sorted') == colnum; |
40 | |
41 | $(this).parent().find('th:not(.nosort) .sortdirection') |
42 | .html(' '); |
43 | $(this).children('.sortdirection').html( |
44 | reverse ? '▲' : '▼'); |
45 | |
46 | var index = $(this).parent().children('th').index(this); |
47 | var data = []; |
48 | var usenumbers = true; |
49 | tbody.find('tr').each(function() { |
50 | var cells = $(this).children('td'); |
51 | var sortableitem = sortable(cells.slice(index,index+1)); |
52 | if (isNaN(sortableitem)) usenumbers = false; |
53 | data.push([ |
54 | sortableitem, |
55 | // crude way to sort by surname and name after first choice |
56 | sortable(cells.slice(1,2)), sortable(cells.slice(0,1)), |
57 | this]); |
58 | }); |
59 | |
60 | if (data.length) { |
61 | if (usenumbers) |
62 | data.sort(function(a,b) {return a[0]-b[0];}); |
63 | else |
64 | data.sort(); |
65 | if (reverse) data.reverse(); |
66 | table.attr('sorted', reverse ? '' : colnum); |
67 | |
68 | // appending the tr nodes in sorted order will remove them from their old ordering |
69 | tbody.append($.map(data, function(a) { return a[3]; })); |
70 | // jquery :odd and :even are 0 based |
71 | tbody.each(setoddeven); |
72 | } |
73 | } |
74 | |
75 | function setoddeven() { |
76 | var tbody = $(this); |
77 | // jquery :odd and :even are 0 based |
78 | tbody.find('tr').removeClass('odd').removeClass('even') |
79 | .filter(':odd').addClass('even').end() |
80 | .filter(':even').addClass('odd'); |
81 | } |
82 | |
83 | $(function() { |
84 | // set up blank spaceholder gif |
85 | var blankarrow = $('<span> </span>').addClass('sortdirection'); |
86 | // all listing tables not explicitly nosort, all sortable th cells |
87 | // give them a pointer cursor and blank cell and click event handler |
88 | // the first one of the cells gets a up arrow instead. |
89 | $('table.listing:not(.nosort) thead th:not(.nosort)') |
90 | .append(blankarrow.clone()) |
91 | .css('cursor', 'pointer') |
92 | .click(sort); |
93 | $('table.listing:not(.nosort) tbody').each(setoddeven); |
94 | }); |
95 | |
96 | })(jQuery); |
97 | |