aboutsummaryrefslogtreecommitdiff
path: root/uploader/static/js
diff options
context:
space:
mode:
Diffstat (limited to 'uploader/static/js')
-rw-r--r--uploader/static/js/datatables.js115
-rw-r--r--uploader/static/js/files.js118
-rw-r--r--uploader/static/js/populations.js22
-rw-r--r--uploader/static/js/species.js21
4 files changed, 276 insertions, 0 deletions
diff --git a/uploader/static/js/datatables.js b/uploader/static/js/datatables.js
new file mode 100644
index 0000000..9782a60
--- /dev/null
+++ b/uploader/static/js/datatables.js
@@ -0,0 +1,115 @@
+/** Handlers for events in datatables **/
+
+var dtAddRowSelectionHandler = (tableId) => {
+ $(tableId).on("draw.dt", (event) => {
+ $(".chk-row-select").on("change", (event) => {
+ var checkboxOrRadio = event.target;
+ var tablerow = checkboxOrRadio.parentElement.parentElement;
+ var tableclass = tablerow.getAttribute("class");
+ if(checkboxOrRadio.checked) {
+ if (checkboxOrRadio.type == "radio") {
+ $(tableId + " tr").each((index, row) => {
+ var rowKlass = $(row).attr("class") || "";
+ row.setAttribute(
+ "class", rowKlass.replaceAll("selected", "").trim());
+ });
+ }
+ tablerow.setAttribute("class", `${tableclass} selected`);
+ }
+ else {
+ tablerow.setAttribute(
+ "class", tableclass.replaceAll("selected", "").trim());
+ }
+ });
+ });
+};
+
+
+var toggleCheck = (checkboxOrRadio) => {
+ if (checkboxOrRadio.length > 0) {
+ var currentState = checkboxOrRadio.prop("checked");
+ var newState = !currentState;
+ if (currentState == true && checkboxOrRadio.attr("type").toLowerCase() == "radio") {
+ // We don't want to toggle from true to false by clicking on the row
+ // if it is a radio button.
+ newState = currentState;
+ }
+ checkboxOrRadio.prop("checked", newState);
+ checkboxOrRadio.trigger("change");
+ }
+};
+
+
+var dtAddRowClickHandler = (tableId) => {
+ $(tableId).on("draw.dt", (event) => {
+ $(tableId + " tbody tr").on("click", (event) => {
+ var row = event.target.closest("tr");
+ var checkboxOrRadio = $(row).find(".chk-row-select");
+ toggleCheck(checkboxOrRadio);
+ });
+ });
+};
+
+
+var dtAddCommonHandlers = (tableId) => {
+ dtAddRowSelectionHandler(tableId);
+ dtAddRowClickHandler(tableId);
+};
+
+var addTableLength = (menuList, lengthToAdd, dataLength) => {
+ if(dataLength >= lengthToAdd) {
+ newList = structuredClone(menuList);//menuList.slice(0, menuList.length); // shallow copy
+ newList.push(lengthToAdd);
+ return newList;
+ }
+ return menuList;
+};
+
+var defaultLengthMenu = (data) => {
+ menuList = []
+ var lengths = [10, 25, 50, 100, 1000, data.length];
+ lengths.forEach((len) => {
+ menuList = addTableLength(menuList, len, data.length);
+ });
+ return menuList;
+};
+
+var buildDataTable = (tableId, data = [], columns = [], userSettings = {}) => {
+ var defaultSettings = {
+ responsive: true,
+ /* == Scroller settings == */
+ scroller: true,
+ paging: true, // MUST be true for scroller to work
+ sDom: "iti",
+ scrollY: "100vh",
+ scrollCollapse: true,
+ /* == END: Scroller settings == */
+ lengthMenu: defaultLengthMenu(data),
+ language: {
+ processing: "Processing… Please wait.",
+ loadingRecords: "Loading population — Please wait.",
+ lengthMenu: "Show _MENU_ populations",
+ info: "Showing _START_ to _END_ of _TOTAL_ populations"
+ },
+ data: data,
+ columns: columns,
+ drawCallback: (settings) => {
+ $(this[0]).find("tbody tr").each((idx, row) => {
+ var arow = $(row);
+ var checkboxOrRadio = arow.find(".chk-row-select");
+ if (checkboxOrRadio) {
+ if (arow.hasClass("selected")) {
+ checkboxOrRadio.prop("checked", true);
+ } else {
+ checkboxOrRadio.prop("checked", false);
+ }
+ }
+ });
+ }
+ }
+ var theDataTable = $(tableId).DataTable({
+ ...defaultSettings,
+ ...userSettings
+ });
+ return theDataTable;
+};
diff --git a/uploader/static/js/files.js b/uploader/static/js/files.js
new file mode 100644
index 0000000..9d6bca1
--- /dev/null
+++ b/uploader/static/js/files.js
@@ -0,0 +1,118 @@
+var readFirstNLines = (thefile, count, process_content_fns) => {
+ var reader = new FileReader();
+ if(typeof thefile !== "undefined" && thefile !== null) {
+ reader.addEventListener("load", (event) => {
+ var content = event
+ .target
+ .result
+ .split("\n")
+ .slice(0, count)
+ .map((line) => {return line.trim("\r");});
+ process_content_fns.forEach((fn) => {fn(content);});
+ });
+ reader.readAsText(thefile);
+ }
+};
+var read_first_n_lines = readFirstNLines;
+
+
+var readBinaryFile = (file) => {
+ return new Promise((resolve, reject) => {
+ var _reader = new FileReader();
+ _reader.onload = (event) => {resolve(_reader.result);};
+ _reader.readAsArrayBuffer(file);
+ });
+};
+
+
+var Uint8ArrayToHex = (arr) => {
+ var toHex = (val) => {
+ _hex = val.toString(16);
+ if(_hex.length < 2) {
+ return "0" + val;
+ }
+ return _hex;
+ };
+ _hexstr = ""
+ arr.forEach((val) => {_hexstr += toHex(val)});
+ return _hexstr
+};
+
+
+var computeFileChecksum = (file) => {
+ return readBinaryFile(file)
+ .then((content) => {
+ return window.crypto.subtle.digest(
+ "SHA-256", new Uint8Array(content));
+ }).then((digest) => {
+ return Uint8ArrayToHex(new Uint8Array(digest))
+ });
+};
+
+
+var defaultResumableHandler = (event) => {
+ throw new Error("Please provide a valid event handler!");
+};
+
+var addHandler = (resumable, handlername, handler) => {
+ if(resumable.support) {
+ resumable.on(handlername, (handler || defaultResumableHandler));
+ }
+ return resumable;
+};
+
+
+var makeResumableHandler = (handlername) => {
+ return (resumable, handler) => {
+ return addHandler(resumable, handlername, handler);
+ };
+};
+
+
+var fileSuccessHandler = makeResumableHandler("fileSuccess");
+var fileProgressHandler = makeResumableHandler("fileProgress");
+var fileAddedHandler = makeResumableHandler("fileAdded");
+var filesAddedHandler = makeResumableHandler("filesAdded");
+var filesRetryHandler = makeResumableHandler("filesRetry");
+var filesErrorHandler = makeResumableHandler("filesError");
+var uploadStartHandler = makeResumableHandler("uploadStart");
+var completeHandler = makeResumableHandler("complete");
+var progressHandler = makeResumableHandler("progress");
+var errorHandler = makeResumableHandler("error");
+
+
+var markResumableDragAndDropElement = (resumable, fileinput, droparea, browsebutton) => {
+ if(resumable.support) {
+ //Hide file input element and display drag&drop UI
+ add_class(fileinput, "hidden");
+ remove_class(droparea, "hidden");
+
+ // Define UI elements for browse and drag&drop
+ resumable.assignDrop(droparea);
+ resumable.assignBrowse(browsebutton);
+ }
+
+ return resumable;
+};
+
+
+var makeResumableElement = (targeturi, fileinput, droparea, uploadbutton, filetype) => {
+ var resumable = Resumable({
+ target: targeturi,
+ fileType: filetype,
+ maxFiles: 1,
+ forceChunkSize: true,
+ generateUniqueIdentifier: (file, event) => {
+ return computeFileChecksum(file).then((checksum) => {
+ var _relativePath = (file.webkitRelativePath
+ || file.relativePath
+ || file.fileName
+ || file.name);
+ return checksum + "-" + _relativePath.replace(
+ /[^a-zA-Z0-9_-]/img, "");
+ });
+ }
+ });
+
+ return resumable;
+};
diff --git a/uploader/static/js/populations.js b/uploader/static/js/populations.js
new file mode 100644
index 0000000..73e298a
--- /dev/null
+++ b/uploader/static/js/populations.js
@@ -0,0 +1,22 @@
+$(() => {
+ dtAddCommonHandlers("#tbl-select-population");
+ var populationsDataTable = buildDataTable(
+ "#tbl-select-population",
+ JSON.parse(
+ $("#tbl-select-population").attr("data-populations-list")),
+ [
+ {
+ data: (apopulation) => {
+ return `<input type="radio" name="population_id"`
+ + `id="rdo_population_id_${apopulation.InbredSetId}" `
+ + `value="${apopulation.InbredSetId}" `
+ + `class="chk-row-select">`;
+ }
+ },
+ {
+ data: (apopulation) => {
+ return `${apopulation.FullName} (${apopulation.InbredSetName})`;
+ }
+ }
+ ]);
+});
diff --git a/uploader/static/js/species.js b/uploader/static/js/species.js
new file mode 100644
index 0000000..c1374c6
--- /dev/null
+++ b/uploader/static/js/species.js
@@ -0,0 +1,21 @@
+$(() => {
+ dtAddCommonHandlers("#tbl-select-species");
+ var speciesDataTable = buildDataTable(
+ "#tbl-select-species",
+ JSON.parse(
+ $("#tbl-select-species").attr("data-species-list")),
+ [
+ {
+ data: (aspecies) => {
+ return `<input type="radio" name="species_id"`
+ + `id="rdo_species_id_${aspecies.SpeciesId}" `
+ + `value="${aspecies.SpeciesId}" class="chk-row-select">`;
+ }
+ },
+ {
+ data: (aspecies) => {
+ return `${aspecies.FullName} (${aspecies.SpeciesName})`;
+ }
+ }
+ ]);
+});