Skip to content

Instantly share code, notes, and snippets.

@stefanak-michal
Created February 4, 2022 19:14
Show Gist options
  • Save stefanak-michal/b12737679649855118152e303746a404 to your computer and use it in GitHub Desktop.
Save stefanak-michal/b12737679649855118152e303746a404 to your computer and use it in GitHub Desktop.
//if you need debug speed to console
var DEBUG_SORT_SPEED = false;
/**
* Ordering tables with table class definition <table class='sort'>, and have defined <thead> with <th> cells
* Column with all integer values, sorted automatic numeric
* Force say to column be a order numeric <th sorttype='int'>
* Or by datetime <th sorttype='date' date-format='d.m.y'> (for more info see fnc generateDateByFormat anotation)
*
* @author Michal Stefanak
* @link https://ko-fi.com/michalstefanak
* @param {Object} t
*/
function sortTable(t)
{
var column = $(t).index(),
columnText = $(t).text(),
isInt = false,
isDate = false,
dateFormat = '',
sTable = $(t).closest('table'),
sort = $(t).attr('sort'),
debug_time;
if ( DEBUG_SORT_SPEED ) {
console.log('Sort by: ' + columnText)
debug_time = microtime(true);
}
//if is defined order
if ($(t).attr('sorttype') == 'int') {
isInt = true;
} else if ($(t).attr('sorttype') == 'date') {
isDate = true;
dateFormat = $(t).attr('date-format');
}
if ( DEBUG_SORT_SPEED ) {
console.log('get defined sorttype', microtime(true) - debug_time);
debug_time = microtime(true);
}
//resolve direction of sorting
if (typeof sort == "undefined") {
sort = 'asc';
$(t).html(columnText + ' &#8593;');
} else if (sort == 'asc') {
sort = 'desc';
$(t).html(columnText.substring(0, columnText.length - 2) + ' &#8595;');
} else if (sort == 'desc') {
sort = 'asc';
$(t).html(columnText.substring(0, columnText.length - 2) + ' &#8593;');
}
$(t).attr('sort', sort);
if ( DEBUG_SORT_SPEED ) {
console.log('get sort direction', microtime(true) - debug_time);
debug_time = microtime(true);
}
//clear other head cells
var tmpValueText,
headerColumns = $('thead > tr > th', sTable);
headerColumns.each(function() {
if ( !$(this).is( $(t) ) && typeof $(this).attr('sort') != "undefined" ) {
$(this).removeAttr('sort');
tmpValueText = $(this).text();
$(this).text(tmpValueText.substring(0, tmpValueText.length - 2));
}
});
if ( DEBUG_SORT_SPEED ) {
console.log('clear other table cells sort info', microtime(true) - debug_time);
debug_time = microtime(true);
}
var keyA, keyB,
tRows = $('tbody > tr', sTable);
//if we dont have defined order, look if can order numeric
if (isInt === false && isDate === false) {
isInt = true;
tRows.each(function() {
if ( this.cells[column].textContent.toLowerCase().match(/^\D+/) ) {
isInt = false;
return false;
}
});
}
if ( DEBUG_SORT_SPEED ) {
console.log('check int order', microtime(true) - debug_time);
debug_time = microtime(true);
}
//ordering table rows
tRows.sort(function(a, b) {
keyA = a.cells[column].textContent.toLowerCase();
keyB = b.cells[column].textContent.toLowerCase();
if (isInt) {
//take first number in string
keyA = keyA.length > 0 ? parseInt(keyA.replace(/[^\d]/g, '')) : 0;
keyB = keyB.length > 0 ? parseInt(keyB.replace(/[^\d]/g, '')) : 0;
} else if ( isDate ) {
keyA = keyA.trim().length > 0 ? generateDateByFormat(keyA.trim(), dateFormat) : 0;
keyB = keyB.trim().length > 0 ? generateDateByFormat(keyB.trim(), dateFormat) : 0;
}
if (sort === 'asc') {
if (isInt || isDate) {
return keyA > keyB ? 1 : -1;
} else {
return keyA.localeCompare(keyB);
}
} else if (sort === 'desc') {
if (isInt || isDate) {
return keyB > keyA ? 1 : -1;
} else {
return keyB.localeCompare(keyA);
}
}
});
if ( DEBUG_SORT_SPEED ) {
console.log('sort rows', microtime(true) - debug_time);
debug_time = microtime(true);
}
sTable.append(tRows);
if ( DEBUG_SORT_SPEED ) {
console.log('replace rows', microtime(true) - debug_time);
}
}
/**
* Create object Date from datetime string by mask
* Formatting allowed characters:
* y - year
* m - month
* d - day
* h - hours
* i - minutes
* s - seconds
* Allowed separators ./: and space
*
* @param {String} date
* @param {String} format
* @returns {Date}
*/
function generateDateByFormat(date, format)
{
var patt = /[ \.\/:]/,
formatOrder = format.toLowerCase().split(patt),
dateParts = date.split(patt),
createDateParts = [0,0,0,0,0,0],
formatIndex;
$.each(formatOrder, function(index, formatChar) {
formatIndex = -1;
switch (formatChar) {
case 'y':
formatIndex = 0;
break;
case 'm':
formatIndex = 1;
break;
case 'd':
formatIndex = 2;
break;
case 'h':
formatIndex = 3;
break;
case 'i':
formatIndex = 4;
break;
case 's':
formatIndex = 5;
break;
}
if ( formatIndex !== -1 && typeof dateParts[index] !== "undefined" ) {
createDateParts[formatIndex] = parseInt(dateParts[index]);
}
});
return new Date(createDateParts[0], createDateParts[1] !== 0 ? (createDateParts[1] -1) : 0, createDateParts[2], createDateParts[3], createDateParts[4], createDateParts[5], 0)
}
function microtime(get_as_float) {
// discuss at: http://phpjs.org/functions/microtime/
// original by: Paulo Freitas
// example 1: timeStamp = microtime(true);
// example 1: timeStamp > 1000000000 && timeStamp < 2000000000
// returns 1: true
var now = new Date()
.getTime() / 1000;
var s = parseInt(now, 10);
return (get_as_float) ? now : (Math.round((now - s) * 1000) / 1000) + ' ' + s;
}
//init ordering
$(document).ready(function() {
$('table.sort > thead > tr > th').click(function() {
sortTable(this);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment