Skip to content

Instantly share code, notes, and snippets.

@andrewnicols
Created March 26, 2020 08:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andrewnicols/917c55fded91396475823e4c00bbf736 to your computer and use it in GitHub Desktop.
Save andrewnicols/917c55fded91396475823e4c00bbf736 to your computer and use it in GitHub Desktop.
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Module to handle dynamic table features.
*
* @module core_table/dynamic
* @package core_table
* @copyright 2020 Simey Lameze <simey@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import {fetch as fetchTableData} from 'core_table/local/dynamic/repository';
import * as Selectors from 'core_table/local/dynamic/selectors';
let watching = false;
/**
* Ensure that a table is a dynamic table.
*
* @param {HTMLElement} tableRoot
* @returns {Bool}
*/
const checkTableIsDynamic = tableRoot => {
if (!tableRoot) {
// The table is not a dynamic table.
throw new Error("The table specified is not a dynamic table and cannot be updated");
}
if (!tableRoot.matches(Selectors.table.region)) {
// The table is not a dynamic table.
throw new Error("The table specified is not a dynamic table and cannot be updated");
}
return true;
};
/**
* Get the filterset data from a known dynamic table.
*
* @param {HTMLElement} tableRoot
* @returns {Object}
*/
const getFiltersetFromTable = tableRoot => {
return JSON.parse(tableRoot.dataset.tableFilters);
};
/**
* Update the specified table based on its current values.
*
* @param {HTMLElement} tableRoot
* @returns {Promise}
*/
export const refreshTableContent = tableRoot => {
const filterset = getFiltersetFromTable(tableRoot);
return fetchTableData(
tableRoot.dataset.tableHandler,
tableRoot.dataset.tableUniqueid,
{
sortBy: tableRoot.dataset.sortBy,
sortOrder: tableRoot.dataset.sortOrder,
joinType: filterset.jointype,
filters: filterset.filters,
}
)
.then(data => {
const placeholder = document.createElement('div');
placeholder.innerHTML = data.html;
tableRoot.replaceWith(...placeholder.childNodes);
return data;
});
};
export const updateTable = (tableRoot, {
sortBy = null,
sortOrder = null,
filters = null,
} = {}, refreshContent = true) => {
checkTableIsDynamic(tableRoot);
// Update sort fields.
if (sortBy && sortOrder) {
tableRoot.dataset.sortBy = sortBy;
tableRoot.dataset.sortOrder = sortOrder;
}
// Update filters.
if (filters) {
tableRoot.dataset.filters = JSON.stringify(filters);
}
// Refresh.
if (refreshContent) {
return refreshTableContent(tableRoot);
} else {
return Promise.resolve();
}
};
/**
* Update the specified table using the new filters.
*
* @param {HTMLElement} tableRoot
* @param {Object} filters
* @param {Bool} refreshContent
* @returns {Promise}
*/
export const setFilters = (tableRoot, filters, refreshContent = true) =>
updateTable(tableRoot, {filters}, refreshContent);
/**
* Update the sort order.
*
* @param {HTMLElement} tableRoot
* @param {String} sortBy
* @param {Number} sortOrder
* @param {Bool} refreshContent
* @returns {Promise}
*/
export const setSortOrder = (tableRoot, sortBy, sortOrder, refreshContent = true) =>
updateTable(tableRoot, {sortBy, sortOrder}, refreshContent);
/**
* Set up listeners to handle table updates.
*/
export const init = () => {
if (watching) {
// Already watching.
return;
}
watching = true;
document.addEventListener('click', e => {
const tableRoot = e.target.closest(Selectors.table.region);
if (!tableRoot) {
return;
}
const sortableLink = e.target.closest(Selectors.table.sortablelink);
if (sortableLink) {
e.preventDefault();
setSortOrder(tableRoot, sortableLink.dataset.sortby, sortableLink.dataset.sortorder);
}
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment