Component-Builder/media/footable/js/footable.sort.js

191 lines
8.0 KiB
JavaScript

(function ($, w, undefined) {
if (w.footable === undefined || w.footable === null)
throw new Error('Please check and make sure footable.js is included in the page and is loaded prior to this script.');
var defaults = {
sort: true,
sorters: {
alpha: function (a, b) {
if (typeof(a) === 'string') { a = a.toLowerCase(); }
if (typeof(b) === 'string') { b = b.toLowerCase(); }
if (a === b) return 0;
if (a < b) return -1;
return 1;
},
numeric: function (a, b) {
return a - b;
}
},
classes: {
sort: {
sortable: 'footable-sortable',
sorted: 'footable-sorted',
descending: 'footable-sorted-desc',
indicator: 'footable-sort-indicator'
}
},
events: {
sort: {
sorting: 'footable_sorting',
sorted: 'footable_sorted'
}
}
};
function Sort() {
var p = this;
p.name = 'Footable Sortable';
p.init = function (ft) {
p.footable = ft;
if (ft.options.sort === true) {
$(ft.table)
.unbind('.sorting')
.bind({
'footable_initialized.sorting': function (e) {
var $table = $(ft.table),
$tbody = $table.find('> tbody'),
cls = ft.options.classes.sort,
column, $th;
if ($table.data('sort') === false) return;
$table.find('> thead > tr:last-child > th, > thead > tr:last-child > td').each(function (ec) {
var $th = $(this), column = ft.columns[$th.index()];
if (column.sort.ignore !== true && !$th.hasClass(cls.sortable)) {
$th.addClass(cls.sortable);
$('<span />').addClass(cls.indicator).appendTo($th);
}
});
$table.find('> thead > tr:last-child > th.' + cls.sortable + ', > thead > tr:last-child > td.' + cls.sortable).unbind('click.footable').bind('click.footable', function (ec) {
ec.preventDefault();
$th = $(this);
var ascending = !$th.hasClass(cls.sorted);
p.doSort($th.index(), ascending);
return false;
});
var didSomeSorting = false;
for (var c in ft.columns) {
column = ft.columns[c];
if (column.sort.initial) {
var ascending = (column.sort.initial !== 'descending');
p.doSort(column.index, ascending);
break;
}
}
if (didSomeSorting) {
ft.bindToggleSelectors();
}
},
'footable_redrawn.sorting': function(e) {
var $table = $(ft.table),
cls = ft.options.classes.sort;
if ($table.data('sorted') >= 0) {
$table.find('> thead > tr:last-child > th').each(function(i){
var $th = $(this);
if ($th.hasClass(cls.sorted) || $th.hasClass(cls.descending)) {
p.doSort(i);
return;
}
});
}
},
'footable_column_data.sorting': function (e) {
var $th = $(e.column.th);
e.column.data.sort = e.column.data.sort || {};
e.column.data.sort.initial = $th.data('sort-initial') || false;
e.column.data.sort.ignore = $th.data('sort-ignore') || false;
e.column.data.sort.selector = $th.data('sort-selector') || null;
var match = $th.data('sort-match') || 0;
if (match >= e.column.data.matches.length) match = 0;
e.column.data.sort.match = e.column.data.matches[match];
}
})
//save the sort object onto the table so we can access it later
.data('footable-sort', p);
}
};
p.doSort = function(columnIndex, ascending) {
var ft = p.footable;
if ($(ft.table).data('sort') === false) return;
var $table = $(ft.table),
$tbody = $table.find('> tbody'),
column = ft.columns[columnIndex],
$th = $table.find('> thead > tr:last-child > th:eq(' + columnIndex + ')'),
cls = ft.options.classes.sort,
evt = ft.options.events.sort;
ascending = (ascending === undefined) ? $th.hasClass(cls.sorted) :
(ascending === 'toggle') ? !$th.hasClass(cls.sorted) : ascending;
if (column.sort.ignore === true) return true;
//raise a pre-sorting event so that we can cancel the sorting if needed
var event = ft.raise(evt.sorting, { column: column, direction: ascending ? 'ASC' : 'DESC' });
if (event && event.result === false) return;
$table.data('sorted', column.index);
$table.find('> thead > tr:last-child > th, > thead > tr:last-child > td').not($th).removeClass(cls.sorted + ' ' + cls.descending);
if (ascending === undefined) {
ascending = $th.hasClass(cls.sorted);
}
if (ascending) {
$th.removeClass(cls.descending).addClass(cls.sorted);
} else {
$th.removeClass(cls.sorted).addClass(cls.descending);
}
p.sort(ft, $tbody, column, ascending);
ft.bindToggleSelectors();
ft.raise(evt.sorted, { column: column, direction: ascending ? 'ASC' : 'DESC' });
};
p.rows = function (ft, tbody, column) {
var rows = [];
tbody.find('> tr').each(function () {
var $row = $(this), $next = null;
if ($row.hasClass(ft.options.classes.detail)) return true;
if ($row.next().hasClass(ft.options.classes.detail)) {
$next = $row.next().get(0);
}
var row = { 'row': $row, 'detail': $next };
if (column !== undefined) {
row.value = ft.parse(this.cells[column.sort.match], column);
}
rows.push(row);
return true;
}).detach();
return rows;
};
p.sort = function (ft, tbody, column, ascending) {
var rows = p.rows(ft, tbody, column);
var sorter = ft.options.sorters[column.type] || ft.options.sorters.alpha;
rows.sort(function (a, b) {
if (ascending) {
return sorter(a.value, b.value);
} else {
return sorter(b.value, a.value);
}
});
for (var j = 0; j < rows.length; j++) {
tbody.append(rows[j].row);
if (rows[j].detail !== null) {
tbody.append(rows[j].detail);
}
}
};
}
w.footable.plugins.register(Sort, defaults);
})(jQuery, window);