diff --git a/js/h5p-data-view.js b/js/h5p-data-view.js
index 54c8c87..255d1f2 100644
--- a/js/h5p-data-view.js
+++ b/js/h5p-data-view.js
@@ -41,6 +41,11 @@ var H5PDataView = (function ($) {
var url = self.source;
url += (url.indexOf('?') === -1 ? '?' : '&') + 'offset=' + self.offset + '&limit=' + self.limit;
+ // Add sorting
+ if (self.sortBy !== undefined && self.sortDir !== undefined) {
+ url += '&sortBy=' + self.sortBy + '&sortDir=' + self.sortDir;
+ }
+
// Add filters
for (var i = 0; i < self.filterOn.length; i++) {
if (self.filterOn[i] === undefined) {
@@ -106,6 +111,12 @@ var H5PDataView = (function ($) {
// Create new table
self.table = new H5PUtils.Table(self.classes, self.headers);
+ self.table.setHeaders(self.headers, function (col, dir) {
+ // Sorting column or direction has changed callback.
+ self.sortBy = col;
+ self.sortDir = dir;
+ self.loadData();
+ });
self.table.appendTo(self.$container);
}
diff --git a/js/h5p-utils.js b/js/h5p-utils.js
index 7fac307..a25cab1 100644
--- a/js/h5p-utils.js
+++ b/js/h5p-utils.js
@@ -133,27 +133,117 @@ var H5PUtils = H5PUtils || {};
/**
* Generic table class with useful helpers.
*
+ * @class
* @param {Object} classes to use for styling
* @param {Array} cols headers
*/
- H5PUtils.Table = function (classes, cols) {
+ H5PUtils.Table = function (classes) {
// Create basic table
var tableOptions = {};
if (classes.table !== undefined) {
tableOptions['class'] = classes.table;
}
+ var numCols;
+ var sortByCol;
+ var $sortCol;
+ var sortCol;
+ var sortDir;
+
var $table = $('
', tableOptions);
var $thead = $('').appendTo($table);
var $tfoot = $('').appendTo($table);
var $tbody = $('').appendTo($table);
- // Set cols - create header
- var $tr = $('
').appendTo($thead);
- for (var i = 0; i < cols.length; i++) {
- $('', {
- html: cols[i]
- }).appendTo($tr);
- }
+ /**
+ * Add columns to given table row.
+ *
+ * @private
+ *
+ */
+ var addCol = function ($tr, col, id) {
+ var options = {
+ on: {}
+ };
+
+ if (!(col instanceof Object)) {
+ options.text = col;
+ }
+ else {
+ options.text = col.text;
+
+ if (sortByCol !== undefined && col.sortable === true) {
+ // Make sortable
+ options.role = 'button';
+ options.tabIndex = 1;
+
+ // This is the first sortable column, use as default sort
+ if (sortCol === undefined) {
+ sortCol = id;
+ sortDir = 0;
+ options['class'] = 'h5p-sort';
+ }
+
+ options.on.click = function () {
+ sort($th, id);
+ };
+ }
+ }
+
+ // Append
+ var $th = $(' | ', options).appendTo($tr);
+ if (sortCol === id) {
+ $sortCol = $th; // Default sort column
+ }
+ };
+
+ /**
+ * @private
+ */
+ var sort = function ($th, id) {
+ if (id === sortCol) {
+ // Change sorting direction
+ if (sortDir === 0) {
+ sortDir = 1;
+ $th.addClass('h5p-reverse');
+ }
+ else {
+ sortDir = 0;
+ $th.removeClass('h5p-reverse');
+ }
+ }
+ else {
+ // Change sorting column
+ $sortCol.removeClass('h5p-sort').removeClass('h5p-reverse');
+ $sortCol = $th.addClass('h5p-sort');
+ sortCol = id;
+ sortDir = 0;
+ }
+
+ sortByCol(sortCol, sortDir);
+ };
+
+ /**
+ * Set headers
+ *
+ * @public
+ * @param {Array} cols
+ * @param {Function} sort callback when sorting changes
+ */
+ this.setHeaders = function (cols, sort) {
+ numCols = cols.length;
+ sortByCol = sort;
+
+ // Create new head
+ var $newThead = $('');
+ var $tr = $(' |
').appendTo($newThead);
+ for (var i = 0; i < cols.length; i++) {
+ addCol($tr, cols[i], i);
+ }
+
+ // Update DOM
+ $thead.replaceWith($newThead);
+ $thead = $newThead;
+ };
/**
* Public.
@@ -186,7 +276,7 @@ var H5PUtils = H5PUtils || {};
var $newTbody = $('');
var $tr = $('
').appendTo($newTbody);
$('', {
- colspan: cols.length
+ colspan: numCols
}).append($content).appendTo($tr);
$tbody.replaceWith($newTbody);
$tbody = $newTbody;
@@ -201,7 +291,7 @@ var H5PUtils = H5PUtils || {};
var $newTfoot = $(' | ');
var $tr = $('
').appendTo($newTfoot);
$('', {
- colspan: cols.length
+ colspan: numCols
}).append($content).appendTo($tr);
$tfoot.replaceWith($newTfoot);
};
diff --git a/styles/h5p-admin.css b/styles/h5p-admin.css
index d704aa1..ed9d744 100644
--- a/styles/h5p-admin.css
+++ b/styles/h5p-admin.css
@@ -258,3 +258,24 @@ button.h5p-admin.disabled:hover {
.h5p-data-view input[type="text"] {
margin-bottom: 0.5em;
}
+.h5p-data-view th[role="button"] {
+ cursor: pointer;
+}
+.h5p-data-view th[role="button"].h5p-sort:after,
+.h5p-data-view th[role="button"]:hover:after,
+.h5p-data-view th[role="button"].h5p-sort.h5p-reverse:hover:after {
+ content: "\25BE";
+ position: relative;
+ left: 0.5em;
+ top: -1px;
+}
+.h5p-data-view th[role="button"].h5p-sort.h5p-reverse:after,
+.h5p-data-view th[role="button"].h5p-sort:hover:after {
+ content: "\25B4";
+ top: -2px;
+}
+.h5p-data-view th[role="button"]:hover:after,
+.h5p-data-view th[role="button"].h5p-sort.h5p-reverse:hover:after,
+.h5p-data-view th[role="button"].h5p-sort:hover:after {
+ color: #999;
+}
|