From 86c18476cd473910b0067c50b4ac730ea4e21a12 Mon Sep 17 00:00:00 2001 From: Frode Petterson Date: Wed, 15 Oct 2014 11:38:29 +0200 Subject: [PATCH] Created a new table data view from library management and library details that is more generic. Added support for finish event from H5Ps. JS now also log to results when the H5P was opened and finished. --- js/h5p-data-view.js | 126 ++++++++++++++++++++++++ js/h5p-utils.js | 222 ++++++++++++++++++++++++++++++++++++++++++- js/h5p.js | 45 ++++++++- styles/h5p-admin.css | 31 +++--- 4 files changed, 406 insertions(+), 18 deletions(-) create mode 100644 js/h5p-data-view.js diff --git a/js/h5p-data-view.js b/js/h5p-data-view.js new file mode 100644 index 0000000..e38ecd3 --- /dev/null +++ b/js/h5p-data-view.js @@ -0,0 +1,126 @@ +var H5PDataView = (function ($) { + + /** + * Initialize a new H5P data view. + * + * @param {Object} container + * @param {String} source URL for data + * @param {Array} headers for data + * @param {Object} l10n translations + */ + function H5PDataView(container, source, headers, l10n, classes) { + var self = this; + + self.$container = $(container).addClass('h5p-data-view').html(''); + H5PUtils.throbber(l10n.loading).appendTo(self.$container); + + self.source = source; + self.headers = headers; + self.l10n = l10n; + self.classes = (classes === undefined ? {} : classes); + self.limit = 20; + + self.loadData(); + } + + /** + * Load data for view. + * + * @param {Number} offset data collection offset + */ + H5PDataView.prototype.loadData = function (offset) { + var self = this; + + // Create URL + var url = self.source; + if (offset !== undefined) { + url += (url.indexOf('?') === -1 ? '?' : '&') + 'offset=' + offset + '&limit=' + self.limit; + } + + // Fire ajax request + $.ajax({ + dataType: 'json', + cache: true, + url: url + }).fail(function () { + // Error handling + self.setMessage(self.l10n.ajaxFailed); + }).done(function (data) { + if (!data.rows.length) { + self.setMessage(self.l10n.noData); + } + else { + // Update table data + self.updateTable(data.rows); + } + + // Update pagination widget + self.updatePagination(data.num); + }); + }; + + /** + * Display the given message to the user. + * + * @param {String} message + */ + H5PDataView.prototype.setMessage = function (message) { + var self = this; + + var $message = $('

', { + text: message + }); + if (self.table === undefined) { + self.$container.children().replaceWith($message); + } + else { + self.table.setBody($('

', {text: message})); + } + }; + + /** + * Update table data. + * + * @param {Array} rows + */ + H5PDataView.prototype.updateTable = function (rows) { + var self = this; + + if (self.table === undefined) { + // Create new table + self.table = new H5PUtils.Table(self.classes, self.headers); + self.table.appendTo(self.$container.html('')); + } + + // Add/update rows + self.table.setRows(rows); + }; + + /** + * Update pagination widget. + * + * @param {Number} num size of data collection + */ + H5PDataView.prototype.updatePagination = function (num) { + var self = this; + + if (self.pagination === undefined) { + // Create new widget + var $pagerContainer = $('

', {'class': 'h5p-pagination'}); + self.pagination = new H5PUtils.Pagination(num, self.limit, function (offset) { + // Handle page changes in pagination widget + self.table.setBody(H5PUtils.throbber(self.l10n.loading)); + self.loadData(offset); + }, self.l10n); + + self.pagination.appendTo($pagerContainer); + self.table.setFoot($pagerContainer); + } + else { + // Update existing widget + self.pagination.update(num, self.limit); + } + }; + + return H5PDataView; +})(H5P.jQuery); diff --git a/js/h5p-utils.js b/js/h5p-utils.js index 0db73a7..6ef61ad 100644 --- a/js/h5p-utils.js +++ b/js/h5p-utils.js @@ -64,7 +64,7 @@ var H5PUtils = H5PUtils || {}; return $field; }; - + /** * Replaces placeholder fields in translation strings * @@ -130,4 +130,224 @@ var H5PUtils = H5PUtils || {}; return $container; }; + /** + * Generic table class with useful helpers. + * + * @param {Object} classes to use for styling + * @param {Array} cols headers + */ + H5PUtils.Table = function (classes, cols) { + // Create basic table + var tableOptions = {}; + if (classes.table !== undefined) { + tableOptions['class'] = classes.table; + } + 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++) { + $(''); + + for (var i = 0; i < rows.length; i++) { + var $tr = $('').appendTo($newTbody); + + for (var j = 0; j < rows[i].length; j++) { + $(''); + var $tr = $('').appendTo($newTbody); + $(''); + var $tr = $('').appendTo($newTfoot); + $('
', { + html: cols[i] + }).appendTo($tr); + } + + /** + * Public. + * + * @param {Array} rows with cols + */ + this.setRows = function (rows) { + var $newTbody = $('
', { + html: rows[i][j] + }).appendTo($tr); + } + } + + $tbody.replaceWith($newTbody); + $tbody = $newTbody; + }; + + /** + * Public. + * + * @param {jQuery} $content custom + */ + this.setBody = function ($content) { + var $newTbody = $('
', { + colspan: cols.length + }).append($content).appendTo($tr); + $tbody.replaceWith($newTbody); + $tbody = $newTbody; + }; + + /** + * Public. + * + * @param {jQuery} $content custom + */ + this.setFoot = function ($content) { + var $newTfoot = $('
', { + colspan: cols.length + }).append($content).appendTo($tr); + $tfoot.replaceWith($newTfoot); + }; + + + /** + * Public. + * + * @param {jQuery} $container + */ + this.appendTo = function ($container) { + $table.appendTo($container); + }; + }; + + /** + * Generic pagination class. + * + * @param {Number} num total items + * @param {Number} limit items per page + * @param {Function} goneTo page callback + */ + H5PUtils.Pagination = function (num, limit, goneTo, l10n) { + var current = 0; + var pages = Math.ceil(num / limit); + + // Create components + + // Previous button + var $left = $('