Ce script est destiné à la page readingrec.pl de Koha. Il met en forme l’historique de prêt des adhérents en traitant un tableau de lecture.
Le script calcule la durée du prêt ou le retard en fonction des dates d'emprunt, de retour prévue et de retour effective.
Il applique un fond vert clair pour les retours effectués dans les délais et un fond rouge clair en cas de retard.
readingrec.pl.scriptExecuted empêche l’exécution multiple du script.table#table_readingrec.parseCustomDate convertit les chaînes de date (au format « Emprunté le DD/MM/YYYY HH:MM » ou « DD/MM/YYYY ») en objets Date..paginate_button) afin de relancer le traitement lors du changement de page.MutationObserver surveille l’apparition du conteneur de pagination pour ajouter les écouteurs dès qu’il est disponible.//Mise en forme historique de prêt adhérent
if (window.location.pathname.includes("readingrec.pl")) {
let scriptExecuted = false; // Variable pour vérifier si le script a déjà été exécuté
// Fonction pour analyser et traiter le tableau
function highlightReadingRec() {
if (scriptExecuted) return; // Si le script a déjà été exécuté, ne pas relancer
scriptExecuted = true; // Marquer le script comme exécuté
console.log("Exécution du script pour traiter le tableau de lecture.");
const table = document.querySelector("table#table_readingrec");
if (!table) return; // Quitte si le tableau n'est pas trouvé
const rows = table.querySelectorAll("tbody tr");
// Fonction pour convertir une chaîne de date au format attendu
function parseCustomDate(dateString) {
const cleanedString = dateString.replace(/Emprunté le\s*/, "").trim();
const match = cleanedString.match(/^(\d{2})\/(\d{2})\/(\d{4})(?:\s+(\d{2}):(\d{2}))?$/);
if (!match) return NaN;
const [, day, month, year, hour = "0", minute = "0"] = match;
return new Date(year, parseInt(month) - 1, day, hour, minute);
}
// Parcourt les lignes du tableau
rows.forEach((row) => {
const cells = row.querySelectorAll("td");
if (cells.length < 13) return; // Assure qu'il y a suffisamment de colonnes
// Extraction des dates depuis les colonnes appropriées
const borrowedDate = parseCustomDate(cells[8].textContent.trim()); // Colonne 8 : "Date de prêt"
const expectedReturnDate = parseCustomDate(cells[11].textContent.trim()); // Colonne 11 : "Date de retour prévue"
let actualReturnDate;
// Si "Prêté" est dans la colonne retour effective, on prend la date actuelle
if (cells[12].textContent.includes("Prêté")) {
actualReturnDate = new Date(); // Date actuelle
} else {
actualReturnDate = parseCustomDate(cells[12].textContent.trim()); // Colonne 12 : "Date de retour effective"
}
// Si le retour est effectué dans les délais
if (actualReturnDate <= expectedReturnDate) {
const loanDuration = Math.ceil((actualReturnDate - borrowedDate) / (1000 * 60 * 60 * 24));
// Appliquer un fond vert clair à la cellule de la date de retour
cells[12].style.backgroundColor = "#d4f8d4"; // Vert clair
if (!cells[12].innerHTML.includes('Durée du prêt :')) {
cells[12].insertAdjacentHTML('beforeend', `<div style="color: green;">Durée du prêt : ${loanDuration} jours</div>`);
}
} else {
// Si retard, calcul de la durée du retard en jours
const delayDuration = Math.ceil((actualReturnDate - expectedReturnDate) / (1000 * 60 * 60 * 24));
// Appliquer un fond rouge clair à la cellule de la date de retour
cells[12].style.backgroundColor = "#f8d4d4"; // Rouge clair
if (!cells[12].innerHTML.includes('Retard')) {
cells[12].insertAdjacentHTML('beforeend', `<div style="color: red;">Retard (${delayDuration} jours)</div>`);
}
}
});
}
// Délai de 2 secondes avant l'exécution pour que le tableau soit entièrement chargé
setTimeout(highlightReadingRec, 2000);
// Fonction pour ajouter l'écouteur d'événement sur la pagination
function addPaginationListener() {
console.log("Ajout des écouteurs d'événements sur les boutons de pagination.");
const paginationButtons = document.querySelectorAll('.paginate_button');
paginationButtons.forEach(button => {
button.addEventListener('click', function() {
console.log("Bouton de pagination cliqué : " + button.id);
// Attendez 1 seconde avant de relancer le script pour la nouvelle page
setTimeout(() => {
console.log("Relance du script après le délai de 1 seconde.");
if (!scriptExecuted) {
highlightReadingRec(); // Relance la fonction si elle n'a pas encore été exécutée
}
}, 1000);
});
});
}
// Fonction pour observer les changements du DOM et détecter l'apparition du conteneur de pagination
function observePagination() {
const paginateContainer = document.querySelector('#table_readingrec_paginate');
if (paginateContainer) {
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'childList') {
addPaginationListener(); // Ajouter les écouteurs quand la pagination est présente
}
});
});
// Observer les changements dans le DOM
observer.observe(paginateContainer, {
childList: true,
subtree: true,
});
} else {
// Si l'élément n'existe pas encore, réessayer après un délai
setTimeout(observePagination, 500);
}
}
// Lancer l'observation de la pagination après la première exécution
observePagination();
// Lancer le script initialement
highlightReadingRec();
}
table#table_readingrec) et l'indice des colonnes utilisés pour extraire les dates.parseCustomDate pour adapter la conversion de date en fonction du format des chaînes.#table_readingrec reste inchangée après les mises à jour.MutationObserver.