:: Enseignements :: ESIPE :: E3INFO :: 2021-2022 :: Programmation Web avec JavaScript ::
[LOGO]

TP noté de Programmation Web - session 2


Le but de ce TP noté est d'écrire une petite application qui émule le fonctionnement d'un tableau à la Microsoft Excel.

Vous devez créer vos fichier dans le répertoire EXAM qui est un sous répertoire de votre répertoire home dans l'environement de TP noté. Seuls les fichiers créer dans ce répertoire seront sauvegarder. Donc si vous ne créez pas les fichiers dans le rpertoire EXAM mais dans un autre répertoire, ils ne seront pas sauvegardés, donc pas corrigés.
Comme l'environement coupe les communications TCP vers l'extérieur, le cours est disponible à cette adresse https://monge.univ-mlv.fr/~forax/progweb/.

Il est important de faire attention à la qualité du code que vous allez rendre. Avoir un code qui semble marcher mais qui est pas maintenable et compréhensible ou qui contient du code mort/qui ne sert à rien sera fortement pénalisé.

Exercice 1 - TP noté

Pour simplifier, notre "tableur" est consistué d'une ligne composée de 3 (ou plus) cases que l'utilisateur peut éditer et de 4 cases (enfin cela dépend du serveur) dont les valeurs sont calculées à partir des valeurs des 3 cases que l'utilisateur peut modifier.
L'édition des 3 cases se fait coté de l'application JavaScript, les calculs (ops) sont fait par le serveur qui renvoie le résultat du calcul.

Le code JavaScript doit utiliser la version JavaScript 2017. Attention à bien utiliser les "nouvelles" constructions partout et ne pas mixer les choses.

Pour ce TP, nous allons utiliser un serveur Web écrit en Java commen en TP. Cela vous permet voir les requètes et les réponses HTTP au niveau du réseau.
Le serveur qui définie deux endpoints REST,
  • GET /ops qui permet renvoie un tableau au format JSON avec toutes les opérations disponibles sur le serveur (sum, min, max, etc).
  • POST /ops/:id avec :id une chaine de caractères correspondant au nom de l'opération (toujours sum, min, max, etc) qui demande d'effectuer le calcul.
    Le body de la requète POST est un tableau au format JSON des 3 valeurs (au moins) éditables par l'utilisateur. La réponse est un objet JSON avec un champ result qui correspond au résultat de l'opération (la somme, le minimum, etc) sous forme d'un number.

