Exercice XML et DOM

Objectif Appronfir la manipulation du DOM HTML (et XML) via la réalisation d'une application Web pour la visualisation des horaires de la filière IM.

Ressources

Mise en place

Créez un projet Vite et installez ses dépendances :

npm create vite@latest schedule -- --template vanilla
cd schedule

Téléchargez les fichiers de départ et décompressez l'archive à la racine du projet, en remplaçant index.html et main.js. Elle contient le HTML, la CSS, les images, les XML et les modules du dossier utils.

Le fichier main.js est vide et déjà chargé par le HTML. Commencez par y importer les fonctions et les horaires :

import { getNode, getNodes, cloneTemplate, forEach, on } from './utils/dom.js';
import { strToDate, dateToFrCh, dateToHours } from './utils/date.js';
import { schedules } from './utils/schedule.js';

Lancez le serveur avec npm run dev, puis ouvrez l'adresse indiquée dans le terminal.

Gestion des événements

Gérez les clics sur les boutons possédant la classe CSS btn-schedule avec la fonction on. Lors d'un clic, récupérez l'attribut data-class-id contenant l'identifiant de la classe grâce à la propriété dataset. Ajoutez aussi la classe CSS selected au bouton cliqué et supprimez-la des autres boutons.

DOM XML des horaires

Le fichier utils/schedule.js importe les XML du dossier schedules à la racine du projet avec le chemin /schedules/*.xml et les transforme en DOM XML. Il exporte un objet schedules dont les clés sont les identifiants des classes.

Une fois l'identifiant de la classe récupéré, retrouvez le DOM XML de son horaire :

const xmlDom = schedules[classId];

Vous pouvez consulter un exemple de XML pour en observer la structure.

Traitement des données des horaires

À partir du DOM XML de la classe choisie, réalisez les traitements dans l'ordre suivant :

  1. Récupérez les éléments VEVENT du DOM XML et convertissez la collection en tableau. Indication : les fonctions getNode et getNodes acceptent une racine en deuxième argument.
  2. Filtrez le tableau pour ne conserver que les cours dont la date de fin, contenue dans DTEND, se situe dans le futur. Indication : récupérez le texte avec textContent, convertissez-le en objet Date grâce à strToDate, puis comparez-le avec new Date(), qui donne la date et l'heure actuelles.
  3. Triez les cours par ordre chronologique. Vous pouvez comparer les textes des éléments DTSTART sans les convertir en objets Date.

Génération du DOM des horaires

Parcourez les cours traités au point précédent et générez une ligne tr pour chacun d'eux avec cloneTemplate('#course-template').

Remplissez les cellules du clone avec textContent, en utilisant leurs classes CSS pour les sélectionner : .date pour la date, .hours .start et .hours .end pour les heures de début et de fin, .course pour le nom du cours (SUMMARY) et .room pour la salle (LOCATION).

Remplacez le contenu de #schedule par les lignes créées avec replaceChildren.

Changement de thème

Gérez les clics sur le bouton #theme-toggle pour alterner entre les thèmes light et dark. Le thème est défini par l'attribut data-theme de l'élément body, accessible avec getNode('body').dataset.theme. La CSS adapte les couleurs et l'icône du bouton à cet attribut.

Assurez la persistance du thème choisi avec localStorage.