/* * Menu and navigation */ /* Small helpers */ function cell(text) { html = "" html += ' <div class="rTableCell">'; html += text; html += ' </div>'; return html } /* Convert a list of table items to an HTML DIV table */ function toDIVTable(rows) { if (rows.length == 0) html = "no results"; else { html = '<div class="rTable">'; rows.forEach(row => { id = row['id']; info = row['info']; html += '<div class="rTableRow">'; html += cell('<a href="'+info+'">'+id+'</a>'); html += cell('<a href="'+row['collection']+'">Collection</a>'); html += cell('<a href="'+row['fasta']+'">FASTA</a>'); html += cell('<a href="/api/ebi/sample-'+id+'.xml">EBI/ENA export XML</a>'); html += '</div>'; }); html += '</div>'; } console.log(html); document.getElementById("table").innerHTML = html; } /* Toggle between adding and removing the "responsive" class to topnav * when the user clicks on the icon */ function myFunction() { var x = document.getElementById("myTopnav"); if (x.className === "topnav") { x.className += " responsive"; } else { x.className = "topnav"; } } function fetchAPI(apiEndPoint,injectHTML=NULL) { fetch(scriptRoot + apiEndPoint) .then(response => { console.log("* response",response); return response.json(); }) .then(data => { console.log("* data",data); if (injectHTML) injectHTML(data); }); } // Copy from function above but now output HTML table instead of plain json function fetchHTMLTable(apiEndPoint) { fetch(scriptRoot + apiEndPoint) .then(response => { return response.json(); }) .then(data => { console.log(data) htmlString="<table>" for (var i=0; i<data.length;i++) { let url = data[i]["key"]; continents = ["Q538", "Q48", "Q49", "Q18", "Q15", "Q27611" ]; node = url.split("/").pop(); console.log(continents.includes(node)); if (url.includes("wikidata") && !continents.includes(node)) { url = "http://covid19.genenetwork.org/location?label="+url ; } let label = data[i]["label"]; htmlString=htmlString+"<tr><td><a href=\""+url+"\">"+label+"</a></td><td>"+data[i]["count"]+"<td></tr>" } htmlString=htmlString+"</table>" document.getElementById("table").innerHTML = htmlString }); } // changing access for Demo page function demofetchHTMLTable(apiEndPoint) { fetch(scriptRoot + apiEndPoint) .then(response => { return response.json(); }) .then(data => { console.log(data); htmlString="<h3>Description</h3><p>"+data[0][0]["description"]+"</p>" prefix=data[0][1]["prefix"].replace(/</g,"<"); htmlString+="<h4>Namespace</h4><pre>"+prefix+"</pre>"//prefix to construct correct query @data[0][1]["prefix"] htmlString+="<h3>SPARQL query</h3><pre>"+data[0][2]["query"]+"</pre>" htmlString+="<h3>SPARQL results table</h3><table>" keys=Object.keys(data[1][0]) // Add keys as table headers htmlString+="<tr>" for (var j=0; j<keys.length;j++){ htmlString+="<td style='font-weight: bold;'>"+keys[j]+"</bold></td>" } //Go through the results set given the keys and fill the tail of the table for (var i=0; i<data[1].length;i++) { htmlString+="</tr><tr>" for (var j=0; j<keys.length;j++){ content = data[1][i][keys[j]]; if (content.startsWith("http://")) { content = "<a href=\""+content+"\">"+content+"</a>"; } htmlString+="<td>"+content+"</td>" } htmlString+="</tr>" } htmlString=htmlString+"</table>" //Something like this would be nice, hm //htmlString+="Execute this query <a href='http://sparql.genenetwork.org/sparql?query='"+encodeURIComponent(encodeURIComponent(data[0][1]["prefix"]+data[0][2]["query"]))+"'>here</a>" document.getElementById("playground").innerHTML = htmlString }); } /* Fetch record info using a 'global search'. Returns for example [ { "id": "MT326090.1", "seq": "http://collections.lugli.arvadosapi.com/c=10eaef75e0b875f81aa1f411c75370cf+126/sequence.fasta" }, { "id": "MT326090.1", "seq": "http://collections.lugli.arvadosapi.com/c=5a4c815f3e076ad7760a91864c39dd07+126/sequence.fasta" } ] */ let searchGlobal = (toHTML) => { let m = document.getElementById('search-input').value; fetchAPI(scriptRoot + "/api/search?s=" + encodeURIComponent(m), toHTML); } // Same as above, but generates div table let searchGlobaltoDIVTable = () => { searchGlobal(toDIVTable); } let searchSeq = () => { let m = document.getElementById('search-input').value; fetchAPI(scriptRoot + "/api/getDetailsForSeq?seq=" + encodeURIComponent(m)); } // Get count from Arvados let fetchCount = () => { fetchAPI("/api/getCount"); } // Get count from Virtuoso let fetchCountDB = () => { fetchAPI("/api/getCountDB"); } ////// old API functions, some might no be used // let fetchSEQCountByTech = () => { fetchHTMLTable("/api/getSEQCountbytech"); } let fetchAllaccessions = () => { fetchHTMLTable("/api/getAllaccessions"); }; let fetchMap = () => { fetchAPI("/api/getCountByGPS"); updateMapMarkers(); }; let fetchSEQByLocation = () => { console.log("Missing - set parameter for request, retrieve data") }; let fetchSEQCountbyContinent = () => { fetchHTMLTable("/api/getSEQCountbyContinent"); } /////////////////////////////////// End "old" function ////****** SPARQL playground functions ***************//// let demoFetchSEQCountBySpecimen = (toHTML) => { //fetchHTMLTable("/api/getSEQCountbySpecimenSource"); demofetchHTMLTable("/api/demoGetSEQCountbySpecimenSource") } let demoFetchSEQCountByLocation = () => { //fetchHTMLTable("/api/getSEQCountbyLocation"); demofetchHTMLTable("/api/demoGetSEQCountbyLocation") } //Get authors and there country/contitent where they come from let demoGetAuthors = () => { demofetchHTMLTable("/api/demoGetAuthors") } // Fetch all institutes/originating labs and their associeted publications let demoFetchInstitutesPublications = () => { demofetchHTMLTable("/api/demoInstitutesPublications") } // Fetch sequence technology used by continent let demoGetSEQCountbytechContinent = () => { demofetchHTMLTable("/api/demoGetSEQCountbytechContinent") } let demoGetSEQCountbytech = () => { demofetchHTMLTable("/api/demoGetSEQCountbytech") } let demoGetSequencePerDate = () => { demofetchHTMLTable('/api/demoGetSequencePerDate') } let demoGetLocationGps = () => { demofetchHTMLTable("/api/demoGetLocationGps") } let demoGetNYsamples = () => { demofetchHTMLTable("/api/demoGetNYsamples") } let demoGetSouthAmericaSeq = () => { demofetchHTMLTable("/api/demoGetSouthAmericaSeq") } let demoGetSeqByAgeGender = () => { demofetchHTMLTable("/api/demoGetSeqByAgeGender") } let demoGetSeqIllumina = () => { demofetchHTMLTable("/api/demoGetSeqIllumina") } let demoGetSeqWithStrain = () => { demofetchHTMLTable("/api/demoGetSeqWithStrain") } let demoGetContinentSpecimentSeqCount = () => { demofetchHTMLTable("/api/demoGetContinentSpecimentSeqCount") } let demoGetSampleSchema= () => { demofetchHTMLTable("/api/demoGetSampleSchema") } ////****** SPARQL playground functions ***************//// /* * Make sure that only one of the manual metadata entry and metadata upload * form components is *actually* a child of the form element in the DOM. * * Because both make use of the "required" attribute, we can't get away with * just hiding the one we don't want the user to fill in. The hidden part will * still have possibly empty required fields and (some) browsers will * blocksubmission because of it. Moreover, the data (including file uploads) * from the hidden elements will still be sent to the server, which the user * may not expect. */ function setUploadMode() { // Make the upload form the one in use. uploadFormSpot.appendChild(uploadForm) // Remove the upload form from the DOM so its required-ness does not block submission. fillFormSpot.removeChild(fillForm) } function setFillMode() { // Make the fillable form the one in use uploadFormSpot.removeChild(uploadForm) // Remove the fillable form from the DOM so its required-ness does not block submission. fillFormSpot.appendChild(fillForm) } function setMode() { // Pick mode based on radio if (document.getElementById('metadata_upload').checked) { setUploadMode() } else { setFillMode() } } /* * Machinery for variable-length lists of input items. */ // Start in mode appropriate to selected form item. // It is important that we run this code when the page starts! The browser may // have set the radio button to whatever the state was on last page load, // instead of the default state, without raising an event, and we have to // handle that. /** * Add another form field to the group this button is part of. */ function addField(e) { // Find our parent field-group div let fieldGroup = this.parentElement // Get its keypath let keypath = fieldGroup.dataset.keypath // Find its last field child let existingFields = fieldGroup.getElementsByClassName('field') let templateField = existingFields[existingFields.length - 1] // Get its number let fieldNumber = templateField.dataset.number // Duplicate it let newField = templateField.cloneNode(true) // Increment the number and use the keypath and number to set IDs and cross // references. // TODO: Heavily dependent on the form field HTML. Maybe we want custom // elements for the labeled controls that know how to be list items? fieldNumber++ newField.dataset.number = fieldNumber let newID = keypath + '[' + fieldNumber + ']' let newControl = newField.getElementsByClassName('control')[0] newControl.id = newID newControl.setAttribute('name', newID) let newLabel = newField.getElementsByTagName('label')[0] newLabel.setAttribute('for', newID) // Find the minus button let minusButton = fieldGroup.getElementsByClassName('remove-field')[0] // Put new field as a child before the minus button fieldGroup.insertBefore(newField, minusButton) // Enable the minus button minusButton.classList.remove('invisible') } /** * Remove the last form field from the group button is part of. */ function removeField(e) { // Find our parent field-group div let fieldGroup = this.parentElement // Find its field children let existingFields = fieldGroup.getElementsByClassName('field') if (existingFields.length > 1) { // There is a last field we can safely remove. let lastField = existingFields[existingFields.length - 1] fieldGroup.removeChild(lastField) } if (existingFields.length <= 1) { // Collection auto-updates. Now there's only one element. Don't let the // user remove it. If they don't want it, they can leave it empty. this.classList.add('invisible') } } // Change the submit button after hitting function on_submit_button() { var f = document.getElementsByTagName('form')[0]; if(f.checkValidity()) { var elem = document.getElementById("submit"); elem.value = "Submitting..."; elem.disabled = true; f.submit(); } else { alert(document.getElementById('example').validationMessage); return false; } }