Description du script

Ce script JavaScript s’exécute sur la page moredetail.pl du backoffice de Koha. Il réorganise l'affichage des informations bibliographiques et des exemplaires, améliore la lisibilité, masque certaines données non pertinentes et surligne l'exemplaire correspondant à un code-barres stocké.

Explication détaillée de l’algorithme

  1. Le script vérifie que la page actuelle est bien moredetail.pl.
  2. Il récupère un éventuel code-barres depuis localStorage.
  3. Il crée une nouvelle structure HTML (div) pour organiser les informations par sections claires et lisibles.
  4. Il extrait les données bibliographiques (.bibliodetails) et les insère dans une section dédiée.
  5. Il parcourt chaque bloc .page-section et isole ceux qui contiennent des informations d'exemplaire pour les organiser en colonnes (grid).
  6. Il remplace certains libellés de champs pour les adapter au vocabulaire interne (par ex. « Statut de prêt » devient « Informations de prêt »).
  7. Il masque les lignes contenant des informations comme le coût du prêt ou les frais horaires.
  8. Il surligne l'exemplaire correspondant au code-barres enregistré (si présent dans la page).
  9. Il réintègre les informations complémentaires (type de document) extraites de la div .catalogue-info dans la section des détails bibliographiques tout en évitant les doublons.

Code JavaScript

