Développement Web côté client - TP4 - Tutoriel + Projet

Dans ce tutoriel, on va apprendre à créer une interface de gestion de base de données :

Au début, pour eviter les problèmes de sécurité, on travaille avec un fichier XML sur le serveur phobos. À la fin de ce tutoriel, vous trouverez des instructions qui vous permettre d'utiliser un fichier XML local - votre propre BDD.

  1. Télécharger et extrait le fichier DWC_XML_VE.zip
  2. On veut récupérer le fichier book_catalog.xml ( https://phobos.univ-brest.fr/media/edu/kx07kar7/book_catalog.xml ) et l'afficher dans un tableau en utlisant JavaScript :
  3. Dans le code HTML, on a un button "My book collection" et un tableau avec id="tblBook"
  4. Mettre à jour le button, appeler la fonction loadXMLDoc() lorsque l'utilisateur click sur le button
    <button type="button" onclick="loadXMLDoc()">My book collection</button>
  5. Dans votre code JS, ajouter la fonction loadXMLDoc(). Rappel : voir cours 3 pour explication des éléments : onreadystatechange, readyState, status, et XMLHttpRequest.
    
        let xmlhttp = new XMLHttpRequest();
        function loadXMLDoc() {
            xmlhttp.onreadystatechange = function () {
                if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                    fetchData();
                }
            };
            xmlhttp.open("GET", "https://phobos.univ-brest.fr/media/edu/kx07kar7/book_catalog.xml", true);
            xmlhttp.send();
        }
    
    
  6. Dans votre code JS, ajouter la fonction fetchData(). Dans cette fonction, la boucle for est utilisée pour créer le contenu HTML du tableau data. (Rappel : utilisation du propriété innerHTML dans cours 1 et 2)
    
        function fetchData() {
            let i;
            let xmlDoc = xmlhttp.responseXML;
            let table = "<tr><th>Book</th><th>Authors</th></tr>";
            let x = xmlDoc.getElementsByTagName("BOOK");
            for (i = 0; i < x.length; i++) {
                table += "<tr><td>" +
                x[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue +
                "</td><td>" +
                x[i].getElementsByTagName("AUTHOR")[0].childNodes[0].nodeValue +
                "</td>" +
                "<td><button type=\"button\" onclick=\"editBook(" +
                x[i].getElementsByTagName("ID")[0].childNodes[0].nodeValue + ")\">" +
                "Edit</button></td>" +
                "<td><button type=\"button\" onclick=\"deleteBook(" +
                x[i].getElementsByTagName("ID")[0].childNodes[0].nodeValue + ")\">" +
                "Delete</button></td>" +                
                "</tr>";
    
            }
            document.getElementById("data").innerHTML = table;
        }    
    
    
    Pour la suite, on va programmer le comportement des buttons Edit et Delete.
  1. Dans votre code JS, ajouter la fonction editBook(id)
    
        function editBook(id) {
            let tblBook = document.getElementById("tblBook");
            let txtTitle = document.getElementById("txtTitle");
            let txtAuthor = document.getElementById("txtAuthor");
            let hId = document.getElementById("hId");
        
            let xmlDoc = xmlhttp.responseXML;
            let books = xmlDoc.getElementsByTagName("BOOK");
            let book;
        
            for (i = 0; i < books.length; i++) {
                if (books[i].getElementsByTagName("ID")[0].childNodes[0].nodeValue == id) {
                    book = books[i];
                }
            }
        
            tblBook.style.display = "block";
            hId.value = book.getElementsByTagName("ID")[0].childNodes[0].nodeValue;
            txtTitle.value = book.getElementsByTagName("TITLE")[0].childNodes[0].nodeValue;
            txtAuthor.value = book.getElementsByTagName("AUTHOR")[0].childNodes[0].nodeValue;
        }
        
    
    Cette fonction faire apparaître le tableau tblBook et remplir les 2 textboxes avec les valeur correspondants aux livre choisi. Il y a un <input type="hidden" id="hId"> que l'on utilise pour sauvegarder l'identifiant du livre. Finalement, il y a un button Update pour mettre à jour les informations dans le tableau data.
  2. Dans votre code JS, ajouter la fonction updateBook(id)
        
        function updateBook() {
            let xmlDoc = xmlhttp.responseXML;
            let id = document.getElementById("hId").value;
            let books = xmlDoc.getElementsByTagName("BOOK");
            let book;
        
            for (i = 0; i < books.length; i++) {
                if (books[i].getElementsByTagName("ID")[0].childNodes[0].nodeValue == id) {
                    book = books[i];
                }
            }
        
            let txtTitle = document.getElementById("txtTitle");
            let txtAuthor = document.getElementById("txtAuthor");
        
            book.getElementsByTagName("TITLE")[0].childNodes[0].nodeValue = txtTitle.value;
            book.getElementsByTagName("AUTHOR")[0].childNodes[0].nodeValue = txtAuthor.value;
        
            fetchData();
        }
    
    
  1. Dans votre code JS, ajouter la fonction deleteBook(id)
                
        function deleteBook(id) {
            let xmlDoc = xmlhttp.responseXML;
            let books = xmlDoc.getElementsByTagName("BOOK");
            let book;
    
            for (i = 0; i < books.length; i++) {
                if(books[i].getElementsByTagName("ID")[0].childNodes[0].nodeValue == id) {
                    book = books[i];
                }
            }
            
            xmlDoc.documentElement.removeChild(book);
            fetchData();
        }
    
    

Lorsqu'on refresh la page, les changements sont perdus. La raison est que nous ne modifions que l'objet xmlDoc. Comme nous n'avons pas pris en compte le développement web côté serveur dans ce tutoriel, il n'y a pas de solution pour modifier directement le contenu d'un fichier sur le serveur.

Vous trouverez ci-dessous le code à mettre pour le button Save. Maintenant, on peut sauvegarder le contenu modifié dans un fichier (local).

Attention : cette fonction n'est PAS dans le cadre de l'UE Developpement Web côté client, il n'y aura PAS de questions sur son code lors de la séance d'évaluation.

    function makeTextFile (text) {
        let textFile = null;
        let data = new Blob([text], { type: 'text/plain' });

        if (textFile !== null) {
            window.URL.revokeObjectURL(textFile);
        }

        textFile = window.URL.createObjectURL(data);

        return textFile;
    };

    function saveBook() {                
        let create = document.getElementById('btnSave');

        let link = document.createElement('a');
        link.setAttribute('download', 'dwc_bdd.xml');
        
        const s = new XMLSerializer();

        link.href = makeTextFile(s.serializeToString(xmlhttp.responseXML));
        document.body.appendChild(link);

        window.requestAnimationFrame(function () {
            let event = new MouseEvent('click');
            link.dispatchEvent(event);
            document.body.removeChild(link);
        });
    }