1 |
efrain |
1 |
/* global H5PAdminIntegration H5PUtils */
|
|
|
2 |
var H5PLibraryDetails = H5PLibraryDetails || {};
|
|
|
3 |
|
|
|
4 |
(function ($) {
|
|
|
5 |
|
|
|
6 |
H5PLibraryDetails.PAGER_SIZE = 20;
|
|
|
7 |
/**
|
|
|
8 |
* Initializing
|
|
|
9 |
*/
|
|
|
10 |
H5PLibraryDetails.init = function () {
|
|
|
11 |
H5PLibraryDetails.$adminContainer = H5P.jQuery(H5PAdminIntegration.containerSelector);
|
|
|
12 |
H5PLibraryDetails.library = H5PAdminIntegration.libraryInfo;
|
|
|
13 |
|
|
|
14 |
// currentContent holds the current list if data (relevant for filtering)
|
|
|
15 |
H5PLibraryDetails.currentContent = H5PLibraryDetails.library.content;
|
|
|
16 |
|
|
|
17 |
// The current page index (for pager)
|
|
|
18 |
H5PLibraryDetails.currentPage = 0;
|
|
|
19 |
|
|
|
20 |
// The current filter
|
|
|
21 |
H5PLibraryDetails.currentFilter = '';
|
|
|
22 |
|
|
|
23 |
// We cache the filtered results, so we don't have to do unneccessary searches
|
|
|
24 |
H5PLibraryDetails.filterCache = [];
|
|
|
25 |
|
|
|
26 |
// Append library info
|
|
|
27 |
H5PLibraryDetails.$adminContainer.append(H5PLibraryDetails.createLibraryInfo());
|
|
|
28 |
|
|
|
29 |
// Append node list
|
|
|
30 |
H5PLibraryDetails.$adminContainer.append(H5PLibraryDetails.createContentElement());
|
|
|
31 |
};
|
|
|
32 |
|
|
|
33 |
/**
|
|
|
34 |
* Create the library details view
|
|
|
35 |
*/
|
|
|
36 |
H5PLibraryDetails.createLibraryInfo = function () {
|
|
|
37 |
var $libraryInfo = $('<div class="h5p-library-info"></div>');
|
|
|
38 |
|
|
|
39 |
$.each(H5PLibraryDetails.library.info, function (title, value) {
|
|
|
40 |
$libraryInfo.append(H5PUtils.createLabeledField(title, value));
|
|
|
41 |
});
|
|
|
42 |
|
|
|
43 |
return $libraryInfo;
|
|
|
44 |
};
|
|
|
45 |
|
|
|
46 |
/**
|
|
|
47 |
* Create the content list with searching and paging
|
|
|
48 |
*/
|
|
|
49 |
H5PLibraryDetails.createContentElement = function () {
|
|
|
50 |
if (H5PLibraryDetails.library.notCached !== undefined) {
|
|
|
51 |
return H5PUtils.getRebuildCache(H5PLibraryDetails.library.notCached);
|
|
|
52 |
}
|
|
|
53 |
|
|
|
54 |
if (H5PLibraryDetails.currentContent === undefined) {
|
|
|
55 |
H5PLibraryDetails.$content = $('<div class="h5p-content empty">' + H5PLibraryDetails.library.translations.noContent + '</div>');
|
|
|
56 |
}
|
|
|
57 |
else {
|
|
|
58 |
H5PLibraryDetails.$content = $('<div class="h5p-content"><h3>' + H5PLibraryDetails.library.translations.contentHeader + '</h3></div>');
|
|
|
59 |
H5PLibraryDetails.createSearchElement();
|
|
|
60 |
H5PLibraryDetails.createPageSizeSelector();
|
|
|
61 |
H5PLibraryDetails.createContentTable();
|
|
|
62 |
H5PLibraryDetails.createPagerElement();
|
|
|
63 |
return H5PLibraryDetails.$content;
|
|
|
64 |
}
|
|
|
65 |
};
|
|
|
66 |
|
|
|
67 |
/**
|
|
|
68 |
* Creates the content list
|
|
|
69 |
*/
|
|
|
70 |
H5PLibraryDetails.createContentTable = function () {
|
|
|
71 |
// Remove it if it exists:
|
|
|
72 |
if (H5PLibraryDetails.$contentTable) {
|
|
|
73 |
H5PLibraryDetails.$contentTable.remove();
|
|
|
74 |
}
|
|
|
75 |
|
|
|
76 |
H5PLibraryDetails.$contentTable = H5PUtils.createTable();
|
|
|
77 |
|
|
|
78 |
var i = (H5PLibraryDetails.currentPage*H5PLibraryDetails.PAGER_SIZE);
|
|
|
79 |
var lastIndex = (i+H5PLibraryDetails.PAGER_SIZE);
|
|
|
80 |
|
|
|
81 |
if (lastIndex > H5PLibraryDetails.currentContent.length) {
|
|
|
82 |
lastIndex = H5PLibraryDetails.currentContent.length;
|
|
|
83 |
}
|
|
|
84 |
for (; i<lastIndex; i++) {
|
|
|
85 |
var content = H5PLibraryDetails.currentContent[i];
|
|
|
86 |
H5PLibraryDetails.$contentTable.append(H5PUtils.createTableRow(['<a href="' + content.url + '">' + content.title + '</a>']));
|
|
|
87 |
}
|
|
|
88 |
|
|
|
89 |
// Appends it to the browser DOM
|
|
|
90 |
H5PLibraryDetails.$contentTable.insertAfter(H5PLibraryDetails.$search);
|
|
|
91 |
};
|
|
|
92 |
|
|
|
93 |
/**
|
|
|
94 |
* Creates the pager element on the bottom of the list
|
|
|
95 |
*/
|
|
|
96 |
H5PLibraryDetails.createPagerElement = function () {
|
|
|
97 |
H5PLibraryDetails.$previous = $('<button type="button" class="previous h5p-admin"><</button>');
|
|
|
98 |
H5PLibraryDetails.$next = $('<button type="button" class="next h5p-admin">></button>');
|
|
|
99 |
|
|
|
100 |
H5PLibraryDetails.$previous.on('click', function () {
|
|
|
101 |
if (H5PLibraryDetails.$previous.hasClass('disabled')) {
|
|
|
102 |
return;
|
|
|
103 |
}
|
|
|
104 |
|
|
|
105 |
H5PLibraryDetails.currentPage--;
|
|
|
106 |
H5PLibraryDetails.updatePager();
|
|
|
107 |
H5PLibraryDetails.createContentTable();
|
|
|
108 |
});
|
|
|
109 |
|
|
|
110 |
H5PLibraryDetails.$next.on('click', function () {
|
|
|
111 |
if (H5PLibraryDetails.$next.hasClass('disabled')) {
|
|
|
112 |
return;
|
|
|
113 |
}
|
|
|
114 |
|
|
|
115 |
H5PLibraryDetails.currentPage++;
|
|
|
116 |
H5PLibraryDetails.updatePager();
|
|
|
117 |
H5PLibraryDetails.createContentTable();
|
|
|
118 |
});
|
|
|
119 |
|
|
|
120 |
// This is the Page x of y widget:
|
|
|
121 |
H5PLibraryDetails.$pagerInfo = $('<span class="pager-info"></span>');
|
|
|
122 |
|
|
|
123 |
H5PLibraryDetails.$pager = $('<div class="h5p-content-pager"></div>').append(H5PLibraryDetails.$previous, H5PLibraryDetails.$pagerInfo, H5PLibraryDetails.$next);
|
|
|
124 |
H5PLibraryDetails.$content.append(H5PLibraryDetails.$pager);
|
|
|
125 |
|
|
|
126 |
H5PLibraryDetails.$pagerInfo.on('click', function () {
|
|
|
127 |
var width = H5PLibraryDetails.$pagerInfo.innerWidth();
|
|
|
128 |
H5PLibraryDetails.$pagerInfo.hide();
|
|
|
129 |
|
|
|
130 |
// User has updated the pageNumber
|
|
|
131 |
var pageNumerUpdated = function () {
|
|
|
132 |
var newPageNum = $gotoInput.val()-1;
|
|
|
133 |
var intRegex = /^\d+$/;
|
|
|
134 |
|
|
|
135 |
$goto.remove();
|
|
|
136 |
H5PLibraryDetails.$pagerInfo.css({display: 'inline-block'});
|
|
|
137 |
|
|
|
138 |
// Check if input value is valid, and that it has actually changed
|
|
|
139 |
if (!(intRegex.test(newPageNum) && newPageNum >= 0 && newPageNum < H5PLibraryDetails.getNumPages() && newPageNum != H5PLibraryDetails.currentPage)) {
|
|
|
140 |
return;
|
|
|
141 |
}
|
|
|
142 |
|
|
|
143 |
H5PLibraryDetails.currentPage = newPageNum;
|
|
|
144 |
H5PLibraryDetails.updatePager();
|
|
|
145 |
H5PLibraryDetails.createContentTable();
|
|
|
146 |
};
|
|
|
147 |
|
|
|
148 |
// We create an input box where the user may type in the page number
|
|
|
149 |
// he wants to be displayed.
|
|
|
150 |
// Reson for doing this is when user has ten-thousands of elements in list,
|
|
|
151 |
// this is the easiest way of getting to a specified page
|
|
|
152 |
var $gotoInput = $('<input/>', {
|
|
|
153 |
type: 'number',
|
|
|
154 |
min : 1,
|
|
|
155 |
max: H5PLibraryDetails.getNumPages(),
|
|
|
156 |
on: {
|
|
|
157 |
// Listen to blur, and the enter-key:
|
|
|
158 |
'blur': pageNumerUpdated,
|
|
|
159 |
'keyup': function (event) {
|
|
|
160 |
if (event.keyCode === 13) {
|
|
|
161 |
pageNumerUpdated();
|
|
|
162 |
}
|
|
|
163 |
}
|
|
|
164 |
}
|
|
|
165 |
}).css({width: width});
|
|
|
166 |
var $goto = $('<span/>', {
|
|
|
167 |
'class': 'h5p-pager-goto'
|
|
|
168 |
}).css({width: width}).append($gotoInput).insertAfter(H5PLibraryDetails.$pagerInfo);
|
|
|
169 |
|
|
|
170 |
$gotoInput.focus();
|
|
|
171 |
});
|
|
|
172 |
|
|
|
173 |
H5PLibraryDetails.updatePager();
|
|
|
174 |
};
|
|
|
175 |
|
|
|
176 |
/**
|
|
|
177 |
* Calculates number of pages
|
|
|
178 |
*/
|
|
|
179 |
H5PLibraryDetails.getNumPages = function () {
|
|
|
180 |
return Math.ceil(H5PLibraryDetails.currentContent.length / H5PLibraryDetails.PAGER_SIZE);
|
|
|
181 |
};
|
|
|
182 |
|
|
|
183 |
/**
|
|
|
184 |
* Update the pager text, and enables/disables the next and previous buttons as needed
|
|
|
185 |
*/
|
|
|
186 |
H5PLibraryDetails.updatePager = function () {
|
|
|
187 |
H5PLibraryDetails.$pagerInfo.css({display: 'inline-block'});
|
|
|
188 |
|
|
|
189 |
if (H5PLibraryDetails.getNumPages() > 0) {
|
|
|
190 |
var message = H5PUtils.translateReplace(H5PLibraryDetails.library.translations.pageXOfY, {
|
|
|
191 |
'$x': (H5PLibraryDetails.currentPage+1),
|
|
|
192 |
'$y': H5PLibraryDetails.getNumPages()
|
|
|
193 |
});
|
|
|
194 |
H5PLibraryDetails.$pagerInfo.html(message);
|
|
|
195 |
}
|
|
|
196 |
else {
|
|
|
197 |
H5PLibraryDetails.$pagerInfo.html('');
|
|
|
198 |
}
|
|
|
199 |
|
|
|
200 |
H5PLibraryDetails.$previous.toggleClass('disabled', H5PLibraryDetails.currentPage <= 0);
|
|
|
201 |
H5PLibraryDetails.$next.toggleClass('disabled', H5PLibraryDetails.currentContent.length < (H5PLibraryDetails.currentPage+1)*H5PLibraryDetails.PAGER_SIZE);
|
|
|
202 |
};
|
|
|
203 |
|
|
|
204 |
/**
|
|
|
205 |
* Creates the search element
|
|
|
206 |
*/
|
|
|
207 |
H5PLibraryDetails.createSearchElement = function () {
|
|
|
208 |
|
|
|
209 |
H5PLibraryDetails.$search = $('<div class="h5p-content-search"><input placeholder="' + H5PLibraryDetails.library.translations.filterPlaceholder + '" type="search"></div>');
|
|
|
210 |
|
|
|
211 |
var performSeach = function () {
|
|
|
212 |
var searchString = $('.h5p-content-search > input').val();
|
|
|
213 |
|
|
|
214 |
// If search string same as previous, just do nothing
|
|
|
215 |
if (H5PLibraryDetails.currentFilter === searchString) {
|
|
|
216 |
return;
|
|
|
217 |
}
|
|
|
218 |
|
|
|
219 |
if (searchString.trim().length === 0) {
|
|
|
220 |
// If empty search, use the complete list
|
|
|
221 |
H5PLibraryDetails.currentContent = H5PLibraryDetails.library.content;
|
|
|
222 |
}
|
|
|
223 |
else if (H5PLibraryDetails.filterCache[searchString]) {
|
|
|
224 |
// If search is cached, no need to filter
|
|
|
225 |
H5PLibraryDetails.currentContent = H5PLibraryDetails.filterCache[searchString];
|
|
|
226 |
}
|
|
|
227 |
else {
|
|
|
228 |
var listToFilter = H5PLibraryDetails.library.content;
|
|
|
229 |
|
|
|
230 |
// Check if we can filter the already filtered results (for performance)
|
|
|
231 |
if (searchString.length > 1 && H5PLibraryDetails.currentFilter === searchString.substr(0, H5PLibraryDetails.currentFilter.length)) {
|
|
|
232 |
listToFilter = H5PLibraryDetails.currentContent;
|
|
|
233 |
}
|
|
|
234 |
H5PLibraryDetails.currentContent = $.grep(listToFilter, function (content) {
|
|
|
235 |
return content.title && content.title.match(new RegExp(searchString, 'i'));
|
|
|
236 |
});
|
|
|
237 |
}
|
|
|
238 |
|
|
|
239 |
H5PLibraryDetails.currentFilter = searchString;
|
|
|
240 |
// Cache the current result
|
|
|
241 |
H5PLibraryDetails.filterCache[searchString] = H5PLibraryDetails.currentContent;
|
|
|
242 |
H5PLibraryDetails.currentPage = 0;
|
|
|
243 |
H5PLibraryDetails.createContentTable();
|
|
|
244 |
|
|
|
245 |
// Display search results:
|
|
|
246 |
if (H5PLibraryDetails.$searchResults) {
|
|
|
247 |
H5PLibraryDetails.$searchResults.remove();
|
|
|
248 |
}
|
|
|
249 |
if (searchString.trim().length > 0) {
|
|
|
250 |
H5PLibraryDetails.$searchResults = $('<span class="h5p-admin-search-results">' + H5PLibraryDetails.currentContent.length + ' hits on ' + H5PLibraryDetails.currentFilter + '</span>');
|
|
|
251 |
H5PLibraryDetails.$search.append(H5PLibraryDetails.$searchResults);
|
|
|
252 |
}
|
|
|
253 |
H5PLibraryDetails.updatePager();
|
|
|
254 |
};
|
|
|
255 |
|
|
|
256 |
var inputTimer;
|
|
|
257 |
$('input', H5PLibraryDetails.$search).on('change keypress paste input', function () {
|
|
|
258 |
// Here we start the filtering
|
|
|
259 |
// We wait at least 500 ms after last input to perform search
|
|
|
260 |
if (inputTimer) {
|
|
|
261 |
clearTimeout(inputTimer);
|
|
|
262 |
}
|
|
|
263 |
|
|
|
264 |
inputTimer = setTimeout( function () {
|
|
|
265 |
performSeach();
|
|
|
266 |
}, 500);
|
|
|
267 |
});
|
|
|
268 |
|
|
|
269 |
H5PLibraryDetails.$content.append(H5PLibraryDetails.$search);
|
|
|
270 |
};
|
|
|
271 |
|
|
|
272 |
/**
|
|
|
273 |
* Creates the page size selector
|
|
|
274 |
*/
|
|
|
275 |
H5PLibraryDetails.createPageSizeSelector = function () {
|
|
|
276 |
H5PLibraryDetails.$search.append('<div class="h5p-admin-pager-size-selector">' + H5PLibraryDetails.library.translations.pageSizeSelectorLabel + ':<span data-page-size="10">10</span><span class="selected" data-page-size="20">20</span><span data-page-size="50">50</span><span data-page-size="100">100</span><span data-page-size="200">200</span></div>');
|
|
|
277 |
|
|
|
278 |
// Listen to clicks on the page size selector:
|
|
|
279 |
$('.h5p-admin-pager-size-selector > span', H5PLibraryDetails.$search).on('click', function () {
|
|
|
280 |
H5PLibraryDetails.PAGER_SIZE = $(this).data('page-size');
|
|
|
281 |
$('.h5p-admin-pager-size-selector > span', H5PLibraryDetails.$search).removeClass('selected');
|
|
|
282 |
$(this).addClass('selected');
|
|
|
283 |
H5PLibraryDetails.currentPage = 0;
|
|
|
284 |
H5PLibraryDetails.createContentTable();
|
|
|
285 |
H5PLibraryDetails.updatePager();
|
|
|
286 |
});
|
|
|
287 |
};
|
|
|
288 |
|
|
|
289 |
// Initialize me:
|
|
|
290 |
$(document).ready(function () {
|
|
|
291 |
if (!H5PLibraryDetails.initialized) {
|
|
|
292 |
H5PLibraryDetails.initialized = true;
|
|
|
293 |
H5PLibraryDetails.init();
|
|
|
294 |
}
|
|
|
295 |
});
|
|
|
296 |
|
|
|
297 |
})(H5P.jQuery);
|