1 // This file is part of Moodle - http://moodle.org/
3 // Moodle is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
8 // Moodle is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17 * Content bank UI actions.
19 * @module core_contentbank/sort
20 * @package core_contentbank
21 * @copyright 2020 Bas Brands <bas@moodle.com>
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 import selectors from './selectors';
26 import {get_string as getString} from 'core/str';
27 import Prefetch from 'core/prefetch';
28 import Ajax from 'core/ajax';
29 import Notification from 'core/notification';
32 * Set up the contentbank views.
36 export const init = () => {
37 const contentBank = document.querySelector(selectors.regions.contentbank);
38 Prefetch.prefetchStrings('contentbank', ['sortbyx', 'sortbyxreverse', 'contentname',
39 'lastmodified', 'size', 'type']);
40 registerListenerEvents(contentBank);
44 * Register contentbank related event listeners.
46 * @method registerListenerEvents
47 * @param {HTMLElement} contentBank The DOM node of the content bank
49 const registerListenerEvents = (contentBank) => {
52 const fileArea = document.querySelector(selectors.regions.filearea);
53 const shownItems = fileArea.querySelectorAll(selectors.elements.listitem);
56 const viewGrid = contentBank.querySelector(selectors.actions.viewgrid);
57 const viewList = contentBank.querySelector(selectors.actions.viewlist);
59 viewGrid.addEventListener('click', () => {
60 contentBank.classList.remove('view-list');
61 contentBank.classList.add('view-grid');
62 viewGrid.classList.add('active');
63 viewList.classList.remove('active');
64 setViewListPreference(false);
67 viewList.addEventListener('click', () => {
68 contentBank.classList.remove('view-grid');
69 contentBank.classList.add('view-list');
70 viewList.classList.add('active');
71 viewGrid.classList.remove('active');
72 setViewListPreference(true);
75 // Sort by file name alphabetical
76 const sortByName = contentBank.querySelector(selectors.actions.sortname);
77 sortByName.addEventListener('click', () => {
78 const ascending = updateSortButtons(contentBank, sortByName);
79 updateSortOrder(fileArea, shownItems, 'data-file', ascending);
83 const sortByDate = contentBank.querySelector(selectors.actions.sortdate);
84 sortByDate.addEventListener('click', () => {
85 const ascending = updateSortButtons(contentBank, sortByDate);
86 updateSortOrder(fileArea, shownItems, 'data-timemodified', ascending);
90 const sortBySize = contentBank.querySelector(selectors.actions.sortsize);
91 sortBySize.addEventListener('click', () => {
92 const ascending = updateSortButtons(contentBank, sortBySize);
93 updateSortOrder(fileArea, shownItems, 'data-bytes', ascending);
97 const sortByType = contentBank.querySelector(selectors.actions.sorttype);
98 sortByType.addEventListener('click', () => {
99 const ascending = updateSortButtons(contentBank, sortByType);
100 updateSortOrder(fileArea, shownItems, 'data-type', ascending);
106 * Set the contentbank user preference in list view
108 * @param {Bool} viewList view ContentBank as list.
109 * @return {Promise} Repository promise.
111 const setViewListPreference = function(viewList) {
113 // If the given status is not hidden, the preference has to be deleted with a null value.
114 if (viewList === false) {
119 methodname: 'core_user_update_user_preferences',
123 type: 'core_contentbank_view_list',
130 return Ajax.call([request])[0].catch(Notification.exception);
134 * Update the sort button view.
136 * @method updateSortButtons
137 * @param {HTMLElement} contentBank The DOM node of the contentbank button
138 * @param {HTMLElement} sortButton The DOM node of the sort button
139 * @return {Bool} sort ascending
141 const updateSortButtons = (contentBank, sortButton) => {
142 const sortButtons = contentBank.querySelectorAll(selectors.elements.sortbutton);
144 sortButtons.forEach((button) => {
145 if (button !== sortButton) {
146 button.classList.remove('dir-asc');
147 button.classList.remove('dir-desc');
148 button.classList.add('dir-none');
150 updateButtonTitle(button, false);
154 let ascending = true;
156 if (sortButton.classList.contains('dir-none')) {
157 sortButton.classList.remove('dir-none');
158 sortButton.classList.add('dir-asc');
159 } else if (sortButton.classList.contains('dir-asc')) {
160 sortButton.classList.remove('dir-asc');
161 sortButton.classList.add('dir-desc');
163 } else if (sortButton.classList.contains('dir-desc')) {
164 sortButton.classList.remove('dir-desc');
165 sortButton.classList.add('dir-asc');
168 updateButtonTitle(sortButton, ascending);
174 * Update the button title.
176 * @method updateButtonTitle
177 * @param {HTMLElement} button Button to update
178 * @param {Bool} ascending Sort direction
179 * @return {Promise} string promise
181 const updateButtonTitle = (button, ascending) => {
183 const sortString = (ascending ? 'sortbyxreverse' : 'sortbyx');
185 return getString(button.dataset.string, 'contentbank')
186 .then(columnName => {
187 return getString(sortString, 'core', columnName);
189 .then(sortByString => {
190 button.setAttribute('title', sortByString);
197 * Update the sort order of the itemlist and update the DOM
199 * @method updateSortOrder
200 * @param {HTMLElement} fileArea the Dom container for the itemlist
201 * @param {Array} itemList Nodelist of Dom elements
202 * @param {String} attribute, the attribut to sort on
203 * @param {Bool} ascending, Sort Ascending
205 const updateSortOrder = (fileArea, itemList, attribute, ascending) => {
206 const sortList = [].slice.call(itemList).sort(function(a, b) {
208 let aa = a.getAttribute(attribute);
209 let bb = b.getAttribute(attribute);
216 return aa > bb ? 1 : -1;
218 return aa < bb ? 1 : -1;
221 sortList.forEach(listItem => fileArea.appendChild(listItem));