107 lines
4.0 KiB
JavaScript
107 lines
4.0 KiB
JavaScript
// ==UserScript==
|
|
// @name academyFIVE::AddSelectBox
|
|
// @namespace dakp/academyfive
|
|
// @version 2026.04.005
|
|
// @description Füge Selectbox für Kohorten/Planungsgruppen hinzu
|
|
// @author Dims Akpan
|
|
// @match https://a5.fhdw-hannover.de/*
|
|
// @match https://a5.fhdw.de/*
|
|
// @match https://fhdw.academyfive-preview.net/*
|
|
// @match https://fhdw-hannover.academyfive-preview.net/*
|
|
// @grant none
|
|
// @icon https://www.academyfive.com/typo3conf/ext/sitepackage/Resources/Public/build/assets/images/favicon-academyfive.ico
|
|
// ==/UserScript==
|
|
|
|
(function() {
|
|
'use strict';
|
|
|
|
// ─── Gemeinsame Hilfsfunktionen ───────────────────────────────────────────
|
|
|
|
function insertSelectButtons(selectSelector) {
|
|
const select = document.querySelector(selectSelector);
|
|
if (!select) return false;
|
|
|
|
const dropdownContainer = select.closest('.btn-group.bootstrap-select');
|
|
if (!dropdownContainer) return false;
|
|
|
|
const searchBox = dropdownContainer.querySelector('.bs-searchbox');
|
|
if (!searchBox) return false;
|
|
|
|
if (searchBox.nextElementSibling?.classList.contains('bs-actionsbox')) {
|
|
return true; // bereits vorhanden
|
|
}
|
|
|
|
const actionsBox = document.createElement('div');
|
|
actionsBox.className = 'bs-actionsbox';
|
|
actionsBox.innerHTML = `
|
|
<div class="btn-group btn-group-sm btn-block">
|
|
<button type="button" class="actions-btn bs-select-all btn btn-default">Alles auswählen</button>
|
|
<button type="button" class="actions-btn bs-deselect-all btn btn-default">Nichts auswählen</button>
|
|
</div>
|
|
`;
|
|
|
|
searchBox.insertAdjacentElement('afterend', actionsBox);
|
|
console.log('Select/Deselect Buttons eingefügt für:', selectSelector);
|
|
return true;
|
|
}
|
|
|
|
function waitAndInsert(tryFn) {
|
|
if (tryFn()) return;
|
|
|
|
const observer = new MutationObserver(() => {
|
|
if (tryFn()) observer.disconnect();
|
|
});
|
|
|
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
|
|
// Polling für initialen Seitenaufruf (Bootstrap Select initialisiert sich
|
|
// asynchron nach DOMContentLoaded)
|
|
let attempts = 0;
|
|
const poll = setInterval(() => {
|
|
attempts++;
|
|
if (tryFn() || attempts >= 50) {
|
|
clearInterval(poll);
|
|
if (attempts >= 50) observer.disconnect();
|
|
}
|
|
}, 100);
|
|
}
|
|
|
|
// ─── /course/list ─────────────────────────────────────────────────────────
|
|
|
|
function courseList_tryInsert() {
|
|
return insertSelectButtons('select[name="planningGroupIds[]"]');
|
|
}
|
|
|
|
function courseList_init() {
|
|
waitAndInsert(courseList_tryInsert);
|
|
}
|
|
|
|
// ─── /course/planning-group/list ──────────────────────────────────────────
|
|
|
|
function planningGroupList_tryInsert() {
|
|
return insertSelectButtons('select[name="cohort-ids[]"]');
|
|
}
|
|
|
|
function planningGroupList_init() {
|
|
waitAndInsert(planningGroupList_tryInsert);
|
|
}
|
|
|
|
// ─── Routing ──────────────────────────────────────────────────────────────
|
|
|
|
function init() {
|
|
const url = window.location.href;
|
|
|
|
if (url.includes('/course/planning-group/list')) {
|
|
planningGroupList_init();
|
|
} else if (url.includes('/course/list')) {
|
|
courseList_init();
|
|
}
|
|
}
|
|
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', init);
|
|
} else {
|
|
init();
|
|
}
|
|
})();
|