tablesaw-rails 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +69 -0
- data/Rakefile +2 -0
- data/app/assets/javascripts/tablesaw/tables-init.js +32 -0
- data/app/assets/javascripts/tablesaw/tables.btnmarkup.js +90 -0
- data/app/assets/javascripts/tablesaw/tables.columntoggle.js +196 -0
- data/app/assets/javascripts/tablesaw/tables.js +135 -0
- data/app/assets/javascripts/tablesaw/tables.minimap.js +81 -0
- data/app/assets/javascripts/tablesaw/tables.modeswitch.js +87 -0
- data/app/assets/javascripts/tablesaw/tables.sortable.js +274 -0
- data/app/assets/javascripts/tablesaw/tables.stack.js +93 -0
- data/app/assets/javascripts/tablesaw/tables.swipetoggle.js +248 -0
- data/app/assets/stylesheets/tablesaw/tables.columntoggle.css +156 -0
- data/app/assets/stylesheets/tablesaw/tables.css +27 -0
- data/app/assets/stylesheets/tablesaw/tables.minimap.css +31 -0
- data/app/assets/stylesheets/tablesaw/tables.modeswitch.css +15 -0
- data/app/assets/stylesheets/tablesaw/tables.skin.css +79 -0
- data/app/assets/stylesheets/tablesaw/tables.sortable.css +63 -0
- data/app/assets/stylesheets/tablesaw/tables.stack-default-breakpoint.css +32 -0
- data/app/assets/stylesheets/tablesaw/tables.stack.css +53 -0
- data/app/assets/stylesheets/tablesaw/tables.swipetoggle.css +3 -0
- data/app/assets/stylesheets/tablesaw/tables.toolbar.css +331 -0
- data/lib/tablesaw-rails.rb +4 -0
- data/tablesaw-rails.gemspec +22 -0
- metadata +98 -0
@@ -0,0 +1,135 @@
|
|
1
|
+
/*
|
2
|
+
* tablesaw: A set of plugins for responsive tables
|
3
|
+
* Stack and Column Toggle tables
|
4
|
+
* Copyright (c) 2013 Filament Group, Inc.
|
5
|
+
* MIT License
|
6
|
+
*/
|
7
|
+
|
8
|
+
;(function( $ ) {
|
9
|
+
var pluginName = "table",
|
10
|
+
classes = {
|
11
|
+
toolbar: "tablesaw-bar"
|
12
|
+
},
|
13
|
+
events = {
|
14
|
+
create: "tablesawcreate",
|
15
|
+
destroy: "tablesawdestroy",
|
16
|
+
refresh: "tablesawrefresh"
|
17
|
+
},
|
18
|
+
defaultMode = "stack",
|
19
|
+
initSelector = "table[data-mode],table[data-sortable]";
|
20
|
+
|
21
|
+
var Table = function( element ) {
|
22
|
+
if( !element ) {
|
23
|
+
throw new Error( "Tablesaw requires an element." );
|
24
|
+
}
|
25
|
+
|
26
|
+
this.table = element;
|
27
|
+
this.$table = $( element );
|
28
|
+
|
29
|
+
this.mode = this.$table.attr( "data-mode" ) || defaultMode;
|
30
|
+
|
31
|
+
this.init();
|
32
|
+
};
|
33
|
+
|
34
|
+
Table.prototype.init = function() {
|
35
|
+
// assign an id if there is none
|
36
|
+
if ( !this.$table.attr( "id" ) ) {
|
37
|
+
this.$table.attr( "id", pluginName + "-" + Math.round( Math.random() * 10000 ) );
|
38
|
+
}
|
39
|
+
|
40
|
+
this.createToolbar();
|
41
|
+
|
42
|
+
var colstart = this._initCells();
|
43
|
+
|
44
|
+
this.$table.trigger( events.create, [ this, colstart ] );
|
45
|
+
};
|
46
|
+
|
47
|
+
Table.prototype._initCells = function() {
|
48
|
+
var colstart,
|
49
|
+
thrs = this.table.querySelectorAll( "thead tr" ),
|
50
|
+
self = this;
|
51
|
+
|
52
|
+
$( thrs ).each( function(){
|
53
|
+
var coltally = 0;
|
54
|
+
|
55
|
+
$( this ).children().each( function(){
|
56
|
+
var span = parseInt( this.getAttribute( "colspan" ), 10 ),
|
57
|
+
sel = ":nth-child(" + ( coltally + 1 ) + ")";
|
58
|
+
|
59
|
+
colstart = coltally + 1;
|
60
|
+
|
61
|
+
if( span ){
|
62
|
+
for( var k = 0; k < span - 1; k++ ){
|
63
|
+
coltally++;
|
64
|
+
sel += ", :nth-child(" + ( coltally + 1 ) + ")";
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
// Store "cells" data on header as a reference to all cells in the same column as this TH
|
69
|
+
this.cells = self.$table.find("tr").not( $( thrs ).eq( 0 ) ).not( this ).children( sel );
|
70
|
+
coltally++;
|
71
|
+
});
|
72
|
+
});
|
73
|
+
|
74
|
+
return colstart;
|
75
|
+
};
|
76
|
+
|
77
|
+
Table.prototype.refresh = function() {
|
78
|
+
this._initCells();
|
79
|
+
|
80
|
+
this.$table.trigger( events.refresh );
|
81
|
+
};
|
82
|
+
|
83
|
+
Table.prototype.createToolbar = function() {
|
84
|
+
// Insert the toolbar
|
85
|
+
// TODO move this into a separate component
|
86
|
+
var $toolbar = this.$table.prev( '.' + classes.toolbar );
|
87
|
+
if( !$toolbar.length ) {
|
88
|
+
$toolbar = $( '<div>' )
|
89
|
+
.addClass( classes.toolbar )
|
90
|
+
.insertBefore( this.$table );
|
91
|
+
}
|
92
|
+
this.$toolbar = $toolbar;
|
93
|
+
|
94
|
+
if( this.mode ) {
|
95
|
+
this.$toolbar.addClass( 'mode-' + this.mode );
|
96
|
+
}
|
97
|
+
};
|
98
|
+
|
99
|
+
Table.prototype.destroy = function() {
|
100
|
+
// Don’t remove the toolbar. Some of the table features are not yet destroy-friendly.
|
101
|
+
this.$table.prev( '.' + classes.toolbar ).each(function() {
|
102
|
+
this.className = this.className.replace( /\bmode\-\w*\b/gi, '' );
|
103
|
+
});
|
104
|
+
|
105
|
+
var tableId = this.$table.attr( 'id' );
|
106
|
+
$( document ).unbind( "." + tableId );
|
107
|
+
$( window ).unbind( "." + tableId );
|
108
|
+
|
109
|
+
// other plugins
|
110
|
+
this.$table.trigger( events.destroy, [ this ] );
|
111
|
+
|
112
|
+
this.$table.removeAttr( 'data-mode' );
|
113
|
+
|
114
|
+
this.$table.removeData( pluginName );
|
115
|
+
};
|
116
|
+
|
117
|
+
// Collection method.
|
118
|
+
$.fn[ pluginName ] = function() {
|
119
|
+
return this.each( function() {
|
120
|
+
var $t = $( this );
|
121
|
+
|
122
|
+
if( $t.data( pluginName ) ){
|
123
|
+
return;
|
124
|
+
}
|
125
|
+
|
126
|
+
var table = new Table( this );
|
127
|
+
$t.data( pluginName, table );
|
128
|
+
});
|
129
|
+
};
|
130
|
+
|
131
|
+
$( document ).on( "enhance.tablesaw", function( e ) {
|
132
|
+
$( e.target ).find( initSelector )[ pluginName ]();
|
133
|
+
});
|
134
|
+
|
135
|
+
}( jQuery ));
|
@@ -0,0 +1,81 @@
|
|
1
|
+
/*
|
2
|
+
* tablesaw: A set of plugins for responsive tables
|
3
|
+
* minimap: a set of dots to show which columns are currently visible.
|
4
|
+
* Copyright (c) 2013 Filament Group, Inc.
|
5
|
+
* MIT License
|
6
|
+
*/
|
7
|
+
|
8
|
+
;(function( win, $, undefined ){
|
9
|
+
|
10
|
+
var MM = {
|
11
|
+
attr: {
|
12
|
+
init: 'data-minimap'
|
13
|
+
}
|
14
|
+
};
|
15
|
+
|
16
|
+
function createMiniMap( $table ){
|
17
|
+
|
18
|
+
var $btns = $( '<div class="tablesaw-advance minimap">' ),
|
19
|
+
$dotNav = $( '<ul class="tablesaw-advance-dots">' ).appendTo( $btns ),
|
20
|
+
hideDot = 'tablesaw-advance-dots-hide',
|
21
|
+
$headerCells = $table.find( 'thead th' );
|
22
|
+
|
23
|
+
// populate dots
|
24
|
+
$headerCells.each(function(){
|
25
|
+
$dotNav.append( '<li><i></i></li>' );
|
26
|
+
});
|
27
|
+
|
28
|
+
$btns.appendTo( $table.prev( '.tablesaw-bar' ) );
|
29
|
+
|
30
|
+
function showMinimap( $table ) {
|
31
|
+
var mq = $table.attr( MM.attr.init );
|
32
|
+
return !mq || win.matchMedia && win.matchMedia( mq ).matches;
|
33
|
+
}
|
34
|
+
|
35
|
+
function showHideNav(){
|
36
|
+
if( !showMinimap( $table ) ) {
|
37
|
+
$btns.hide();
|
38
|
+
return;
|
39
|
+
}
|
40
|
+
$btns.show();
|
41
|
+
|
42
|
+
// show/hide dots
|
43
|
+
var dots = $dotNav.find( "li" ).removeClass( hideDot );
|
44
|
+
$table.find( "thead th" ).each(function(i){
|
45
|
+
if( $( this ).css( "display" ) === "none" ){
|
46
|
+
dots.eq( i ).addClass( hideDot );
|
47
|
+
}
|
48
|
+
});
|
49
|
+
}
|
50
|
+
|
51
|
+
// run on init and resize
|
52
|
+
showHideNav();
|
53
|
+
$( win ).on( "resize", showHideNav );
|
54
|
+
|
55
|
+
|
56
|
+
$table
|
57
|
+
.bind( "tablesawcolumns.minimap", function(){
|
58
|
+
showHideNav();
|
59
|
+
})
|
60
|
+
.bind( "tablesawdestroy.minimap", function(){
|
61
|
+
var $t = $( this );
|
62
|
+
|
63
|
+
$t.prev( '.tablesaw-bar' ).find( '.tablesaw-advance' ).remove();
|
64
|
+
$( win ).off( "resize", showHideNav );
|
65
|
+
|
66
|
+
$t.unbind( ".minimap" );
|
67
|
+
});
|
68
|
+
}
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
// on tablecreate, init
|
73
|
+
$( document ).on( "tablesawcreate", function( e, Tablesaw ){
|
74
|
+
|
75
|
+
if( ( Tablesaw.mode === 'swipe' || Tablesaw.mode === 'columntoggle' ) && Tablesaw.$table.is( '[ ' + MM.attr.init + ']' ) ){
|
76
|
+
createMiniMap( Tablesaw.$table );
|
77
|
+
}
|
78
|
+
|
79
|
+
} );
|
80
|
+
|
81
|
+
}( this, jQuery ));
|
@@ -0,0 +1,87 @@
|
|
1
|
+
/*
|
2
|
+
* tablesaw: A set of plugins for responsive tables
|
3
|
+
* Mode Switch: UI element to allow the user to change table modes: stack/swipe/columntoggle
|
4
|
+
* Copyright (c) 2013 Filament Group, Inc.
|
5
|
+
* MIT License
|
6
|
+
*/
|
7
|
+
|
8
|
+
;(function( win, $ ) {
|
9
|
+
|
10
|
+
var S = {
|
11
|
+
selectors: {
|
12
|
+
init: 'table[data-mode-switch]'
|
13
|
+
},
|
14
|
+
attributes: {
|
15
|
+
excludeMode: 'data-mode-exclude'
|
16
|
+
},
|
17
|
+
classes: {
|
18
|
+
main: 'tablesaw-modeswitch',
|
19
|
+
toolbar: 'tablesaw-toolbar'
|
20
|
+
},
|
21
|
+
modes: [ 'stack', 'swipe', 'columntoggle' ],
|
22
|
+
i18n: {
|
23
|
+
modes: [ 'Stack', 'Swipe', 'Toggle' ],
|
24
|
+
columns: 'Col<span class="a11y-sm">umn</span>s'
|
25
|
+
},
|
26
|
+
init: function( table ) {
|
27
|
+
var $table = $( table ),
|
28
|
+
ignoreMode = $table.attr( S.attributes.excludeMode ),
|
29
|
+
$toolbar = $table.prev( '.tablesaw-bar' ),
|
30
|
+
modeVal = '',
|
31
|
+
$switcher = $( '<div>' ).addClass( S.classes.main + ' ' + S.classes.toolbar ).html(function() {
|
32
|
+
var html = [ '<label>' + S.i18n.columns + ':' ],
|
33
|
+
dataMode = $table.attr( 'data-mode' ),
|
34
|
+
isSelected;
|
35
|
+
|
36
|
+
html.push( '<span class="btn btn-small"> <select>' );
|
37
|
+
for( var j=0, k = S.modes.length; j<k; j++ ) {
|
38
|
+
if( ignoreMode && ignoreMode.toLowerCase() === S.modes[ j ] ) {
|
39
|
+
continue;
|
40
|
+
}
|
41
|
+
|
42
|
+
isSelected = dataMode === S.modes[ j ];
|
43
|
+
|
44
|
+
if( isSelected ) {
|
45
|
+
modeVal = S.modes[ j ];
|
46
|
+
}
|
47
|
+
|
48
|
+
html.push( '<option' +
|
49
|
+
( isSelected ? ' selected' : '' ) +
|
50
|
+
' value="' + S.modes[ j ] + '">' + S.i18n.modes[ j ] + '</option>' );
|
51
|
+
}
|
52
|
+
html.push( '</select></span></label>' );
|
53
|
+
|
54
|
+
return html.join('');
|
55
|
+
});
|
56
|
+
|
57
|
+
var $otherToolbarItems = $toolbar.find( '.tablesaw-advance' ).eq( 0 );
|
58
|
+
if( $otherToolbarItems.length ) {
|
59
|
+
$switcher.insertBefore( $otherToolbarItems );
|
60
|
+
} else {
|
61
|
+
$switcher.appendTo( $toolbar );
|
62
|
+
}
|
63
|
+
|
64
|
+
$switcher.find( '.btn' ).tablesawbtn();
|
65
|
+
$switcher.find( 'select' ).bind( 'change', S.onModeChange );
|
66
|
+
},
|
67
|
+
onModeChange: function() {
|
68
|
+
var $t = $( this ),
|
69
|
+
$switcher = $t.closest( '.' + S.classes.main ),
|
70
|
+
$table = $t.closest( '.tablesaw-bar' ).nextUntil( $table ).eq( 0 ),
|
71
|
+
val = $t.val();
|
72
|
+
|
73
|
+
$switcher.remove();
|
74
|
+
$table.data( 'table' ).destroy();
|
75
|
+
|
76
|
+
$table.attr( 'data-mode', val );
|
77
|
+
$table.table();
|
78
|
+
}
|
79
|
+
};
|
80
|
+
|
81
|
+
$( win.document ).on( "tablesawcreate", function( e, Tablesaw ) {
|
82
|
+
if( Tablesaw.$table.is( S.selectors.init ) ) {
|
83
|
+
S.init( Tablesaw.table );
|
84
|
+
}
|
85
|
+
});
|
86
|
+
|
87
|
+
})( this, jQuery );
|
@@ -0,0 +1,274 @@
|
|
1
|
+
/*
|
2
|
+
* tablesaw: A set of plugins for responsive tables
|
3
|
+
* Sortable column headers
|
4
|
+
* Copyright (c) 2013 Filament Group, Inc.
|
5
|
+
* MIT License
|
6
|
+
*/
|
7
|
+
|
8
|
+
;(function( $ ) {
|
9
|
+
function getSortValue( cell ) {
|
10
|
+
return $.map( cell.childNodes, function( el ) {
|
11
|
+
var $el = $( el );
|
12
|
+
if( $el.is( 'input, select' ) ) {
|
13
|
+
return $el.val();
|
14
|
+
} else if( $el.hasClass( 'tablesaw-cell-label' ) ) {
|
15
|
+
return;
|
16
|
+
}
|
17
|
+
return $.trim( $el.text() );
|
18
|
+
}).join( '' );
|
19
|
+
}
|
20
|
+
|
21
|
+
var topLevelPluginName = "tablesaw-sortable",
|
22
|
+
pluginName = "sortable",
|
23
|
+
initSelector = "table[data-" + pluginName + "]",
|
24
|
+
sortableSwitchSelector = "[data-" + pluginName + "-switch]",
|
25
|
+
classes = {
|
26
|
+
head: pluginName + "-head",
|
27
|
+
ascend: pluginName + "-ascending",
|
28
|
+
descend: pluginName + "-descending",
|
29
|
+
switcher: topLevelPluginName + "-switch",
|
30
|
+
tableToolbar: 'tablesaw-toolbar'
|
31
|
+
},
|
32
|
+
i18n = {
|
33
|
+
sort: 'Sort'
|
34
|
+
},
|
35
|
+
methods = {
|
36
|
+
_create: function( o ){
|
37
|
+
return $( this ).each(function() {
|
38
|
+
var init = $( this ).data( "init" + pluginName );
|
39
|
+
if( init ) {
|
40
|
+
return false;
|
41
|
+
}
|
42
|
+
$( this )
|
43
|
+
.data( "init"+ pluginName, true )
|
44
|
+
.trigger( "beforecreate." + pluginName )
|
45
|
+
[ pluginName ]( "_init" , o )
|
46
|
+
.trigger( "create." + pluginName );
|
47
|
+
});
|
48
|
+
},
|
49
|
+
_init: function(){
|
50
|
+
var el = $( this ),
|
51
|
+
heads,
|
52
|
+
$switcher;
|
53
|
+
|
54
|
+
var addClassToTable = function(){
|
55
|
+
el.addClass( topLevelPluginName );
|
56
|
+
},
|
57
|
+
addClassToHeads = function( h ){
|
58
|
+
$.each( h , function( i , v ){
|
59
|
+
$( v ).addClass( classes.head );
|
60
|
+
});
|
61
|
+
},
|
62
|
+
makeHeadsActionable = function( h , fn ){
|
63
|
+
$.each( h , function( i , v ){
|
64
|
+
var b = $( "<button />" );
|
65
|
+
b.bind( "click" , { col: v } , fn );
|
66
|
+
$( v ).wrapInner( b );
|
67
|
+
});
|
68
|
+
},
|
69
|
+
clearOthers = function( sibs ){
|
70
|
+
$.each( sibs , function( i , v ){
|
71
|
+
var col = $( v );
|
72
|
+
col.removeAttr( "data-sortable-default-col" );
|
73
|
+
col.removeClass( classes.ascend );
|
74
|
+
col.removeClass( classes.descend );
|
75
|
+
});
|
76
|
+
},
|
77
|
+
headsOnAction = function( e ){
|
78
|
+
if( $( e.target ).is( 'a[href]' ) ) {
|
79
|
+
return;
|
80
|
+
}
|
81
|
+
|
82
|
+
e.stopPropagation();
|
83
|
+
var head = $( this ).parent(),
|
84
|
+
v = e.data.col,
|
85
|
+
newSortValue = heads.index( head );
|
86
|
+
|
87
|
+
clearOthers( head.siblings() );
|
88
|
+
if( head.hasClass( classes.descend ) ){
|
89
|
+
el[ pluginName ]( "sortBy" , v , true);
|
90
|
+
newSortValue += '_asc';
|
91
|
+
} else {
|
92
|
+
el[ pluginName ]( "sortBy" , v );
|
93
|
+
newSortValue += '_desc';
|
94
|
+
}
|
95
|
+
if( $switcher ) {
|
96
|
+
$switcher.find( 'select' ).val( newSortValue ).trigger( 'refresh' );
|
97
|
+
}
|
98
|
+
|
99
|
+
e.preventDefault();
|
100
|
+
},
|
101
|
+
handleDefault = function( heads ){
|
102
|
+
$.each( heads , function( idx , el ){
|
103
|
+
var $el = $( el );
|
104
|
+
if( $el.is( "[data-sortable-default-col]" ) ){
|
105
|
+
if( !$el.hasClass( classes.descend ) ) {
|
106
|
+
$el.addClass( classes.ascend );
|
107
|
+
}
|
108
|
+
}
|
109
|
+
});
|
110
|
+
},
|
111
|
+
addSwitcher = function( heads ){
|
112
|
+
$switcher = $( '<div>' ).addClass( classes.switcher ).addClass( classes.tableToolbar ).html(function() {
|
113
|
+
var html = [ '<label>' + i18n.sort + ':' ];
|
114
|
+
|
115
|
+
html.push( '<span class="btn btn-small"> <select>' );
|
116
|
+
heads.each(function( j ) {
|
117
|
+
var $t = $( this ),
|
118
|
+
isDefaultCol = $t.is( '[data-sortable-default-col]' ),
|
119
|
+
isDescending = $t.hasClass( classes.descend ),
|
120
|
+
isNumeric = false;
|
121
|
+
|
122
|
+
// Check only the first three rows to see if the column is numbers.
|
123
|
+
$( this.cells ).slice( 0, 3 ).each(function() {
|
124
|
+
if( !isNaN( parseInt( getSortValue( this ), 10 ) ) ) {
|
125
|
+
isNumeric = true;
|
126
|
+
return false;
|
127
|
+
}
|
128
|
+
});
|
129
|
+
|
130
|
+
html.push( '<option' + ( isDefaultCol && !isDescending ? ' selected' : '' ) + ' value="' + j + '_asc">' + $t.text() + ' ' + ( isNumeric ? '↑' : '(A-Z)' ) + '</option>' );
|
131
|
+
html.push( '<option' + ( isDefaultCol && isDescending ? ' selected' : '' ) + ' value="' + j + '_desc">' + $t.text() + ' ' + ( isNumeric ? '↓' : '(Z-A)' ) + '</option>' );
|
132
|
+
});
|
133
|
+
html.push( '</select></span></label>' );
|
134
|
+
|
135
|
+
return html.join('');
|
136
|
+
});
|
137
|
+
|
138
|
+
var $toolbar = el.prev( '.tablesaw-bar' ),
|
139
|
+
$firstChild = $toolbar.children().eq( 0 );
|
140
|
+
|
141
|
+
if( $firstChild.length ) {
|
142
|
+
$switcher.insertBefore( $firstChild );
|
143
|
+
} else {
|
144
|
+
$switcher.appendTo( $toolbar );
|
145
|
+
}
|
146
|
+
$switcher.find( '.btn' ).tablesawbtn();
|
147
|
+
$switcher.find( 'select' ).on( 'change', function() {
|
148
|
+
var val = $( this ).val().split( '_' ),
|
149
|
+
head = heads.eq( val[ 0 ] );
|
150
|
+
|
151
|
+
clearOthers( head.siblings() );
|
152
|
+
el.sortable( 'sortBy', head.get( 0 ), val[ 1 ] === 'asc' );
|
153
|
+
});
|
154
|
+
};
|
155
|
+
|
156
|
+
addClassToTable();
|
157
|
+
heads = el.find( "thead th[data-" + pluginName + "-col]" );
|
158
|
+
addClassToHeads( heads );
|
159
|
+
makeHeadsActionable( heads , headsOnAction );
|
160
|
+
handleDefault( heads );
|
161
|
+
|
162
|
+
if( el.is( sortableSwitchSelector ) ) {
|
163
|
+
addSwitcher( heads, el.find('tbody tr:nth-child(-n+3)') );
|
164
|
+
}
|
165
|
+
},
|
166
|
+
getColumnNumber: function( col ){
|
167
|
+
return $( col ).prevAll().length;
|
168
|
+
},
|
169
|
+
getTableRows: function(){
|
170
|
+
return $( this ).find( "tbody tr" );
|
171
|
+
},
|
172
|
+
sortRows: function( rows , colNum , ascending, col ){
|
173
|
+
var cells, fn, sorted;
|
174
|
+
var getCells = function( rows ){
|
175
|
+
var cells = [];
|
176
|
+
$.each( rows , function( i , r ){
|
177
|
+
cells.push({
|
178
|
+
cell: getSortValue( $( r ).children().get( colNum ) ),
|
179
|
+
rowNum: i
|
180
|
+
});
|
181
|
+
});
|
182
|
+
return cells;
|
183
|
+
},
|
184
|
+
getSortFxn = function( ascending, forceNumeric ){
|
185
|
+
var fn,
|
186
|
+
regex = /[^\d\.]/g;
|
187
|
+
if( ascending ){
|
188
|
+
fn = function( a , b ){
|
189
|
+
if( forceNumeric || !isNaN( parseFloat( a.cell ) ) ) {
|
190
|
+
return parseFloat( a.cell.replace( regex, '' ) ) - parseFloat( b.cell.replace( regex, '' ) );
|
191
|
+
} else {
|
192
|
+
return a.cell.toLowerCase() > b.cell.toLowerCase() ? 1 : -1;
|
193
|
+
}
|
194
|
+
};
|
195
|
+
} else {
|
196
|
+
fn = function( a , b ){
|
197
|
+
if( forceNumeric || !isNaN( parseFloat( a.cell ) ) ) {
|
198
|
+
return parseFloat( b.cell.replace( regex, '' ) ) - parseFloat( a.cell.replace( regex, '' ) );
|
199
|
+
} else {
|
200
|
+
return a.cell.toLowerCase() < b.cell.toLowerCase() ? 1 : -1;
|
201
|
+
}
|
202
|
+
};
|
203
|
+
}
|
204
|
+
return fn;
|
205
|
+
},
|
206
|
+
applyToRows = function( sorted , rows ){
|
207
|
+
var newRows = [], i, l, cur;
|
208
|
+
for( i = 0, l = sorted.length ; i < l ; i++ ){
|
209
|
+
cur = sorted[ i ].rowNum;
|
210
|
+
newRows.push( rows[cur] );
|
211
|
+
}
|
212
|
+
return newRows;
|
213
|
+
};
|
214
|
+
|
215
|
+
cells = getCells( rows );
|
216
|
+
fn = getSortFxn( ascending, $( col ).is( '[data-sortable-numeric]' ) );
|
217
|
+
sorted = cells.sort( fn );
|
218
|
+
rows = applyToRows( sorted , rows );
|
219
|
+
return rows;
|
220
|
+
},
|
221
|
+
replaceTableRows: function( rows ){
|
222
|
+
var el = $( this ),
|
223
|
+
body = el.find( "tbody" );
|
224
|
+
body.html( rows );
|
225
|
+
},
|
226
|
+
makeColDefault: function( col , a ){
|
227
|
+
var c = $( col );
|
228
|
+
c.attr( "data-sortable-default-col" , "true" );
|
229
|
+
if( a ){
|
230
|
+
c.removeClass( classes.descend );
|
231
|
+
c.addClass( classes.ascend );
|
232
|
+
} else {
|
233
|
+
c.removeClass( classes.ascend );
|
234
|
+
c.addClass( classes.descend );
|
235
|
+
}
|
236
|
+
},
|
237
|
+
sortBy: function( col , ascending ){
|
238
|
+
var el = $( this ), colNum, rows;
|
239
|
+
|
240
|
+
colNum = el[ pluginName ]( "getColumnNumber" , col );
|
241
|
+
rows = el[ pluginName ]( "getTableRows" );
|
242
|
+
rows = el[ pluginName ]( "sortRows" , rows , colNum , ascending, col );
|
243
|
+
el[ pluginName ]( "replaceTableRows" , rows );
|
244
|
+
el[ pluginName ]( "makeColDefault" , col , ascending );
|
245
|
+
}
|
246
|
+
};
|
247
|
+
|
248
|
+
// Collection method.
|
249
|
+
$.fn[ pluginName ] = function( arrg ) {
|
250
|
+
var args = Array.prototype.slice.call( arguments , 1),
|
251
|
+
returnVal;
|
252
|
+
|
253
|
+
// if it's a method
|
254
|
+
if( arrg && typeof( arrg ) === "string" ){
|
255
|
+
returnVal = $.fn[ pluginName ].prototype[ arrg ].apply( this[0], args );
|
256
|
+
return (typeof returnVal !== "undefined")? returnVal:$(this);
|
257
|
+
}
|
258
|
+
// check init
|
259
|
+
if( !$( this ).data( pluginName + "data" ) ){
|
260
|
+
$( this ).data( pluginName + "active", true );
|
261
|
+
$.fn[ pluginName ].prototype._create.call( this , arrg );
|
262
|
+
}
|
263
|
+
return $(this);
|
264
|
+
};
|
265
|
+
// add methods
|
266
|
+
$.extend( $.fn[ pluginName ].prototype, methods );
|
267
|
+
|
268
|
+
$( document ).on( "tablesawcreate", function( e, Tablesaw ) {
|
269
|
+
if( Tablesaw.$table.is( initSelector ) ) {
|
270
|
+
Tablesaw.$table[ pluginName ]();
|
271
|
+
}
|
272
|
+
});
|
273
|
+
|
274
|
+
}( jQuery ));
|