Added support for Tags in data views

HFJ-1620
pull/17/head
Frode Petterson 2016-02-29 16:35:07 +01:00
parent dc8b70748f
commit a398589c80
3 changed files with 186 additions and 10 deletions

View File

@ -50,14 +50,13 @@ var H5PDataView = (function ($) {
self.limit = 20; self.limit = 20;
self.offset = 0; self.offset = 0;
self.filterOn = []; self.filterOn = [];
self.facets = {};
self.loadData(); self.loadData();
} }
/** /**
* Load data from source URL. * Load data from source URL.
*
* @public
*/ */
H5PDataView.prototype.loadData = function () { H5PDataView.prototype.loadData = function () {
var self = this; var self = this;
@ -85,6 +84,22 @@ var H5PDataView = (function ($) {
url += '&filters[' + i + ']=' + encodeURIComponent(self.filterOn[i]); url += '&filters[' + i + ']=' + encodeURIComponent(self.filterOn[i]);
} }
// Add facets
for (var col in self.facets) {
if (!self.facets.hasOwnProperty(col)) {
continue;
}
var facets = self.facets[col];
for (var facet in facets) {
if (!facets.hasOwnProperty(facet)) {
continue;
}
url += '&facets[' + col + '][]=' + facet;
}
}
// Fire ajax request // Fire ajax request
$.ajax({ $.ajax({
dataType: 'json', dataType: 'json',
@ -114,7 +129,6 @@ var H5PDataView = (function ($) {
/** /**
* Display the given message to the user. * Display the given message to the user.
* *
* @public
* @param {jQuery} $message wrapper with message * @param {jQuery} $message wrapper with message
*/ */
H5PDataView.prototype.setMessage = function ($message) { H5PDataView.prototype.setMessage = function ($message) {
@ -131,7 +145,6 @@ var H5PDataView = (function ($) {
/** /**
* Update table data. * Update table data.
* *
* @public
* @param {Array} rows * @param {Array} rows
*/ */
H5PDataView.prototype.updateTable = function (rows) { H5PDataView.prototype.updateTable = function (rows) {
@ -144,6 +157,12 @@ var H5PDataView = (function ($) {
// Add filters // Add filters
self.addFilters(); self.addFilters();
// Add facets
self.$facets = $('<div/>', {
'class': 'h5p-facet-wrapper',
appendTo: self.$container
});
// Create new table // Create new table
self.table = new H5PUtils.Table(self.classes, self.headers); self.table = new H5PUtils.Table(self.classes, self.headers);
self.table.setHeaders(self.headers, function (order) { self.table.setHeaders(self.headers, function (order) {
@ -154,14 +173,119 @@ var H5PDataView = (function ($) {
self.table.appendTo(self.$container); self.table.appendTo(self.$container);
} }
// Process cell data before updating table
for (var i = 0; i < self.headers.length; i++) {
if (self.headers[i].facet === true) {
// Process rows for col, expect object or array
for (var j = 0; j < rows.length; j++) {
rows[j][i] = self.createFacets(rows[j][i], i);
}
}
}
// Add/update rows // Add/update rows
self.table.setRows(rows); var $tbody = self.table.setRows(rows);
// Add event handlers for facets
$('.h5p-facet', $tbody).click(function () {
var $facet = $(this);
self.filterByFacet($facet.data('col'), $facet.data('id'), $facet.text());
}).keypress(function (event) {
if (event.which === 32) {
var $facet = $(this);
self.filterByFacet($facet.data('col'), $facet.data('id'), $facet.text());
}
});
};
/**
* Create button for adding facet to filter.
*
* @param (object|Array) input
* @param number col ID of column
*/
H5PDataView.prototype.createFacets = function (input, col) {
var self = this;
var facets = '';
if (input instanceof Array) {
// Facet can be filtered on multiple values at the same time
for (var i = 0; i < input.length; i++) {
if (facets !== '') {
facets += ', ';
}
facets += '<span class="h5p-facet" role="button" tabindex="0" data-id="' + input[i].id + '" data-col="' + col + '">' + input[i].title + '</span>';
}
}
else {
// Single value facet filtering
facets += '<span class="h5p-facet" role="button" tabindex="0" data-id="' + input.id + '" data-col="' + col + '">' + input.title + '</span>';
}
return facets;
};
/**
* Adds a filter based on the given facet.
*
* @param number col ID of column we're filtering
* @param number id ID to filter on
* @param string text Human readable label for the filter
*/
H5PDataView.prototype.filterByFacet = function (col, id, text) {
var self = this;
if (self.facets[col] === undefined) {
self.facets[col] = {};
}
// Only add if it isn't already added
if (self.facets[col][id] === undefined) {
self.facets[col][id] = text;
// Add to UI
var $tag = $('<span/>', {
'class': 'h5p-facet-tag',
text: text,
appendTo: self.$facets,
});
/**
* Callback for removing filter
*
* @private
*/
var remove = function () {
delete self.facets[col][id];
$tag.remove();
self.loadData();
};
// Remove button
$('<span/>', {
role: 'button',
tabindex: 0,
appendTo: $tag,
text: self.l10n.remove,
title: self.l10n.remove,
on: {
click: remove,
keypress: function (event) {
if (event.which === 32) {
remove();
}
}
}
});
// Load data with new filter
self.loadData();
}
}; };
/** /**
* Update pagination widget. * Update pagination widget.
* *
* @public
* @param {Number} num size of data collection * @param {Number} num size of data collection
*/ */
H5PDataView.prototype.updatePagination = function (num) { H5PDataView.prototype.updatePagination = function (num) {
@ -187,8 +311,6 @@ var H5PDataView = (function ($) {
/** /**
* Add filters. * Add filters.
*
* @public
*/ */
H5PDataView.prototype.addFilters = function () { H5PDataView.prototype.addFilters = function () {
var self = this; var self = this;
@ -203,8 +325,7 @@ var H5PDataView = (function ($) {
/** /**
* Add text filter for given col num. * Add text filter for given col num.
*
* @public
* @param {Number} col * @param {Number} col
*/ */
H5PDataView.prototype.addTextFilter = function (col) { H5PDataView.prototype.addTextFilter = function (col) {

View File

@ -303,6 +303,8 @@ var H5PUtils = H5PUtils || {};
$tbody.replaceWith($newTbody); $tbody.replaceWith($newTbody);
$tbody = $newTbody; $tbody = $newTbody;
return $tbody;
}; };
/** /**

View File

@ -257,6 +257,8 @@ button.h5p-admin.disabled:hover {
} }
.h5p-data-view input[type="text"] { .h5p-data-view input[type="text"] {
margin-bottom: 0.5em; margin-bottom: 0.5em;
float: left;
margin-right: 10px;
} }
.h5p-data-view input[type="text"]::-ms-clear { .h5p-data-view input[type="text"]::-ms-clear {
display: none; display: none;
@ -283,3 +285,54 @@ button.h5p-admin.disabled:hover {
.h5p-data-view th[role="button"].h5p-sort:hover:after { .h5p-data-view th[role="button"].h5p-sort:hover:after {
color: #999; color: #999;
} }
.h5p-data-view .h5p-facet {
cursor: pointer;
color: #0073aa;
outline: none;
}
.h5p-data-view .h5p-facet:hover,
.h5p-data-view .h5p-facet:active {
color: #00a0d2;
}
.h5p-data-view .h5p-facet:focus {
color: #124964;
box-shadow: 0 0 0 1px #5b9dd9,0 0 2px 1px rgba(30,140,190,.8);
}
.h5p-data-view .h5p-facet-wrapper {
line-height: 27px;
}
.h5p-data-view .h5p-facet-tag {
margin-left: 10px;
background: #e8e8e8;
border: 1px solid #cbcbcc;
border-radius: 5px;
color: #5d5d5d;
padding: 0 24px 0 10px;
display: inline-block;
position: relative;
}
.h5p-data-view .h5p-facet-tag > span {
position: absolute;
right: 0;
top: auto;
bottom: auto;
font-size: 18px;
color: #a2a2a2;
outline: none;
width: 21px;
text-indent: 4px;
letter-spacing: 10px;
overflow: hidden;
cursor: pointer;
}
.h5p-data-view .h5p-facet-tag > span:before {
content: "×";
font-weight: bold;
}
.h5p-data-view .h5p-facet-tag > span:hover,
.h5p-data-view .h5p-facet-tag > span:focus {
color: #a20000;
}
.h5p-data-view .h5p-facet-tag > span:active {
color: #d20000;
}