//mise en page de la page des exemplaires 
  
  
if (window.location.pathname.includes("moredetail.pl")) {
    console.log("Détection de la page 'moredetail.pl'.");

    const storedBarcode = localStorage.getItem("searchbox_value");

    const catalogueDetail = document.getElementById("catalogue_detail_biblio");
    if (!catalogueDetail) {
        console.error("Le conteneur principal 'catalogue_detail_biblio' est introuvable.");
        return;
    }
    console.log("Conteneur principal 'catalogue_detail_biblio' trouvé.");

    // Création du nouveau conteneur
    const newLayout = document.createElement("div");
    newLayout.id = "custom-layout";

    function createSection(title, content) {
        if (!content) {
            console.warn(`Contenu introuvable pour la section '${title}'.`);
            return null;
        }
        const section = document.createElement("div");
        section.classList.add("custom-section");
        section.innerHTML = `<h2>${title}</h2>`;
        section.appendChild(content.cloneNode(true));
        console.log(`Section '${title}' créée avec succès.`);
        return section;
    }

    const bibliographicDetails = catalogueDetail.querySelector(".listgroup .rows ol.bibliodetails");
    if (bibliographicDetails) {
        const bibliographicSection = createSection("Informations Bibliographiques", bibliographicDetails);
        if (bibliographicSection) newLayout.appendChild(bibliographicSection);
    } else {
        console.warn("Informations bibliographiques introuvables.");
    }

    const itemsGrid = document.createElement("div");
    itemsGrid.classList.add("items-grid");
    const itemSections = catalogueDetail.querySelectorAll(".page-section");
    console.log(`Nombre de sections d'exemplaires trouvées : ${itemSections.length}`);

    if (itemSections.length > 0) {
        let exemplarCount = 1;
        itemSections.forEach((section) => {
            const itemDetailsHeader = section.querySelector("h4");
            if (itemDetailsHeader && itemDetailsHeader.textContent.includes("Information sur l'exemplaire")) {
                const itemBlock = document.createElement("div");
                itemBlock.classList.add("item-block");
                itemBlock.innerHTML = `<h3>Exemplaire ${exemplarCount}</h3>`;
                exemplarCount++;
                const itemDetails = section.cloneNode(true);
                itemBlock.appendChild(itemDetails);
                itemsGrid.appendChild(itemBlock);
                console.log("Exemplaire ajouté au grid.");
            }
        });
        newLayout.appendChild(itemsGrid);
    } else {
        console.warn("Aucune section d'exemplaire trouvée.");
    }

    catalogueDetail.innerHTML = "";
    catalogueDetail.appendChild(newLayout);

    const style = document.createElement("style");
    style.textContent = `
        #custom-layout {
            display: flex;
            flex-direction: column;
            gap: 20px;
            padding: 10px;
            background-color: #f9f9f9;
            border: 1px solid #ccc;
        }
.custom-section ol li {
list-style: disc;
}
.custom-section ol li span {
font-weight: bold;
}
        .custom-section {
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 4px;
            background-color: #fff;
        }
        .items-grid {
            display: flex;
            flex-wrap: wrap;
            gap: 20px;
        }
        .item-block {
            flex: 1 1 calc(33.333% - 20px);
            box-sizing: border-box;
            padding: 10px;
            border: 1px solid #ccc;
            border-radius: 4px;
            background-color: #f1f1f1;
        }
        .item-block h3 {
            margin-top: 0;
        }
    `;
    document.head.appendChild(style);
    console.log("Styles personnalisés appliqués.");
    
    function updateLabel(selector, oldText, newText) {
        const elements = document.querySelectorAll(selector);
        elements.forEach(element => {
            if (element.textContent.trim() === oldText) {
                element.textContent = newText;
                console.log(`Label mis à jour : '${oldText}' → '${newText}'`);
            }
        });
    }

    updateLabel("li .label", "Numéro de copie :", "Sous-localisation :");
    updateLabel("li .label", "Statut perdu :", "Motif d'exclusion :");
    updateLabel("li .label", "Enumération du périodique :", "Etage :");
      updateLabel("li .label", "Statut de prêt :", "Informations de prêt :");

    const loanStatusElements = document.querySelectorAll("li");
    loanStatusElements.forEach(element => {
        const loanStatusText = element.innerHTML;
        if (loanStatusText.includes("Statut de prêt :")) {
            element.innerHTML = loanStatusText.replace(/\s+/g, ' ').replace(/>\s+</g, '><');
            console.log("Espaces multiples corrigés dans 'Statut de prêt :'.");
        }
    });
document.querySelectorAll('ol.bibliodetails > li').forEach(li => {
    const textContent = li.textContent.trim();

    // Vérifie si le contenu correspond à l'une des valeurs spécifiques
    if (
        textContent.includes("Coût du prêt") ||
        textContent.includes("Coût du prêt par jour") ||
        textContent.includes("Frais de location horaires")
    ) {
        li.style.display = "none"; // Masque l'élément
    }
});
  
  
  
    console.log("Mise en page personnalisée appliquée avec succès.");

    if (storedBarcode) {
        console.log("Code-barres récupéré dans le localStorage :", storedBarcode);

        // Récupérer tous les éléments qui contiennent des codes-barres
        const barcodeElements = document.querySelectorAll(".listgroup h3");
        console.log(`Nombre d'éléments contenant des codes-barres trouvés : ${barcodeElements.length}`);

        barcodeElements.forEach(barcodeElement => {
            const barcodeText = barcodeElement.textContent.trim().replace("Code à barres", "").trim();
            console.log("Code-barres analysé :", barcodeText);

            if (barcodeText === storedBarcode) {
                console.log("Code-barres correspondant trouvé :", barcodeText);
                const itemBlock = barcodeElement.closest(".item-block");
                if (itemBlock) {
                    itemBlock.style.backgroundColor = "#7abf87"; // Jaune
                    console.log("Mise en surbrillance appliquée à l'élément.");
                } else {
                    console.warn("Aucun élément 'item-block' associé trouvé.");
                }
            }
        });

      
      
function moveCatalogueInfo() {
    const catalogueInfo = document.querySelector('.catalogue-info');
    if (catalogueInfo) {
        // Sélectionner la div 'custom-section' où vous souhaitez insérer 'catalogue-info'
        const customSection = document.querySelector('.custom-section');

        // Vérifier si la section 'custom-section' existe
        if (customSection) {
            // Trouver l'élément <ol class="bibliodetails"> à l'intérieur de 'custom-section'
            const bibliodetails = customSection.querySelector('ol.bibliodetails');

            // Si l'élément <ol class="bibliodetails"> existe, insérer 'catalogue-info' après cette liste
            if (bibliodetails) {
                // Extraire les types de documents déjà présents dans la liste pour éviter les doublons
                const existingDocTypes = Array.from(bibliodetails.querySelectorAll('li span.label'))
                    .map(span => span.textContent.trim());

                // Récupérer les types de documents du 'catalogue-info' et les ajouter un par un
                const docTypes = catalogueInfo.querySelectorAll('.doc-type');
                docTypes.forEach(docType => {
                    const typeText = docType.textContent.trim();

                    // Vérifier si le type de document n'est pas déjà dans la liste
                    if (!existingDocTypes.includes(typeText)) {
                        // Créer un nouvel élément <li> pour ce type de document
                        const newListItem = document.createElement('li');
                        newListItem.innerHTML = `<span class="label">${typeText} :</span> ${docType.nextElementSibling.textContent.trim()}`;
                        bibliodetails.appendChild(newListItem);  // Ajouter à la liste
                        existingDocTypes.push(typeText);  // Ajouter le type à la liste des existants
                    }
                });

                // Déplacer 'catalogue-info' après 'bibliodetails'
                customSection.insertBefore(catalogueInfo, bibliodetails.nextSibling);
                console.log("Élément déplacé avec succès et types de documents ajoutés.");
            } else {
                console.log("L'élément <ol class='bibliodetails'> n'a pas été trouvé.");
            }
        } else {
            console.log("Section 'custom-section' non trouvée.");
        }
    } else {
        console.log("Élément 'catalogue-info' non trouvé.");
    }
}

// Essayer après un délai de 500ms pour donner le temps aux éléments d'être chargés
setTimeout(moveCatalogueInfo, 500);

      
    
    } else {
        console.warn("Aucun code-barres trouvé dans le localStorage sous 'searchbox_value'.");
    }
}

Éléments à modifier

Points clés pour les mises à jour de Koha