/*
* Menu and navigation
*/
/* Small helpers */
function cell(text) {
html = ""
html += '
';
html += text;
html += '
';
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 = '';
rows.forEach(row => {
id = row['id'];
info = row['info'];
html += '
';
});
html += '
';
}
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=""
for (var i=0; i"+label+" | "+data[i]["count"]+" | "
}
htmlString=htmlString+" |
"
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="Description
"+data[0][0]["description"]+"
"
prefix=data[0][1]["prefix"].replace(/Namespace"+prefix+"
"//prefix to construct correct query @data[0][1]["prefix"]
htmlString+="SPARQL query
"+data[0][2]["query"]+"
"
htmlString+="SPARQL results table
"
keys=Object.keys(data[1][0])
// Add keys as table headers
htmlString+=""
for (var j=0; j"+keys[j]+""
}
//Go through the results set given the keys and fill the tail of the table
for (var i=0; i"
for (var j=0; j"+content+"";
}
htmlString+=""+content+" | "
}
htmlString+="
"
}
htmlString=htmlString+"
"
//Something like this would be nice, hm
//htmlString+="Execute this query here"
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;
}
}