Move git RSS link to github
[phpmyadmin-website.git] / js / master_sorting_table.js
blob2553d44a3ca60342d766f5b34af89ff37505ba3a
1 //
2 // new SortingTable( 'my_table', {
3 // zebra: true, // Stripe the table, also on initialize
4 // details: false, // Has details every other row
5 // paginator: false, // Pass a paginator object
6 // dont_sort_class: 'nosort', // Class name on th's that don't sort
7 // forward_sort_class: 'forward_sort', // Class applied to forward sort th's
8 // reverse_sort_class: 'reverse_sort' // Class applied to reverse sort th's
9 // });
11 // The above were the defaults. The regexes in load_conversions test a cell
12 // begin sorted for a match, then use that conversion for all elements on that
13 // column.
15 // Requires mootools Class, Array, Function, Element, Element.Selectors,
16 // Element.Event, and you should probably get Window.DomReady if you're smart.
19 var SortingTable = new Class({
21 Implements: Options,
23 options: {
24 zebra: true,
25 details: false,
26 paginator: false,
27 dont_sort_class: 'nosort',
28 forward_sort_class: 'forward_sort',
29 reverse_sort_class: 'reverse_sort'
32 initialize: function( table, options ) {
33 this.table = $(table);
34 this.setOptions(options);
35 this.sort_column = 0;
37 this.tbody = this.table.getElement('tbody');
38 if (this.options.zebra) {
39 SortingTable.stripe_table(this.tbody.getChildren());
42 var skip = 0;
44 this.headers = this.table.getElement('thead').getElements('th');
45 this.headers.each(function( header, index ) {
46 if (header.hasClass( this.options.dont_sort_class )) { return }
47 header.store( 'column', index + skip )
48 if (header.colSpan > 1) {
49 skip = skip + header.colSpan - 1;
51 header.addEvent( 'mousedown', function(evt){
52 this.sort_by_header( evt.target );
53 if ( this.options.paginator) this.options.paginator.to_page( 1 );
54 }.bind( this ) );
55 }, this);
57 this.load_conversions();
60 sort_by_header: function( header ){
61 var rows = [];
63 var before = this.tbody.getPrevious();
64 this.tbody.dispose();
66 var trs = this.tbody.getChildren();
67 while ( row = trs.shift() ) {
68 row = { row: row.dispose() };
69 if ( this.options.details ) {
70 row.detail = trs.shift().dispose();
72 rows.unshift( row );
75 if ( this.sort_column >= 0 &&
76 this.sort_column == header.retrieve('column') ) {
77 // They were pulled off in reverse
78 if ( header.hasClass( this.options.reverse_sort_class ) ) {
79 header.removeClass( this.options.reverse_sort_class );
80 header.addClass( this.options.forward_sort_class );
81 } else {
82 header.removeClass( this.options.forward_sort_class );
83 header.addClass( this.options.reverse_sort_class );
85 } else {
86 this.headers.each(function(h){
87 h.removeClass( this.options.forward_sort_class );
88 h.removeClass( this.options.reverse_sort_class );
89 }, this);
90 this.sort_column = header.retrieve('column');
91 if (header.retrieve('conversion_function')) {
92 this.conversion_matcher = header.retrieve('conversion_matcher');
93 this.conversion_function = header.retrieve('conversion_function');
94 } else {
95 this.conversion_function = false;
96 rows.some(function(row){
97 var to_match = $(row.row.getElementsByTagName('td')[this.sort_column]).get('text');
98 if (to_match == '') return false;
99 this.conversions.some(function(conversion){
100 if (conversion.matcher.test( to_match )){
101 this.conversion_matcher = conversion.matcher;
102 this.conversion_function = conversion.conversion_function;
103 return true;
105 return false;
106 }, this);
107 return !!(this.conversion_function);
108 }, this);
109 header.store('conversion_function', this.conversion_function );
110 header.store('conversion_matcher', this.conversion_matcher );
112 header.addClass( this.options.forward_sort_class );
113 rows.each(function(row){
114 var compare_value = this.conversion_function( row );
115 row.toString = function(){
116 return compare_value;
118 }, this);
119 rows.sort();
122 var index = 0;
123 while ( row = rows.shift() ) {
124 this.tbody.appendChild(row.row);
125 if (row.detail) this.tbody.appendChild(row.detail);
126 if ( this.options.zebra ) {
127 row.row.className = row.row.className.replace( this.removeAltClassRe, '$1').clean();
128 if (row.detail)
129 row.detail.className = row.detail.className.replace( this.removeAltClassRe, '$1').clean();
130 if (index % 2) {
131 row.row.addClass( 'alt' );
132 if (row.detail) row.detail.addClass( 'alt' );
135 index++;
137 this.tbody.inject(before, 'after');
140 load_conversions: function() {
141 this.conversions = $A([
142 // 1.75 MB, 301 GB, 34 KB, 8 TB
143 { matcher: /([0-9.]{1,8}).*([KMGT]{1})B/,
144 conversion_function: function( row ) {
145 var cell = $(row.row.getElementsByTagName('td')[this.sort_column]).get('text');
146 cell = this.conversion_matcher.exec( cell );
147 if (!cell) { return '0' }
148 if (cell[2] == 'M') {
149 sort_val = '1';
150 } else if (cell[2] == 'G') {
151 sort_val = '2';
152 } else if (cell[2] == 'T') {
153 sort_val = '3';
154 } else {
155 sort_val = '0';
157 var i = cell[1].indexOf('.')
158 if (i == -1) {
159 post = '00'
160 } else {
161 var dec = cell[1].split('.');
162 cell[1] = dec[0];
163 post = dec[1].concat('00'.substr(0,2-dec[1].length));
165 return sort_val.concat('00000000'.substr(0,2-cell[1].length).concat(cell[1])).concat(post);
168 // 1 day ago, 4 days ago, 38 years ago, 1 month ago
169 { matcher: /(\d{1,2}) (.{3,6}) ago/,
170 conversion_function: function( row ) {
171 var cell = $(row.row.getElementsByTagName('td')[this.sort_column]).get('text');
172 cell = this.conversion_matcher.exec( cell );
173 if (!cell) { return '0' }
174 var sort_val;
175 if (cell[2].indexOf('month') != -1) {
176 sort_val = '1';
177 } else if (cell[2].indexOf('year') != -1) {
178 sort_val = '2';
179 } else {
180 sort_val = '0';
182 return sort_val.concat('00'.substr(0,2-cell[1].length).concat(cell[1]));
185 // Currency
186 { matcher: /((\d{1}\.\d{2}|\d{2}\.\d{2}|\d{3}\.\d{2}|\d{4}\.\d{2}|\d{5}\.\d{2}|\d{6}\.\d{2}))/,
187 conversion_function: function( row ) {
188 var cell = $(row.row.getElementsByTagName('td')[this.sort_column]).get('text');
189 cell = cell.replace(/[^\d]/g, "");
190 return '00000000000000000000000000000000'.substr(0,32-cell.length).concat(cell);
193 // YYYY-MM-DD, YYYY-m-d
194 { matcher: /(\d{4})-(\d{1,2})-(\d{1,2})/,
195 conversion_function: function( row ) {
196 var cell = $(row.row.getElementsByTagName('td')[this.sort_column]).get('text');
197 cell = this.conversion_matcher.exec( cell );
198 if (cell) {
199 return cell[1]+
200 '00'.substr(0,2-cell[2].length).concat(cell[2])+
201 '00'.substr(0,2-cell[3].length).concat(cell[3]);
202 } else {
203 return '00000000000000000000000000000000';
207 // Numbers
208 { matcher: /^\d+$/,
209 conversion_function: function( row ) {
210 var cell = $(row.row.getElementsByTagName('td')[this.sort_column]).get('text');
211 return '00000000000000000000000000000000'.substr(0,32-cell.length).concat(cell);
214 // Percent
215 { matcher: /^[0-9.,]+%$/,
216 conversion_function: function( row ) {
217 var cell = $(row.row.getElementsByTagName('td')[this.sort_column]).get('text');
218 return '00000000000000000000000000000000'.substr(0,32-cell.length).concat(cell);
221 // Fallback
222 { matcher: /.*/,
223 conversion_function: function( row ) {
224 return $(row.row.getElementsByTagName('td')[this.sort_column]).get('text');
232 SortingTable.removeAltClassRe = new RegExp('(^|\\s)alt(?:\\s|$)');
233 SortingTable.implement({ removeAltClassRe: SortingTable.removeAltClassRe });
235 SortingTable.stripe_table = function ( tr_elements ) {
236 var counter = 0;
237 tr_elements.each( function( tr ) {
238 if ( !tr.hasClass('collapsed') ) counter++;
239 tr.className = tr.className.replace( this.removeAltClassRe, '$1').clean();
240 if (counter % 2) tr.addClass( 'alt' );
245 // AUTOLOAD CODE BLOCK
246 SortingTable.scanPage = function() {
247 if ($("sorttable")) {
248 var tt = new SortingTable("sorttable");
251 window.addEvent("domready", SortingTable.scanPage);