diff options
Diffstat (limited to 'uploader/static/js')
| -rw-r--r-- | uploader/static/js/datatables.js | 69 | ||||
| -rw-r--r-- | uploader/static/js/debug.js | 40 | ||||
| -rw-r--r-- | uploader/static/js/files.js | 4 | ||||
| -rw-r--r-- | uploader/static/js/misc.js | 6 | ||||
| -rw-r--r-- | uploader/static/js/populations.js | 36 | ||||
| -rw-r--r-- | uploader/static/js/pubmed.js | 113 | ||||
| -rw-r--r-- | uploader/static/js/species.js | 34 | ||||
| -rw-r--r-- | uploader/static/js/upload_samples.js | 24 | ||||
| -rw-r--r-- | uploader/static/js/urls.js | 26 | ||||
| -rw-r--r-- | uploader/static/js/utils.js | 27 |
10 files changed, 359 insertions, 20 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..111ebb7 --- /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: 500, + 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..f425f49 --- /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()] || "January") : "January", + "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..fb0d2d2 --- /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: 500, + deferRender: true, + scroller: true, + scrollCollapse: true, + layout: { + topStart: "info", + topEnd: "search", + bottomStart: "pageLength", + bottomEnd: false + } + }); +}); diff --git a/uploader/static/js/upload_samples.js b/uploader/static/js/upload_samples.js index aed536f..1c25a1d 100644 --- a/uploader/static/js/upload_samples.js +++ b/uploader/static/js/upload_samples.js @@ -87,20 +87,20 @@ function display_preview(event) { var data_preview_table = document.getElementById("tbl:samples-preview"); remove_rows(data_preview_table); - var separator = document.getElementById("select:separator").value; + var separator = document.getElementById("select-separator").value; if(separator === "other") { - separator = document.getElementById("txt:separator").value; + separator = document.getElementById("txt-separator").value; } if(separator == "") { display_error_row(data_preview_table, "Please provide a separator."); return false; } - var delimiter = document.getElementById("txt:delimiter").value; + var delimiter = document.getElementById("txt-delimiter").value; - var firstlineheading = document.getElementById("chk:heading").checked; + var firstlineheading = document.getElementById("chk-heading").checked; - var fileelement = document.getElementById("file:samples"); + var fileelement = document.getElementById("file-samples"); var preview_data = JSON.parse( fileelement.getAttribute("data-preview-content") || "[]"); if(preview_data.length == 0) { @@ -115,18 +115,18 @@ function display_preview(event) { delimiter)); } -document.getElementById("chk:heading").addEventListener( +document.getElementById("chk-heading").addEventListener( "change", display_preview); -document.getElementById("select:separator").addEventListener( +document.getElementById("select-separator").addEventListener( "change", display_preview); -document.getElementById("txt:separator").addEventListener( +document.getElementById("txt-separator").addEventListener( "keyup", display_preview); -document.getElementById("txt:delimiter").addEventListener( +document.getElementById("txt-delimiter").addEventListener( "keyup", display_preview); -document.getElementById("file:samples").addEventListener( +document.getElementById("file-samples").addEventListener( "change", (event) => { read_first_n_lines(event, - document.getElementById("file:samples"), + document.getElementById("file-samples"), 30, - document.getElementById("chk:heading").checked); + document.getElementById("chk-heading").checked); }); diff --git a/uploader/static/js/urls.js b/uploader/static/js/urls.js new file mode 100644 index 0000000..e3fb7c6 --- /dev/null +++ b/uploader/static/js/urls.js @@ -0,0 +1,26 @@ +function baseURL() { + return new URL(`${window.location.protocol}//${window.location.host}`); +}; + +function buildURLFromCurrentURL(pathname, searchParams = new URLSearchParams()) { + var uri = baseURL(); + uri.pathname=pathname; + var _search = new URLSearchParams(window.location.search); + searchParams.forEach(function(value, key) { + _search.set(key, value); + }); + uri.search = _search.toString(); + return uri +}; + +function deleteSearchParams(url, listOfParams = []) { + _params = new URLSearchParams(url.search); + listOfParams.forEach(function(paramName) { + _params.delete(paramName); + }); + + + newUrl = new URL(url.toString()); + newUrl.search = _params.toString(); + return newUrl; +} 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."); +}); |
