about summary refs log tree commit diff
path: root/uploader/static/js
diff options
context:
space:
mode:
Diffstat (limited to 'uploader/static/js')
-rw-r--r--uploader/static/js/datatables.js69
-rw-r--r--uploader/static/js/debug.js40
-rw-r--r--uploader/static/js/files.js4
-rw-r--r--uploader/static/js/misc.js6
-rw-r--r--uploader/static/js/populations.js36
-rw-r--r--uploader/static/js/pubmed.js113
-rw-r--r--uploader/static/js/species.js34
-rw-r--r--uploader/static/js/utils.js27
8 files changed, 321 insertions, 8 deletions
diff --git a/uploader/static/js/datatables.js b/uploader/static/js/datatables.js
new file mode 100644
index 0000000..82fd696
--- /dev/null
+++ b/uploader/static/js/datatables.js
@@ -0,0 +1,69 @@
+/** Handlers for events in datatables **/
+
+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,
+        layout: {
+            topStart: null,
+            topEnd: null,
+            bottomStart: null,
+            bottomEnd: null,
+        },
+        select: true,
+        lengthMenu: defaultLengthMenu(data),
+        language: {
+            processing: "Processing… Please wait.",
+            loadingRecords: "Loading table data… Please wait.",
+            lengthMenu: "",
+            info: ""
+        },
+        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
+    });
+    theDataTable.on("select", (event, datatable, type, cell, originalEvent) => {
+        datatable.rows({selected: true}).nodes().each((node, index) => {
+            $(node).find(".chk-row-select").prop("checked", true)
+        });
+    });
+    theDataTable.on("deselect", (event, datatable, type, cell, originalEvent) => {
+        datatable.rows({selected: false}).nodes().each((node, index) => {
+            $(node).find(".chk-row-select").prop("checked", false)
+        });
+    });
+    return theDataTable;
+};
diff --git a/uploader/static/js/debug.js b/uploader/static/js/debug.js
new file mode 100644
index 0000000..eb01209
--- /dev/null
+++ b/uploader/static/js/debug.js
@@ -0,0 +1,40 @@
+/**
+ * The entire purpose of this function is for use to debug values inline
+ * without changing the flow of the code too much.
+ *
+ * This **MUST** be a non-arrow function to allow access to the `arguments`
+ * object.
+ *
+ * This function expects at least one argument.
+ *
+ * If more than one argument is provided, then:
+ * a) the last argument is considered the value, and will be returned
+ * b) all other arguments will be converted to string and output
+ *
+ * If only one argument is provided, it is considered the value, and will be
+ * returned.
+ *
+ * Zero arguments is an error condition.
+ **/
+function __pk__(val) {
+    /* Handle zero arguments */
+    if (arguments.length < 1) {
+        throw new Error("Invalid arguments: Expected at least one argument.");
+    }
+
+    msg = "/********** DEBUG **********/";
+    if (arguments.length > 1) {
+        msg = Array.from(
+            arguments
+        ).slice(
+            0,
+            arguments.length - 1
+        ).map((val) => {
+            return String(val);
+        }).join("; ")
+    }
+
+    value = arguments[arguments.length - 1];
+    console.debug("/********** " + msg + " **********/", value);
+    return value;
+}
diff --git a/uploader/static/js/files.js b/uploader/static/js/files.js
index 9d6bca1..0bde6f7 100644
--- a/uploader/static/js/files.js
+++ b/uploader/static/js/files.js
@@ -84,8 +84,8 @@ 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");
+        add_class(fileinput, "visually-hidden");
+        remove_class(droparea, "visually-hidden");
 
         // Define UI elements for browse and drag&drop
         resumable.assignDrop(droparea);
