Jérôme Cutrona

Version statique de l'intranet de Jérôme Cutrona - Rejoindre la version dynamique 🔒

Les exemples et corrections sont potentiellement non fonctionnels.

B.U.T. Informatique - IUT de Reims - Université de Reims

AJAX / AJAJ

Navigation

Objectifs de la séance

  • Concevoir un objet AjaxRequest JavaScript encapsulant une requête AJAX
  • Concevoir une page Web utilisant AJAX
  • Mettre en œuvre une liste de suggestions
  • Mettre en œuvre des listes déroulantes liées

Versionnage du projet

Pour ce sujet de TP, vous créerez un nouveau répertoire, vous initialiserez un dépôt Git dans ce répertoire et créerez un dépôt distant sur GitLab. Vous réaliserez une opération de validation avec git commit au moins une fois par question du sujet.

Initialisation du dépôt

  • Ouvrez un terminal puis utilisez la commande mkdir un_nom_de_répertoire pour créer un nouveau répertoire « php-ajaj » dans « ~/public_html » suivie de la commande cd un_chemin_relatif_ou_absolu pour vous placer dans le répertoire
  • Initialisez le dépôt Git du projet
    git init
  • Effectuez une première validation
    git commit --allow-empty -m "Initial commit"
  • Éditez le fichier « .gitignore » pour exclure les fichiers binaires inutiles à votre projet (fichiers pptx du cours, …), les fichiers qui contiennent des mots de passe ou, dans le cas des projets collaboratifs, les fichiers créés par votre éditeur de texte (répertoire « .idea » pour PhpStorm)
  • Éditez un fichier « README.md » dans lequel doivent figurer :
    • un titre de niveau 1 contenant le titre explicite du projet
    • un titre de niveau 2 « Auteur(s) » vous permettant de préciser votre nom et votre prénom (ainsi que ceux de votre binôme, le cas échéant)
    • un titre de niveau 2 « Installation / Configuration » précisant les points essentiels permettant d'installer, de configurer et de lancer le projet
  • Ajoutez les fichiers au dépôt
    git add .
  • Effectuez une nouvelle validation
    git commit -m "Repository setup"
  • Si nécessaire, renommez la branche principale en « main » (une branche vide ne peut pas être renommée, c'est pourquoi ceci est fait après le premier commit)
    git branch -m main
    Notez que vous pouvez le faire de façon définitive avec la commande suivante, à condition d'utiliser git dans une version supérieure à 2.28
    git config --global init.defaultbranch main
  • Connectez-vous à l'application GitLab et créez un dépôt portant le même nom que votre nouveau répertoire en pensant à décocher la case « Initialize repository with a README »
  • Accordez la permission « Reporter » à votre enseignant de TP/TD
  • Associez le dépôt local et le dépôt distant
    git remote add origin https://iut-info.univ-reims.fr/gitlab/votre_login/php-ajaj.git
  • Poussez le dépôt local vers le dépôt distant
    git push -u origin main

Consignes

  • Vous effectuerez une validation après chaque question.
  • À la fin de chaque séance, vous effectuerez une validation. Si cette validation contient du code incomplet ou ne fonctionnant pas, mentionnez-le dans le message de validation. Vous pousserez ensuite votre travail vers le dépôt distant.
  • Ce dépôt sera utilisé par votre enseignant(e) de TP pour évaluer votre travail, que cela conduise à un note ou pas. Assurez-vous donc régulièrement que tous les fichiers que vous souhaitez lui rendre sont bien présents dans le dépôt. Respectez les noms des fichiers qui vous sont demandés si des consignes particulières vous sont données.
  • Le dépôt lui-même sera évalué, soignez l'écriture de vos messages : clarté, pertinence, orthographe.

L'aide-mémoire Git et l'aide-mémoire GitLab de Monsieur Nourrit pourront vous être utiles.

Encapsulation d'une requête AJAX

Comme vous avez pu le constater à travers le CM sur AJAX, l'écriture d'une requête AJAX complète n'est pas une tâche complexe mais elle met en jeu un certain nombre d'étapes rébarbatives. Afin de vous simplifier la vie tout en appréhendant bien le fonctionnement complet de l'objet XmlHttpRequest, vous allez développer votre propre objet AjaxRequest qui encapsule toutes les étapes de la requête AJAX.

Afin de vous facilter la tâche, vous compléterez le script JavaScript request.js (télécharger) dans lequel les opérations fastidieuses de vérification des paramètres sont faites. Il vous reste à compléter les parties faisant spécifiquement appel aux fonctionnalités de l'objet xmlHttpRequest.

Toujours dans un but d'efficacité et d'exactitude, récupérez le script PHP test_request.php (télécharger) qui produit les réponses aux interrogations AJAX ainsi que la Page Web/JavaScript test_request.html (télécharger) qui utilise votre script request.js et devrait produire l'affichage suivant si votre objet AjaxRequest est conforme aux tests fonctionnels.

Remarque importante

Les script de test effectue des requêtes AJAX asynchrones. Votre liste de résultats doit comporter les mêmes entrées que l'exemple proposé, éventuellement dans un ordre différent.

Encapsulation des requêtes AJAX en JavaScript (Source)

Base de données

Dans la suite, vous utiliserez la base données « morceaux de musique » qui se compose comme suit : Structure de la base de données

Elle est hébergée sur le serveur « mysql » et se nomme « cutron01_cdobj ». Elle est accessible par l'utilisateur « web » dont le mot de passe est « web ».

Suggestions de noms en AJAX

Le but de cet exercice est de concevoir une page HTML (à base de PHP pour exploiter les fonctionnalités de la classe WebPage (télécharger) constituée d'un champ de saisie qui, lorsqu'il est modifié, entraine une requête sur le serveur pour proposer une liste de noms d'artistes contenant le texte saisi.

Le résultat souhaité pourrait être le suivant : Résultat souhaité

Travail à réaliser
  1. Récupérez le singleton de connexion à une base de données basé sur PDO : myPDO.class.php (télécharger). Configurez votre singleton dans un fichier myPDO.include.php qui sera inclus dans vos script PHP nécessitant un accès à la base de données.

    Pour mémoire, le DSN PDO pour cette base de données MySQL est de la forme « mysql:host=mysql;dbname=cutron01_cdobj;charset=utf8 »

    Remarque importante
    Tous les accès à la base de données seront faits à l'aide de requêtes préparées afin d'optimiser la mise en cache et de prévenir toute attaque par injection de code SQL.
  2. Ecrivez une page PHP (liste_artistes.php) capable d'effectuer une requête SQL affichant sous forme de texte brut la liste des artistes (par ordre alphabétique et séparés par des virgules) dont le nom contient la chaîne de caractères (q=…) passée en paramètre selon la méthode HTTP GET.
  3. Testez cette page (liste_artistes.php?q=chi).
  4. Ecrivez la page PHP (suggestions.php) contenant un champ de saisie texte ainsi qu'un SPAN identifié. Cette page utilisera la classe WebPage : webpage.class.php (télécharger)
  5. Ajoutez la capture des événements de saisie du champ texte et contrôlez son bon fonctionnement en affichant le texte saisi avec console.log(…).

    Afin de produire des pages Web plus facilement maintenables, votre code JavaScript ne se trouvera PAS dans les balises HTML (par exemple <form onsubmit="…">). L'alternative consiste à lancer une fonction JavaScript au chargement complet de la page et à y définir toutes les fonctionnalités souhaitées. Pour ce faire, vous utiliserez la base de script fournie :

  6. Ecrivez la fonctionnalité JavaScript permettant d'effectuer la requête HTTP sur le serveur pour obtenir la liste des suggestions. Les suggestions seront transmises sous forme de texte brut, les propositions étant séparées par des virgules. Elles prendront place dans le SPAN identifié lorsque le serveur aura répondu. Vous utliserez évidemment l'objet AjaxRequest développé précédemment.
  7. Testez le bon fonctionnement de l'ensemble.
  8. Observez le comportement du navigateur selon le mode synchrone ou asynchrone de la requête AJAX et suivez les requêtes émises vers le serveur à l'aide de l'outil de développement de votre navigateur Web : Suivi des requêtes AJAX dans la console du navigateur

Suggestions de noms en AJAX, cohérence de l'application

Dans l'état actuel de votre code et en fonction de la vitesse de réponse du serveur, la saisie de l'utilisateur peut être en décalage avec les propositions fournies par le serveur. La capture d'écran suivante témoigne d'un résultat inapproprié résultant de plusieurs saisies et effacements rapides : Mise en évidence des problèmes de cohérence de l'application

Introduisez une latence au niveau de la page PHP qui génère la liste des artistes. Pour cela, vous ajouterez un paramètre wait à votre requête AJAX et placerez le code PHP suivant dans votre script liste_artistes.php :

Ceci produira une pause variable de 0 à 2 secondes dans la réponse du serveur et vous devriez alors constater les incohérences mises en évidence dans l'exemple.

Afin de respecter la cohérence entre la saisie de l'utilisateur et les réponses du serveur, effectuez les modifications nécessaires pour que chaque nouvelle requête engendrée par une saisie de l'utilisateur annule la requête en attente s'il en existe une. Pour cela, si une requête est en cours, elle doit être annulée par la méthode cancel() de l'objet AjaxRequest.

Listes déroulantes dynamiques en AJAJ

Le but de cet exercice est de concevoir une page PHP constituée de trois listes déroulantes : la première contient la liste des genres des albums, la deuxième contient la liste des artistes dont au moins un album appartient au genre choisi et la troisième contient la liste des albums de l'artiste sélectionné. Les deuxièmes et troisièmes listes déroulantes doivent être mises à jour dynamiquement lors d'une modification de choix des premières et deuxièmes listes respectivement. Finalement, lorsqu'un album est sélectionné, un DIV identifié doit être modifié pour afficher les morceaux de l'album. Les données doivent être trouvées grâce à des requêtes sur le serveur.

Le résultat souhaité pourrait être le suivant : Résultat souhaité

Remarque importante

Les données transmises en réponse aux requêtes HTTP de type AJAX seront structurées en JSON. Consultez la documentation dédiée à la représentation de structures de données PHP en JSON.

Vous ne devez en aucun cas produire la structure JSON manuellement mais toujours utiliser la fonction json_encode().

Travail à réaliser
  1. Ecrivez une page PHP (artists.php) qui produit en JSON la liste des artistes dont au moins un des albums appartient au genre passé en paramètre selon la méthode HTTP GET. La structure attendue est un tableau d'objets possédant deux attributs, id et txt.
  2. Testez cette page artists.php?q=15 qui doit produire :
  3. Ecrivez une page PHP (albums.php) qui produit en JSON la liste des albums d'un artiste dont l'identifiant est passé en paramètre selon la méthode HTTP GET. La structure attendue est un tableau d'objets possédant deux attributs, id et txt.
  4. Testez cette page albums.php?q=40 qui doit produire :
  5. Ecrivez une page PHP (songs.php) qui produit en JSON la liste des morceaux d'un album dont l'identifiant est passé en paramètre selon la méthode HTTP GET. La structure attendue est un tableau d'objets possédant trois attributs, num, name et duration. Les attributs num et duration seront correctement formatés par la requête MySQL.
  6. Testez cette page songs.php?q=88 qui doit produire :
  7. Ecrivez une page PHP (genres1.php) contenant les trois listes déroulantes ainsi que le DIV identifié. La première liste déroulante contient la liste des genres obtenue grâce à une requete SQL.
  8. Ecrivez une fonction JavaScript viderSelect(sel) permettant de supprimer toutes les options de la liste déroulante sel sauf la première.
  9. Ecrivez une fonction JavaScript ajouterOption(sel, txt, val) permettant d'ajouter une nouvelle option (dont le texte est txt et la valeur est val) à la fin de la liste déroulante sel.
  10. Ecrivez une fonction JavaScript viderNoeud(noeud) qui permet de supprimer l'ensemble des fils du noeud noeud.
  11. Ecrivez une fonction JavaScript charge(url, str, sel) qui effectue la requête « url?q=str » sur le serveur et ajoute des options à la liste déroulante sel lors de la réponse de ce dernier.
  12. Ajoutez à la page précédente tout le code JavaScript (utilisant la fonction précédente) nécessaire au chargement dynamique de :
    • la liste des artistes dont au moins un album appartient au style
    • la liste des albums d'un artiste
    • la liste des morceaux d'un arlbum
  13. Testez le bon fonctionnement de l'ensemble.

Listes déroulantes dynamiques en AJAJ, cohérence de l'application

Dans l'état actuel de votre code et en fonction de la vitesse de réponse du serveur, l'affichage peut être en décalage avec les sélections faites par l'utilisateur. La capture d'écran suivante témoigne d'un résultat inapproprié résultant de plusieurs sélections rapides dans les diverses listes déroulantes : Mise en évidence des problèmes de cohérence de l'application Introduisez une latence au niveau de la page PHP qui génère la liste des artistes. Pour cela, vous ajouterez un paramètre wait à votre requête AJAX et placerez le code PHP suivant dans vos scripts artists.php, albums.php et songs.php :

Ceci produira une pause variable de 0 à 2 secondes dans la réponse du serveur et vous devriez alors constater certaines incohérences dues à la présence simultanée de requêtes en attente sur le serveur dont les réponses peuvent arriver dans un ordre différent de celui des requêtes.

Adaptez votre code JavaScript pour que votre application soit cohérente.

Pour ceux qui sont en avance, matérialisation de l'attente

Incorporez dans les exercices précédents une image d'attente correspondant au temps de traitement de la requête. L'image doit donc apparaître uniquement durant le traitement au sens large. Vous pouvez utiliser l'image Attente... ou Attente... ou Attente... qui ne sera affichée que durant le traitement du serveur. Vous utiliserez, en JavaScript, la propriété de style visibility à travers une fonction wait(etat) qui affiche ou masque l'image en fonction de etat. L'accès au style en JavaScript se fera par document.getElementById('identifiant_de_votre_image').style.visibility, qui prendra la valeur « visible » ou « hidden ».

Exemples : Capture d'écran de l'attente Capture d'écran de l'attente