Le fichier JExpress.java est un fichier java exécutable correspondant au serveur. La commande java JExpress.java permet d'exécuter celui-ci.
Une fois que le serveur a été lancé, il n'est pas nécessaire de l'arrêter avant la fin du TP.
Voici le fichier qui vous servir de base de travail tpnote.html ainsi que le fichier JavaScript correspodant tpnote.js.
Pour visualiser le fichier tpnote.html en utilisant le serveur, pointer votre navigateur à l'URL http://localhost:8080/tpnote.html


  1. Dans un premier temps, on va se contenter d'afficher une ligne du tableau HTML avec autant de cases que de cases dans array (la constante définie dans le fichier tpnote.js). Chaque case doit contenir la valeur de la case du tableau correspondante. Comme par défaut, le tableau contient les valeurs 1, 2 et 3. Le résultat devrait être un tableau HTML avec 3 cases contenant 1, 2 et 3. Bien sûr, si dans le fichier JavaScript, on change le tableau array, l'affichage HTML soit changer aussi.
    Ecrire le code directement dans le onload.
    Rappel: on créé les noeuds de l'arbre DOM avec document.createElement(tag), on les ajoute avec parent.appendChild(child) et le texte correspond à la propriété innerText.

  2. On cherche maintenant à ce qu'un utilisateur puisse éditeur les cases dans le navigateur. Pour cela, chaque case du tableau va contenir un noeud DOM input de type "text" dont la valeur value est la valeur de la case (par défaut, 1, 2 ou 3).
    Modifier votre code en conséquence.


  3. Comme on permet à l'utilisateur de saisir n'importe quel texte, il va falloir ajouter un peu de validation pour vérifier que le texte entré par l'utilisateur est bien un entier. Pour cela, à chaque fois que l'utilisateur modifie le contenue de l'input (avec onkeyup) utiliser la fonction parseInt sur la valeur (value) de l'input pour savoir si le texte entré par l'utilisateur est un entier ou pas. Pour l'instant on se contentera d'afficher le résultat de l'appel à parseInt sur la console.
    Modifier votre code pour avoir le comportement demandé.

  4. Pour finir la partie validation, si le résultat de parseInt est NaN (Not a Number), on veut changer la classe de l'input pour mettre la classe CSS "error" qui va mettre la bordure de l'input en rouge pour signaler que l'entrée de l'utilisateur est invalide. Si la valeur est valide, penser à retirer la classe "error" et à modifier le tableau array avec la nouvelle valeur.
    Note: il y a deux facons de changer la/les classes d'un noeud DOM, soit la propriété className suivi du nom de la classe ou une chaine vide si il n'y a pas de classe, soit la propriété classList qui permet de faire des add() et des remove() avec le nom de la classe.


  5. On souhaite maintenent afficher une ligne d'entête (header) à notre table HTML, les 3 (enfin cela dépend de la taille de array) premières cases doivent être vide et les 4 (enfin cela dépend du serveur) suivantes doivent contenir le nom des opérations disponible. Pour savoir les opérations disponible, faite un appel au server avec fetch sur le endpoint /ops pour obtenir un tableau des noms des opérations.
    Comme faire un fetch est un peu compliqué, isoler le code dans une fonction retrieveOps. Vous pouvez soit utiliser le mécanisme de async/await soit le mécanisme de promise à votre convenance.
    Ecrire la fonction retrieveOps et modifier votre code pour que la première ligne de la table contiennent autant de case vide que de cases dans le tableau array suivi du nom des opérations disponibles sur le serveur, un par case.
    Note: comme c'est une requète GET, vous pouvez regarder la valeur renvoyée par le serveur dans votre navigateur en tapant http://localhost:8080/ops/.


  6. On veut maintenant que la deuxième ligne du tableau en plus de contenir les valeurs entrées par l'utilisateur contiennent aussi les valeurs des opérations. Par exemple, pour l'opération min, on veut que en dessous de la case min la valeur soit le résultat de l'appel à la fonction min du serveur.
    Pour faire appel à la fonction op du serveur, il faut faire un appel POST sur le endpoint /ops/op avec op le nom de l'opération que l'on veut appeler (un des noms du tableau renvoyé par l'appel à /ops/).
    Modifier le code pour que pour faire une requète POST pour chaque case correspondant à une opération, et afficher le résultat de l'opération dans la case en dessous. Comme pour la question précédente, on va mettre le code de l'appel POST dans une fonction callOp() pour que le code soit plus facile à suivre.
    Note: pour faire un appel POST avec fetch, il faut passer en second paramètre, un objet qui a un champ method avec la chaine de caractère "POST" et un champ body avec encoder au format JSON les valeurs que l'on veut envoyer (dans le notre cas, les valeurs de array).
          fetch(uri, { method: "POST", body: ??? })  // remplacer le ??? par ce qu'il faut !
        

  7. Modifier le code précédent pour que lorsque l'utilisateur modifie une des cases éditables, les opérations sum, min, max, etc soient recalculées automatiquement est que les résultats soit affichés dans le tableau.
    Pour cela, le plus simple est de mettre le code de mise à jour dans une fonction update qui sera appelée au démarrage avec le tableau puis à chaque fois qu'une valeur du tableau est changée.
    Note: il n'est pas nécessaire de faire une mise à jour si l'utilisateur rentre une valeur invalide !

  8. Enfin, le code qui appel les opérations sur le serveur appel surement celles-ci les une après les autres, ce qui est pas très efficace. Pour accéléer le code, il est mieux d'utiliser Promise.all() pour demander au serveur le calcul des toutes les opérations en parallèle.
    Modifier le code de update pour faire le calcul des opérations en parallèle.