diff --git a/uploader/static/js/misc.js b/uploader/static/js/misc.js
deleted file mode 100644
index cf7b39e..0000000
--- a/uploader/static/js/misc.js
+++ /dev/null
@@ -1,6 +0,0 @@
-"Miscellaneous functions and event-handlers"
-
-$(".not-implemented").click((event) => {
-    event.preventDefault();
-    alert("This feature is not implemented yet. Please bear with us.");
-});
diff --git a/uploader/static/js/populations.js b/uploader/static/js/populations.js
new file mode 100644
index 0000000..89ededa
--- /dev/null
+++ b/uploader/static/js/populations.js
@@ -0,0 +1,36 @@
+$(() => {
+    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">`;
+                }
+            },
+            {
+                searchable: true,
+                data: (apopulation) => {
+                    return `${apopulation.FullName} (${apopulation.InbredSetName})`;
+                }
+            }
+        ],
+        {
+            select: "single",
+            paging: true,
+            scrollY: 700,
+            deferRender: true,
+            scroller: true,
+            scrollCollapse: true,
+            layout: {
+                topStart: "info",
+                topEnd: "search",
+                bottomStart: "pageLength",
+                bottomEnd: false
+            }
+        });
+});
diff --git a/uploader/static/js/pubmed.js b/uploader/static/js/pubmed.js
new file mode 100644
index 0000000..9afd4c3
--- /dev/null
+++ b/uploader/static/js/pubmed.js
@@ -0,0 +1,113 @@
+var extract_details = (pubmed_id, details) => {
+    var months = {
+        "jan": "January",
+        "feb": "February",
+        "mar": "March",
+        "apr": "April",
+        "may": "May",
+        "jun": "June",
+        "jul": "July",
+        "aug": "August",
+        "sep": "September",
+        "oct": "October",
+        "nov": "November",
+        "dec": "December"
+    };
+    var _date = details[pubmed_id].pubdate.split(" ");
+    return {
+        "authors": details[pubmed_id].authors.map((authobj) => {
+            return authobj.name;
+        }),
+        "title": details[pubmed_id].title,
+        "journal": details[pubmed_id].fulljournalname,
+        "volume": details[pubmed_id].volume,
+        "pages": details[pubmed_id].pages,
+        "month": _date.length > 1 ? months[_date[1].toLowerCase()] : "jan",
+        "year": _date[0],
+    };
+};
+
+var update_publication_details = (details) => {
+    Object.entries(details).forEach((entry) => {;
+                                                switch(entry[0]) {
+                                                case "authors":
+                                                    $("#txt-publication-authors").val(entry[1].join(", "));
+                                                    break;
+                                                case "month":
+                                                    $("#select-publication-month")
+                                                        .children("option")
+                                                        .each((index, child) => {
+                                                            console.debug(entry[1].toLowerCase());
+                                                            child.selected = child.value == entry[1].toLowerCase();
+                                                        });
+                                                default:
+                                                    $("#txt-publication-" + entry[0]).val(entry[1]);
+                                                    break;
+                                                }
+                                               });
+};
+
+var fetch_publication_abstract = (pubmed_id, pub_details) => {
+    $.ajax("https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi",
+           {
+               "method": "GET",
+               "data": {
+                   "db": "pubmed",
+                   "id": pubmed_id,
+                   "rettype": "abstract",
+                   "retmode": "xml"
+               },
+               "success": (data, textStatus, jqXHR) => {
+                   update_publication_details({
+                       ...pub_details,
+                       ...{
+                           "abstract": Array.from(data
+                                                  .getElementsByTagName(
+                                                      "Abstract")[0]
+                                                  .children)
+                               .map((elt) => {return elt.textContent.trim();})
+                               .join("\r\n")
+                       }});
+               },
+               "error": (jqXHR, textStatus, errorThrown) => {},
+               "complete": (jqXHR, textStatus) => {},
+               "dataType": "xml"
+           });
+};
+
+var fetch_publication_details = (pubmed_id, complete_thunks) => {
+    error_display = $("#search-pubmed-id-error");
+    error_display.text("");
+    add_class(error_display, "visually-hidden");
+    $.ajax("https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi",
+           {
+               "method": "GET",
+               "data": {"db": "pubmed", "id": pubmed_id, "format": "json"},
+               "success": (data, textStatus, jqXHR) => {
+                   // process and update publication details
+                   hasError = (
+                       Object.hasOwn(data, "error") ||
+                           Object.hasOwn(data.result[pubmed_id], "error"));
+                   if(hasError) {
+                       error_display.text(
+                           "There was an error fetching a publication with " +
+                               "the given PubMed ID! The error received " +
+                               "was: '" + (
+                                   data.error ||
+                                       data.result[pubmed_id].error) +
+                               "'. Please check ID you provided and try " +
+                               "again.");
+                       remove_class(error_display, "visually-hidden");
+                   } else {
+                       fetch_publication_abstract(
+                           pubmed_id,
+                           extract_details(pubmed_id, data.result));
+                   }
+               },
+               "error": (jqXHR, textStatus, errorThrown) => {},
+               "complete": () => {
+                   complete_thunks.forEach((thunk) => {thunk()});
+               },
+               "dataType": "json"
+           });
+};
diff --git a/uploader/static/js/species.js b/uploader/static/js/species.js
new file mode 100644
index 0000000..d42e081
--- /dev/null
+++ b/uploader/static/js/species.js
@@ -0,0 +1,34 @@
+$(() => {
+    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})`;
+                }
+            }
+        ],
+        {
+            select: "single",
+            paging: true,
+            scrollY: 700,
+            deferRender: true,
+            scroller: true,
+            scrollCollapse: true,
+            layout: {
+                topStart: "info",
+                topEnd: "search",
+                bottomStart: "pageLength",
+                bottomEnd: false
+            }
+        });
+});
diff --git a/uploader/static/js/utils.js b/uploader/static/js/utils.js
index 045dd47..1b31661 100644
--- a/uploader/static/js/utils.js
+++ b/uploader/static/js/utils.js
@@ -8,3 +8,30 @@ function trigger_change_event(element) {
     evt = new Event("change");
     element.dispatchEvent(evt);
 }
+
+
+var remove_class = (element, classvalue) => {
+    new_classes = (element.attr("class") || "").split(" ").map((val) => {
+        return val.trim();
+    }).filter((val) => {
+        return ((val !== classvalue) &&
+                (val !== ""))
+    }).join(" ");
+
+    if(new_classes === "") {
+        element.removeAttr("class");
+    } else {
+        element.attr("class", new_classes);
+    }
+};
+
+
+var add_class = (element, classvalue) => {
+    remove_class(element, classvalue);
+    element.attr("class", (element.attr("class") || "") + " " + classvalue);
+};
+
+$(".not-implemented").click((event) => {
+    event.preventDefault();
+    alert("This feature is not implemented yet. Please bear with us.");
+});