191 lines
8.0 KiB
JavaScript
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);
|