diff options
| author | Florian Fischer <florian.fischer@muhq.space> | 2026-08-03 14:31:25 +0200 |
|---|---|---|
| committer | Florian Fischer <florian.fischer@muhq.space> | 2026-08-03 14:31:25 +0200 |
| commit | 6839831af54cd9302119bcc3bffafe10475958d4 (patch) | |
| tree | 12a1c1fbd864e9579cb9c3a09d4bf4686a280b73 /js/selection.js | |
| parent | fccb70cbd876785f6833dfe6efc10ec9e445556d (diff) | |
| download | bycs-sol-6839831af54cd9302119bcc3bffafe10475958d4.tar.gz bycs-sol-6839831af54cd9302119bcc3bffafe10475958d4.zip | |
refactor project structure
* merge sites into single project root
* fix name of mass-graduation site
* enable typescript support
Diffstat (limited to 'js/selection.js')
| -rw-r--r-- | js/selection.js | 170 |
1 files changed, 0 insertions, 170 deletions
diff --git a/js/selection.js b/js/selection.js deleted file mode 100644 index eda20ae..0000000 --- a/js/selection.js +++ /dev/null @@ -1,170 +0,0 @@ -/** - * Initialises a selection based on existing HTML elements. - * For HTML elements are required: - * - A text input with id $idPrefix - * - A list with id ${idPrefix}-list - * - An element shown if no results are available with id ${idPrefix}-noresults - * - A button to clear the input with id ${idPrefix}-clear - * - * @param {string} idPrefix - The id prefix of the four HTML elements. - * @param {async function} fetchCandidates - The async function to retrieve the selectable candidates. - * @param {function} fmtCandidate - The function to format the displayed HTML for each candidate. - * @param {function} onSelection - The function to call when a candidate is selected. - */ -async function initSelection(idPrefix, fetchCandidates, fmtCandidate, onSelection) { - const sel = document.getElementById(idPrefix); - const list = document.getElementById(`${idPrefix}-list`); - const noResults = document.getElementById(`${idPrefix}-noresults`); - const clearBtn = document.getElementById(`${idPrefix}-clear`); - const loader = document.getElementById(`${idPrefix}-loader`); - - loader.style.display = "unset"; - const candidates = await fetchCandidates(); - loader.style.display = "none"; - - let items = []; - - let currentFocus = -1; - let visibleItems = []; - function setActive() { - visibleItems.forEach(item => item.classList.remove("active")); - if (currentFocus >= 0 && visibleItems[currentFocus]) { - visibleItems[currentFocus].classList.add("active"); - } - } - - for (const candidate of candidates) { - let item = document.createElement("li"); - item.candidate = candidate; - item.innerHTML = fmtCandidate(candidate); - item.style.display = 'none'; - - item.addEventListener('click', function() { - sel.value = ""; - sel.dispatchEvent(new Event('keyup')); - onSelection(candidate); - }); - - list.appendChild(item); - items.push(item); - } - - sel.addEventListener('keyup', function(e) { - if ((["ArrowDown", "ArrowUp", "Enter"]).includes(e.key)) - return; - - const filter = sel.value.toLowerCase(); - visibleItems = []; - for (const item of items) { - const itemText = item.textContent.trim().toLowerCase(); - - if (itemText.indexOf(filter) > -1 && filter !== "") { - item.style.display = ""; - visibleItems.push(item); - - // Highlight matched text - const regex = new RegExp(`(${filter})`, 'gi'); - item.innerHTML = item.textContent.replace( - regex, - "<u class='student-selection-list-highlight'>$1</u>" - ); - } else { - item.style.display = "none"; - } - } - - // Show the clear button if there is an input - clearBtn.style.display = sel.value ? "block" : "none"; - - // Select the first or none if there are no items visible - currentFocus = visibleItems.length ? 0 : -1; - setActive(visibleItems); - noResults.style.display = visibleItems.length || filter === "" ? "none" : "block"; - }); - - clearBtn.addEventListener('click', function() { - sel.value = ""; - sel.dispatchEvent(new Event('keyup')); // reset list - sel.focus(); - }); - - sel.addEventListener('keydown', function(e) { - if (e.key === "ArrowDown" || e.key === "ArrowUp") { - if(e.key === "ArrowDown") - currentFocus = (currentFocus + 1) % visibleItems.length; - else - currentFocus = (currentFocus - 1 + visibleItems.length) % visibleItems.length; - setActive(); - e.preventDefault(); - } else if (e.key === "Enter") { - if (currentFocus > -1 && visibleItems[currentFocus]) { - - const visibleItem = visibleItems[currentFocus]; - sel.value = ""; - sel.dispatchEvent(new Event('keyup')); - onSelection(visibleItem.candidate); - } - e.preventDefault(); - } - }); -} - -function pointClickHandler(color) { - const textareaDiv = document.getElementById("student-info-point-reason-container"); - const textarea = document.getElementById("student-info-point-reason"); - const submitBtn = document.getElementById("student-info-point-reason-submit"); - - // TODO(muhq): Prefill the textarea with common reasons - switch (color) { - case "green": - textarea.style.background = "rgb(from green r g b / 20%)" - textarea.value = ""; - break; - case "orange": - textarea.style.background = "rgb(from orange r g b / 20%)" - textarea.value = ""; - break; - case "red": - textarea.style.background = "rgb(from red r g b / 20%)" - textarea.value = ""; - break; - } - textareaDiv.style.display = "block"; - textarea.focus(); - - // Can not use string interpolation because of Moodle's firstname filter. - const coach = firstname + " " + lastname; - - let submit = function() { - let change; - switch (color) { - case "green": - change = GraduationChange.newGreenPointChange(student, textarea.value, coach); - break; - case "orange": - change = GraduationChange.newOrangePointChange(student, textarea.value, coach); - break; - case "red": - change = GraduationChange.newRedPointChange(student, textarea.value, coach); - break; - default: - alert("Invalid color"); - break; - } - submitGraduationChange(student, change); - textareaDiv.style.display = "none"; - updateStudentInfo(); - } - // Use onEVENT to override any previous handler - textarea.onkeydown = function(e) { - if (e.shiftKey && e.key === "Enter") { - submit(); - } - if (e.key === "Escape") { - textareaDiv.style.display = "none"; - } - }; - submitBtn.onclick = submit; -} - -export { initSelection }; |
