first commit
This commit is contained in:
285
public/bower_components/filament-tablesaw/src/tables.sortable.js
vendored
Executable file
285
public/bower_components/filament-tablesaw/src/tables.sortable.js
vendored
Executable file
@@ -0,0 +1,285 @@
|
||||
/*
|
||||
* tablesaw: A set of plugins for responsive tables
|
||||
* Sortable column headers
|
||||
* Copyright (c) 2013 Filament Group, Inc.
|
||||
* MIT License
|
||||
*/
|
||||
|
||||
;(function( $ ) {
|
||||
function getSortValue( cell ) {
|
||||
return $.map( cell.childNodes, function( el ) {
|
||||
var $el = $( el );
|
||||
if( $el.is( 'input, select' ) ) {
|
||||
return $el.val();
|
||||
} else if( $el.hasClass( 'tablesaw-cell-label' ) ) {
|
||||
return;
|
||||
}
|
||||
return $.trim( $el.text() );
|
||||
}).join( '' );
|
||||
}
|
||||
|
||||
var pluginName = "tablesaw-sortable",
|
||||
initSelector = "table[data-" + pluginName + "]",
|
||||
sortableSwitchSelector = "[data-" + pluginName + "-switch]",
|
||||
attrs = {
|
||||
defaultCol: "data-tablesaw-sortable-default-col",
|
||||
numericCol: "data-tablesaw-sortable-numeric"
|
||||
},
|
||||
classes = {
|
||||
head: pluginName + "-head",
|
||||
ascend: pluginName + "-ascending",
|
||||
descend: pluginName + "-descending",
|
||||
switcher: pluginName + "-switch",
|
||||
tableToolbar: 'tablesaw-toolbar',
|
||||
sortButton: pluginName + "-btn"
|
||||
},
|
||||
methods = {
|
||||
_create: function( o ){
|
||||
return $( this ).each(function() {
|
||||
var init = $( this ).data( "init" + pluginName );
|
||||
if( init ) {
|
||||
return false;
|
||||
}
|
||||
$( this )
|
||||
.data( "init"+ pluginName, true )
|
||||
.trigger( "beforecreate." + pluginName )
|
||||
[ pluginName ]( "_init" , o )
|
||||
.trigger( "create." + pluginName );
|
||||
});
|
||||
},
|
||||
_init: function(){
|
||||
var el = $( this ),
|
||||
heads,
|
||||
$switcher;
|
||||
|
||||
var addClassToTable = function(){
|
||||
el.addClass( pluginName );
|
||||
},
|
||||
addClassToHeads = function( h ){
|
||||
$.each( h , function( i , v ){
|
||||
$( v ).addClass( classes.head );
|
||||
});
|
||||
},
|
||||
makeHeadsActionable = function( h , fn ){
|
||||
$.each( h , function( i , v ){
|
||||
var b = $( "<button class='" + classes.sortButton + "'/>" );
|
||||
b.bind( "click" , { col: v } , fn );
|
||||
$( v ).wrapInner( b );
|
||||
});
|
||||
},
|
||||
clearOthers = function( sibs ){
|
||||
$.each( sibs , function( i , v ){
|
||||
var col = $( v );
|
||||
col.removeAttr( attrs.defaultCol );
|
||||
col.removeClass( classes.ascend );
|
||||
col.removeClass( classes.descend );
|
||||
});
|
||||
},
|
||||
headsOnAction = function( e ){
|
||||
if( $( e.target ).is( 'a[href]' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.stopPropagation();
|
||||
var head = $( this ).parent(),
|
||||
v = e.data.col,
|
||||
newSortValue = heads.index( head );
|
||||
|
||||
clearOthers( head.siblings() );
|
||||
if( head.hasClass( classes.descend ) ){
|
||||
el[ pluginName ]( "sortBy" , v , true);
|
||||
newSortValue += '_asc';
|
||||
} else {
|
||||
el[ pluginName ]( "sortBy" , v );
|
||||
newSortValue += '_desc';
|
||||
}
|
||||
if( $switcher ) {
|
||||
$switcher.find( 'select' ).val( newSortValue ).trigger( 'refresh' );
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
},
|
||||
handleDefault = function( heads ){
|
||||
$.each( heads , function( idx , el ){
|
||||
var $el = $( el );
|
||||
if( $el.is( "[" + attrs.defaultCol + "]" ) ){
|
||||
if( !$el.hasClass( classes.descend ) ) {
|
||||
$el.addClass( classes.ascend );
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
addSwitcher = function( heads ){
|
||||
$switcher = $( '<div>' ).addClass( classes.switcher ).addClass( classes.tableToolbar ).html(function() {
|
||||
var html = [ '<label>' + Tablesaw.i18n.sort + ':' ];
|
||||
|
||||
html.push( '<span class="btn btn-small"> <select>' );
|
||||
heads.each(function( j ) {
|
||||
var $t = $( this );
|
||||
var isDefaultCol = $t.is( "[" + attrs.defaultCol + "]" );
|
||||
var isDescending = $t.hasClass( classes.descend );
|
||||
|
||||
var hasNumericAttribute = $t.is( '[data-sortable-numeric]' );
|
||||
var numericCount = 0;
|
||||
// Check only the first four rows to see if the column is numbers.
|
||||
var numericCountMax = 5;
|
||||
|
||||
$( this.cells ).slice( 0, numericCountMax ).each(function() {
|
||||
if( !isNaN( parseInt( getSortValue( this ), 10 ) ) ) {
|
||||
numericCount++;
|
||||
}
|
||||
});
|
||||
var isNumeric = numericCount === numericCountMax;
|
||||
if( !hasNumericAttribute ) {
|
||||
$t.attr( "data-sortable-numeric", isNumeric ? "" : "false" );
|
||||
}
|
||||
|
||||
html.push( '<option' + ( isDefaultCol && !isDescending ? ' selected' : '' ) + ' value="' + j + '_asc">' + $t.text() + ' ' + ( isNumeric ? '↑' : '(A-Z)' ) + '</option>' );
|
||||
html.push( '<option' + ( isDefaultCol && isDescending ? ' selected' : '' ) + ' value="' + j + '_desc">' + $t.text() + ' ' + ( isNumeric ? '↓' : '(Z-A)' ) + '</option>' );
|
||||
});
|
||||
html.push( '</select></span></label>' );
|
||||
|
||||
return html.join('');
|
||||
});
|
||||
|
||||
var $toolbar = el.prev().filter( '.tablesaw-bar' ),
|
||||
$firstChild = $toolbar.children().eq( 0 );
|
||||
|
||||
if( $firstChild.length ) {
|
||||
$switcher.insertBefore( $firstChild );
|
||||
} else {
|
||||
$switcher.appendTo( $toolbar );
|
||||
}
|
||||
$switcher.find( '.btn' ).tablesawbtn();
|
||||
$switcher.find( 'select' ).on( 'change', function() {
|
||||
var val = $( this ).val().split( '_' ),
|
||||
head = heads.eq( val[ 0 ] );
|
||||
|
||||
clearOthers( head.siblings() );
|
||||
el[ pluginName ]( 'sortBy', head.get( 0 ), val[ 1 ] === 'asc' );
|
||||
});
|
||||
};
|
||||
|
||||
addClassToTable();
|
||||
heads = el.find( "thead th[data-" + pluginName + "-col]" );
|
||||
addClassToHeads( heads );
|
||||
makeHeadsActionable( heads , headsOnAction );
|
||||
handleDefault( heads );
|
||||
|
||||
if( el.is( sortableSwitchSelector ) ) {
|
||||
addSwitcher( heads, el.find('tbody tr:nth-child(-n+3)') );
|
||||
}
|
||||
},
|
||||
getColumnNumber: function( col ){
|
||||
return $( col ).prevAll().length;
|
||||
},
|
||||
getTableRows: function(){
|
||||
return $( this ).find( "tbody tr" );
|
||||
},
|
||||
sortRows: function( rows , colNum , ascending, col ){
|
||||
var cells, fn, sorted;
|
||||
var getCells = function( rows ){
|
||||
var cells = [];
|
||||
$.each( rows , function( i , r ){
|
||||
var element = $( r ).children().get( colNum );
|
||||
cells.push({
|
||||
element: element,
|
||||
cell: getSortValue( element ),
|
||||
rowNum: i
|
||||
});
|
||||
});
|
||||
return cells;
|
||||
},
|
||||
getSortFxn = function( ascending, forceNumeric ){
|
||||
var fn,
|
||||
regex = /[^\-\+\d\.]/g;
|
||||
if( ascending ){
|
||||
fn = function( a , b ){
|
||||
if( forceNumeric ) {
|
||||
return parseFloat( a.cell.replace( regex, '' ) ) - parseFloat( b.cell.replace( regex, '' ) );
|
||||
} else {
|
||||
return a.cell.toLowerCase() > b.cell.toLowerCase() ? 1 : -1;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
fn = function( a , b ){
|
||||
if( forceNumeric ) {
|
||||
return parseFloat( b.cell.replace( regex, '' ) ) - parseFloat( a.cell.replace( regex, '' ) );
|
||||
} else {
|
||||
return a.cell.toLowerCase() < b.cell.toLowerCase() ? 1 : -1;
|
||||
}
|
||||
};
|
||||
}
|
||||
return fn;
|
||||
},
|
||||
applyToRows = function( sorted , rows ){
|
||||
var newRows = [], i, l, cur;
|
||||
for( i = 0, l = sorted.length ; i < l ; i++ ){
|
||||
cur = sorted[ i ].rowNum;
|
||||
newRows.push( rows[cur] );
|
||||
}
|
||||
return newRows;
|
||||
};
|
||||
|
||||
cells = getCells( rows );
|
||||
var customFn = $( col ).data( 'tablesaw-sort' );
|
||||
fn = ( customFn && typeof customFn === "function" ? customFn( ascending ) : false ) ||
|
||||
getSortFxn( ascending, $( col ).is( '[data-sortable-numeric]' ) && !$( col ).is( '[data-sortable-numeric="false"]' ) );
|
||||
sorted = cells.sort( fn );
|
||||
rows = applyToRows( sorted , rows );
|
||||
return rows;
|
||||
},
|
||||
replaceTableRows: function( rows ){
|
||||
var el = $( this ),
|
||||
body = el.find( "tbody" );
|
||||
body.html( rows );
|
||||
},
|
||||
makeColDefault: function( col , a ){
|
||||
var c = $( col );
|
||||
c.attr( attrs.defaultCol , "true" );
|
||||
if( a ){
|
||||
c.removeClass( classes.descend );
|
||||
c.addClass( classes.ascend );
|
||||
} else {
|
||||
c.removeClass( classes.ascend );
|
||||
c.addClass( classes.descend );
|
||||
}
|
||||
},
|
||||
sortBy: function( col , ascending ){
|
||||
var el = $( this ), colNum, rows;
|
||||
|
||||
colNum = el[ pluginName ]( "getColumnNumber" , col );
|
||||
rows = el[ pluginName ]( "getTableRows" );
|
||||
rows = el[ pluginName ]( "sortRows" , rows , colNum , ascending, col );
|
||||
el[ pluginName ]( "replaceTableRows" , rows );
|
||||
el[ pluginName ]( "makeColDefault" , col , ascending );
|
||||
}
|
||||
};
|
||||
|
||||
// Collection method.
|
||||
$.fn[ pluginName ] = function( arrg ) {
|
||||
var args = Array.prototype.slice.call( arguments , 1),
|
||||
returnVal;
|
||||
|
||||
// if it's a method
|
||||
if( arrg && typeof( arrg ) === "string" ){
|
||||
returnVal = $.fn[ pluginName ].prototype[ arrg ].apply( this[0], args );
|
||||
return (typeof returnVal !== "undefined")? returnVal:$(this);
|
||||
}
|
||||
// check init
|
||||
if( !$( this ).data( pluginName + "data" ) ){
|
||||
$( this ).data( pluginName + "active", true );
|
||||
$.fn[ pluginName ].prototype._create.call( this , arrg );
|
||||
}
|
||||
return $(this);
|
||||
};
|
||||
// add methods
|
||||
$.extend( $.fn[ pluginName ].prototype, methods );
|
||||
|
||||
$( document ).on( "tablesawcreate", function( e, Tablesaw ) {
|
||||
if( Tablesaw.$table.is( initSelector ) ) {
|
||||
Tablesaw.$table[ pluginName ]();
|
||||
}
|
||||
});
|
||||
|
||||
}( jQuery ));
|
||||
Reference in New Issue
Block a user