-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MIR-1361 Allow to enter ROR as affiliation for authors (#1074)
* Display ror id as of https://ror.readme.io/docs/display * Added id attribute to ror input * Added ror-search.js * Enable search in ROR registry
- Loading branch information
Showing
11 changed files
with
194 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
...e/src/main/resources/META-INF/resources/images/ror/ror-icon-rgb-transparent.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
148 changes: 148 additions & 0 deletions
148
mir-module/src/main/resources/META-INF/resources/js/mir/ror-search.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
const RORSearch = { | ||
baseURL: "https://api.ror.org/", | ||
|
||
search: async function (text) { | ||
const q = await fetch(RORSearch.baseURL + "organizations?query=" + encodeURIComponent(text)); | ||
let json = await q.json(); | ||
|
||
let rorIdentifiers = []; | ||
|
||
json.items.forEach((item) => { | ||
item.label = item.name + " (" + item.id + ")"; | ||
rorIdentifiers.push(item); | ||
}); | ||
|
||
rorIdentifiers.sort((a, b) => { | ||
if (a.label < b.label) { | ||
return -1; | ||
} | ||
if (a.label > b.label) { | ||
return 1; | ||
} | ||
return 0; | ||
}); | ||
return rorIdentifiers; | ||
}, | ||
|
||
/** | ||
* Find the option (if any) matching the given label. | ||
* | ||
* @param dataListId the id of the datalist | ||
* @param label the label to find in the given datalist | ||
* | ||
* @return the option element with the givel label or null | ||
* */ | ||
getOption: function (dataListId, label) { | ||
let dataList = document.getElementById(dataListId); | ||
|
||
for (const option of dataList.childNodes) { | ||
if (option.value === label) { | ||
return option; | ||
} | ||
} | ||
|
||
return null; | ||
}, | ||
|
||
/** | ||
* Searches ROR for the given text at https://api.ror.org/ . | ||
* */ | ||
onInput: async function (event) { | ||
let input = event.target; | ||
let dataListId = input.getAttribute("list"); | ||
|
||
let option = RORSearch.getOption(dataListId, input.value); | ||
|
||
// User selects value from list | ||
if (option != null) { | ||
input.value = option.getAttribute("data-ror"); | ||
input.title = option.getAttribute("value") | ||
event.preventDefault(); | ||
return; | ||
} | ||
|
||
// Selected value is not in list, actually execute search at ROR | ||
let result = await RORSearch.search(input.value); | ||
let dataList = document.getElementById(dataListId); | ||
dataList.textContent = ""; | ||
|
||
// Update datalist with results from ROR | ||
for (const suggestion of result) { | ||
let option = document.createElement("option"); | ||
option.setAttribute("value", suggestion.label); | ||
option.setAttribute("data-ror", suggestion.id); | ||
dataList.appendChild(option); | ||
} | ||
}, | ||
|
||
debounce: (f, wait) => { | ||
let timeoutId = null; | ||
|
||
return (...args) => { | ||
window.clearTimeout(timeoutId); | ||
timeoutId = window.setTimeout(() => { | ||
f.apply(null, args); | ||
}, wait); | ||
}; | ||
}, | ||
|
||
/** | ||
* Resolve ror links in xEditor and update title attributes of ror inputs. | ||
* */ | ||
updateXEditorInputTitle: async function () { | ||
let rorInputs = document.querySelectorAll("[id='mir-ror-input']"); | ||
for (const rorInput of rorInputs) { | ||
if (rorInput.value.length == 0) { | ||
continue; | ||
} | ||
|
||
RORSearch.search(rorInput.value).then(data => { | ||
if (data.length > 0) { | ||
rorInput.setAttribute("title", data[0].name + " (" + data[0].id + ")"); | ||
} | ||
}); | ||
} | ||
}, | ||
|
||
/** | ||
* Resolve ror links on metadata page. | ||
* */ | ||
resolve: async function () { | ||
let rorLinks = document.querySelectorAll("a.mir-ror-link"); | ||
for (const rorLink of rorLinks) { | ||
RORSearch.search(rorLink.href).then(data => { | ||
if (data.length > 0) { | ||
if (data[0].name.length > 25) { | ||
rorLink.innerHTML = data[0].name.substring(0, 25).trim() + " …"; | ||
} else { | ||
rorLink.innerHTML = data[0].name; | ||
} | ||
rorLink.setAttribute("title", data[0].name + " | " + data[0].id); | ||
} | ||
}); | ||
} | ||
} | ||
}; | ||
|
||
/** | ||
* Adds event handler to every ror input element. | ||
* */ | ||
document.addEventListener('DOMContentLoaded', function () { | ||
const debouncedInputHandler = RORSearch.debounce(RORSearch.onInput, 500); | ||
|
||
for (const input of document.querySelectorAll('[id="mir-ror-input"]')) { | ||
// create datalist element with random uuid as element id | ||
let dataList = document.createElement("datalist"); | ||
dataList.id = self.crypto.randomUUID(); | ||
|
||
// set the previously created datalist as list to the ror input element | ||
input.setAttribute("list", dataList.id); | ||
input.parentElement.append(dataList); | ||
|
||
// add the actual event handler | ||
input.addEventListener('input', debouncedInputHandler); | ||
} | ||
|
||
RORSearch.resolve(); | ||
RORSearch.updateXEditorInputTitle(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters