Exercices TP-6

  1. Bienvenue au TP-6
  2. Révisions
    1. Variable
    2. Création de fonction
    3. Concaténation
    4. Fonction
    5. Fonction 2
    6. Fonction anonyme
    7. Fonctions jQuery
    8. Fonctions jQuery 2
    9. Fonction jQuery
    10. Fonction jQuery
    11. This
    12. .hide()
    13. .parent()
    14. Parcours arbre
  3. Cours: JSON
    1. HTML / Données
    2. JSON
    3. JSON : exemples
    4. PHP: json_encode()
    5. JS : réponse JSON
    6. Application vs page + JS
    7. Application JS
  4. Exercice JSON : noms
    1. GET ou POST ?
    2. Fichiers
    3. uid utilisateur
    4. Correction
    5. Entêtes HTTP
    6. Console : entêtes http
    7. Content-type
    8. Content-Type image
    9. utilisateurs.php
    10. Correction: utilisateurs.php
    11. utilisateurs.js
    12. Correction: utilisateurs.js
    13. Gestion d'erreurs
    14. Correction: gestion d'erreurs
    15. Popup
    16. Correction
  5. Cours: DOM
    1. jQuery vs DOM
    2. Navigateurs
    3. Compatibilité
    4. Principaux objets DOM
    5. Window & Document
    6. document.getElementById()
    7. document.createElement()
    8. node.appendChild()
    9. DOM & jQuery
    10. Node / HTMLElement
    11. Text
    12. Node & HTMLElement
    13. element.className
    14. node.parentNode
    15. node.children
    16. element.addEventListener()
  6. Questions DOM
    1. Navigateurs
    2. Mobile
    3. Can I Use
    4. Can I use ?
    5. DOM
    6. Arbre DOM
    7. jQuery équivalent DOM
    8. DOM: className
    9. parentNode()
    10. children
    11. addEventListener
  7. Hello DOM world
    1. Fichiers
    2. Document ready
    3. Correction
    4. Click -> rouge
    5. Correction
  8. Morpion DOM
    1. Fichiers
    2. jQuery: multiple
    3. Gestionnaire d’événements
    4. Correction
  9. Commentaires : formulaire AJAX
    1. Fichiers
    2. Popup
    3. Correction
    4. Bouton ajouter
    5. Bouton ajouter
    6. Correction

1. Bienvenue au TP-6

1.1 Bienvenue au TP-6

Pour votre progression, c'est très important de finir le TP précédent avant de commencer celui-ci.

2. Révisions

2.1 Révisions

Commençons ce TP par des révisions.
Ces révisions sont un peu plus approfondies que les précédentes.
On a déjà vu beaucoup de choses, c'est important de faire un bilan.


Révisions

2.2 Variable

Que faut-il écrire pour créer une variable appelée "a" dont la valeur est un booléen vrai ?

Révisions

2.3 Création de fonction

Que faut-il écrire (en une seule ligne) pour créer une fonction qui puisse être appelée comme ceci:

var a=age_client("Akima");

(mettez ce que vous voulez dans la fonction)


Révisions

2.4 Concaténation


var nom="jean";
var fichier=XXXX;

Que faut-il écrire à la place de XXXX pour que fichier prenne la valeur "jean.txt" ?
(en utilisant la variable nom)

Révisions

2.5 Fonction


var a=exemple();

function exemple()
{
return true;
}
Quel est le type contenu dans la variable a ?

Révisions

2.6 Fonction 2


var a=exemple;

function exemple()
{
return true;
}
Quel est le type contenu dans la variable a ?

Révisions

2.7 Fonction anonyme


var a=function()
{
return true;
};
Quel est le type contenu dans la variable a ?

Révisions

2.8 Fonctions jQuery

$('p').XXXX;

Que faut-il écrire à la place de XXXX pour que

<p>
bonjour
</p>

devienne

<p>
aurevoir
</p>

Révisions

2.9 Fonctions jQuery 2

$('p').XXXX;

Que faut-il écrire à la place de XXXX pour que

<p>
bonjour
</p>

devienne

<p>
<strong>aurevoir</strong>
</p>

Révisions

2.10 Fonction jQuery

console.log($('input').XXXX);

Que faut-il écrire à la place de XXXX pour afficher dans la console le texte tapé par l'utilisateur dans le champs texte suivant:

<p>
<input type="text" />
</p>

Révisions

2.11 Fonction jQuery

console.log($('p').XXXX);

Que faut-il écrire à la place de XXXX pour afficher "bonjour" dans la console:

<p>
bonjour
</p>

Révisions

2.12 This



0 $('.boites .non').click(function()
1 {
2
3 });

L'utilisateur clique sur l'élément 7.

A la ligne 2 du programme, quel est le nom de la variable qui désigne l'élément 7  ?
(c'est à dire: l'élément sur lequel on vient de cliquer)

Révisions

2.13 .hide()

Quand l'utilisateur clique sur 5 ou 7, on voudrait que l'élément cliqué (5 ou 7) soit caché.

0 $('.boites .non').click(function()
1 {
2 $(this).XXXX;
3 });

Que faut-il écrire à la place de XXXX ?

Révisions

2.14 .parent()

Quand l'utilisateur clique sur 5 ou 7, on voudrait que l'élément au-dessus (2 ou 3) soit caché.

0 $('.boites .non').click(function()
1 {
2 $(this).XXXX;
3 });
Que faut-il écrire à la place de XXXX ?

Révisions

2.15 Parcours arbre

Quand l'utilisateur clique sur 5 ou 7, on voudrait que 4 ou 6 soit caché.

0 $('.boites .non').click(function()
1 {
2 $(this).XXXX;
3 });

Que faut-il écrire à la place de XXXX ?

3. Cours: JSON

3.1 Cours: JSON

Si vous venez d'assister au cours magistral, passez à la section suivante.

Cours: JSON

3.2 HTML / Données

Dans les exemples vus précédemment, le serveur renvoyait un fragment de HTML qui était ensuite affiché.

Bien souvent, on veut chercher des données complexes sur le serveur, et pas juste du HTML.

On pourrait utiliser n'importe quel format pour ces données. Il suffit juste que le programme sur le serveur et le JavaScript soient d'accord.

Le XML a été beaucoup utilisé, mais est lourd à manipuler.

Pour les tâches simples, du texte brut est possible.

Pour les informations plus structurées on utilise souvent, aujourd'hui, un format appelé JSON.

Cours: JSON

3.3 JSON

Le JSON est format texte qui est presqu'identique au format utilisé en JavaScript pour déclarer des Objets ou des Tableaux.

Tous les principaux langages fournissent des méthodes pour encoder et décoder le JSON.

Cours: JSON

3.4 JSON : exemples

Voici quelques exemples.

En pratique, les données JSON peuvent être volumineuses et complexes

Cours: JSON

3.5 PHP: json_encode()

En PHP la fonction json_encode() permet de transformer très simplement un tableau (ou un objet) en JSON. Ce JSON est ensuite envoyé au client, qui pourra le décoder simplement en un objet (ou tableau) JavaScript.

Remarquez la fonction "header()".

Toute réponse HTTP contient des données appelées "entêtes". Attention: il ne s'agit pas des entêtes du HTML, mais des informations, cachées, en dehors de tout code HTML.

Dans ces entêtes HTTP, on doit préciser le type de contenu transmis:

Pour du HTML: Content-type: text/html

Pour du JSON : Content-type: application/json

Cours: JSON

3.6 JS : réponse JSON

Voici un exemple simplifié.

Le client demande des données sur l'utilisateur numéro 1234.

Le PHP cherche ces données dans la BDD, les récupère dans un tableau associatif et transforme ce tableau en JSON.

Le JSON est renvoyé au client.jQuery décode le JSON et met l'objet décodé en argument (reponse) de la fonction anonyme.

Remarquez que jQuery est capable de distinguer automatiquement une réponse HTML d'une réponse JSON grâce au Content-Type. Si Content-Type est text/html, reponse sera une chaîne de caractères contenant le HTML. Si c'est application/json, reponse est un objet JS.

Cours: JSON

3.7 Application vs page + JS

Dans l'approche classique, la navigation se fait en cliquant sur des liens ou en appuyant sur des boutons de formulaires. A chaque fois une nouvelle page est visitée. De temps en temps une interaction AJAX peut venir enrichir cette navigation.

À l'autre extrême, dans une application JS, une seule page est chargée et l'utilisateur ne la quitte pas. L'utilisateur interagît avec cette page de manière complexe. Ces interactions sont gérées en JS avec des appels AJAX fréquents.

Cours: JSON

3.8 Application JS

Un exemple d'application JS est gmail. L'utilisateur change de boite mail et ouvre chaque mail sans jamais quitter la page. Toutes ces interactions sont gérées en JS/AJAX.

Les applications JS sont difficiles à écrire. Le développeur doit gérer de nombreuses interactions complexes avec l'utilisateur et synchroniser les données avec le serveur.

Des Frameworks JS, comme AngularJS existent pour faciliter cette tâche. Ces techniques sortent du cadre de ce cours.

4. Exercice JSON : noms

4.1 Exercice JSON : noms

Dans cet exercice, on veut chercher des informations sur un joueur quand on clique sur son nom.

Ces informations (nom, age, score) sont sur le serveur.

Il faut donc utiliser une requête AJAX.

Exercice JSON : noms

4.2 GET ou POST ?

On veut chercher des informations sur un joueur quand on clique sur son nom.

Quelle méthode faut-il utiliser pour la requête AJAX ?

Exercice JSON : noms

4.3 Fichiers

Créez les fichiers suivants

utilisateurs.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>utilisateurs</title>
<link type="text/css" rel="stylesheet" href="utilisateurs.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="utilisateurs.js"></script>
</head>
<body>
<!--------------------->
<ul id="utilisateurs">
<li data-uid="karim" >Karim </li>
<li data-uid="martin">Martin</li>
<li data-uid="leila" >Leïla </li>
<li data-uid="joe" >Joe C.</li>
</ul>

<div id="affichage">
<p>Nom : <span id="nom" ></span> </p>
<p>Age : <span id="age" ></span> ans </p>
<p>Score : <span id="score"></span> </p>
</div>

<!--------------------->
</body>
</html>


utilisateurs.css

body
{
font-family: sans;
}

#utilisateurs
{
width: 150px;
cursor: pointer;
}
#utilisateurs li:hover
{
background-color: #fea;
}

#affichage
{
background-color: white;
width: 200px;
border: 1px solid #aaa;
box-shadow: 1px 1px 2px rgba(0,0,0,.2);
padding: 10px;
}

#affichage p
{
margin: 4px;
}

#affichage span
{
color: #00a;
}


utilisateurs.php

<?php
// Une liste d'utilisateurs, juste pour l'exemple.
// En pratique on chercherait dans une base de données.
$utilisateurs=array(
'joe' =>array('nom'=>'Joe C.','score'=>34,'age'=>22),
'martin'=>array('nom'=>'Martin','score'=>3 ,'age'=>7 ),
'karim' =>array('nom'=>'Karim' ,'score'=>45,'age'=>19),
'leila' =>array('nom'=>'Leïla' ,'score'=>49,'age'=>23),
);



utilisateurs.js

console.log("Ce programme JS vient d'être chargé");
$(document).ready(function()
{
console.log("Le document est pret");

// ......

console.log("La mise en place est finie. En attente d'événements...");
});

Exercice JSON : noms

4.4 uid utilisateur

Faites en sorte que le programme affiche dans la console le uid de l'utilisateur sur lequel on a cliqué.

Exercice JSON : noms

4.5 Correction


console.log("Ce programme JS vient d'être chargé");
$(document).ready(function()
{
console.log("Le document est pret");

$('#utilisateurs li').mousedown(function(e)
{
console.log("Évènement mousedown");
console.log("uid:",$(this).attr('data-uid'));
});

console.log("La mise en place est finie. En attente d'événements...");
});


Exercice JSON : noms

4.6 Entêtes HTTP

Vous devriez voir toutes les requêtes faites lors du chargement de la page.
Il y en a une vingtaine.

La toute première requête correspond à la page HTML elle même.
Les autres sont pour l'essentiel du CSS, du JS et des images.

Cliquez sur le + à gauche de cette première requête.


Exercice JSON : noms

4.7 Console : entêtes http



Cette requête est constituée de :


La requête (du client vers le serveur) est constituée uniquement d'entêtes.
C'est une série d'informations de la forme "nom: valeur".

La réponse est constituée d'entêtes et d'un corps.
Ces entêtes sont aussi de la forme "nom: valeur".
Le corps de la réponse c'est le HTML lui même.

Prenez le temps de regarder les différents onglets pour bien comprendre.

Ces entêtes sont "invisibles" pour l'utilisateur et pour le développeur débutant.
Cependant, elles contiennent des informations souvent importantes.



Dans les entêtes de la réponse de http://moodle.iutv.univ-paris13.fr, quelle est la valeur de "Content-type" ?

Exercice JSON : noms

4.8 Content-type

L'entête "Content-type" permet au serveur de dire au client :

« Le corps de la réponse contient des données au format XYZ »

Content-type est un type MIME


Dans cet exercice le serveur veut envoyer du JSON au client.

En regardant sur votre cours (ou sur le web), quel type MIME faut-il utiliser ?

Exercice JSON : noms

4.9 Content-Type image


Ouvrez l'url suivante dans votre navigateur:

http://moodle.iutv.univ-paris13.fr/img/js/revision6-boites.png

Ouvrez l'onglet Réseau de Firebug et rechargez la page complètement (maj+click sur bouton rechargement).

Regardez les entêtes http de la réponse.

Quel est le Content-Type ?

(n'oubliez pas de forcer le rechargement avec maj+click bouton recharger)

Exercice JSON : noms

4.10 utilisateurs.php

Complétez le fichier utilisateurs.php pour qu'il affiche le JSON correspondant à un utilisateur passé en argument GET.
Par exemple, si en argument GET on a "karim", le programme devra afficher:

{"nom":"Karim","score":45,"age":19,"status":"ok"}

Rappel : la fonction json_encode() permet de transformer un tableau PHP en JSON
Rappel : la fonction header spécifier une entête http :
header('Content-type: application/json');


Exercice JSON : noms

4.11 Correction: utilisateurs.php

utilisateurs.php

<?php

// Une liste d'utilisateurs, juste pour l'exemple.
// En pratique on chercherait dans une base de données.
$utilisateurs=array(
'joe' =>array('nom'=>'Joe C.','score'=>34,'age'=>22),
'martin'=>array('nom'=>'Martin','score'=>3 ,'age'=>7 ),
'karim' =>array('nom'=>'Karim' ,'score'=>45,'age'=>19),
'leila' =>array('nom'=>'Leïla' ,'score'=>49,'age'=>23),
);

$uid=$_GET['uid'];
$reponse=$utilisateurs[$uid];

header('Content-type: application/json');
echo json_encode($reponse);

Exercice JSON : noms

4.12 utilisateurs.js

Dans les outils de développement Firefox vérifiez que le Content-Type renvoyé par utilisateurs.php est bien "application/json".

Maintenant on peut compléter utilisateurs.js :

Faites une requête AJAX pour récupérer les informations sur l'utilisateur cliqué et affichez la réponse avec console.log()

Vérifiez que la réponse est bien un objet (l'objet affiché par console.log() devrait être en vert et vous pouvez cliquer dessus pour le voir dans l'onglet DOM de Firebug).

Ensuite remplissez les différents <span> de l'affichage (<div id="affichage">...</div>) avec les valeurs récupérées.


Exercice JSON : noms

4.13 Correction: utilisateurs.js



 utilisateurs.js

console.log("Ce programme JS vient d'être chargé");
$(document).ready(function()
{
console.log("Le document est pret");
$('#utilisateurs li').mousedown(function(e)
{
console.log("Évènement mousedown");
$.get('http://localhost/~1234567/tp-6/utilisateurs.php',
{uid: $(this).attr('data-uid')},
function(reponse)
{
console.log("Réponse reçue du serveur: ",reponse);
$('#nom' ).text(reponse.nom);
$('#age' ).text(reponse.age);
$('#score').text(reponse.score);
});
});
console.log("La mise en place est finie. En attente d'événements...");
});


Exercice JSON : noms

4.14 Gestion d'erreurs

Ajoutez la ligne suivante à utilisateurs.html

	<li data-uid="nath"  >Nath.</li>

Cet utilisateur n'existe pas dans utilisateurs.php

On veut afficher un alert() avec un message d'erreur quand on clique sur un utilisateurs qui n'existe pas.

Faites la vérification nécessaire dans utilisateurs.php
Dans l'objet JSON renvoyé, ajoutez un champs "ok" qui peut être vrai ou faux.
Ajoutez aussi un champs "message" qui peut contenir un message d'erreur.

Faîtes les modifications nécessaires dans utilisateurs.js

Exercice JSON : noms

4.15 Correction: gestion d'erreurs

utilisateurs.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>utilisateurs-1</title>
<link type="text/css" rel="stylesheet" href="utilisateurs.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="utilisateurs.js"></script>
</head>
<body>
<!--------------------->
<ul id="utilisateurs">
<li data-uid="karim" >Karim </li>
<li data-uid="martin">Martin</li>
<li data-uid="tom" >Tom </li>
<li data-uid="leila" >Leïla </li>
<li data-uid="joe" >Joe C.</li>
<li data-uid="nath" >Nath.</li>
</ul>

<div id="affichage">
<p>Nom : <span id="nom" ></span> </p>
<p>Age : <span id="age" ></span> ans </p>
<p>Score : <span id="score"></span> </p>
</div>

<!--------------------->
</body>
</html>

utilisateurs.js

console.log("Ce programme JS vient d'être chargé");
$(document).ready(function()
{
console.log("Le document est pret");
$('#utilisateurs li').mousedown(function(e)
{
console.log("Évènement mousedown");
$.get('http://localhost/~1234567/tp-6/utilisateurs.php',
{uid: $(this).attr('data-uid')},
function(reponse)
{
console.log("Réponse reçue du serveur: ",reponse);
if(reponse.ok)
{
$('#nom' ).text(reponse.nom);
$('#age' ).text(reponse.age);
$('#score').text(reponse.score);
}
else
{
alert(reponse.message);
}
});
});
console.log("La mise en place est finie. En attente d'événements...");
});

utilisateurs.php

<?php

// Une liste d'utilisateurs, juste pour l'exemple.
// En pratique on chercherait dans une base de données.
$utilisateurs=array(
'joe' =>array('nom'=>'Joe C.','score'=>34,'age'=>22),
'martin'=>array('nom'=>'Martin','score'=>3 ,'age'=>7 ),
'karim' =>array('nom'=>'Karim' ,'score'=>45,'age'=>19),
'leila' =>array('nom'=>'Leïla' ,'score'=>49,'age'=>23),
);
$uid=$_GET['uid'];
if(isset($utilisateurs[$uid]))
{
$reponse=$utilisateurs[$uid];
$reponse['ok']=true;
}
else
{
$reponse=array('ok'=>false,
'message'=>"Cet utilisateur n'existe pas");
}

header('Content-type: application/json');
echo json_encode($reponse);


Exercice JSON : noms

4.16 Popup

On voudrait afficher la boite <div id="affichage">...</div> comme un popup.

C'est à dire : la placer à l'endroit où l'utilisateur à cliqué.

Modifiez utilisateurs.css et utilisateurs.js pour obtenir ce résultat.

Indications

on peut, par exemple, utiliser  :

Fermeture de la boite:
Option simple : on veut fermer le popup quand on clique dessus.
Option plus compliquée (pas indispensable) : on ferme le popup si on clique n'importe où dans l'écran (sauf sur un utilisateur).

Rappel :


http://moodle.iutv.univ-paris13.fr/img/web/webs1-tp-5-2.png

Quand un élément (ici l'image) a « position: absolute », il n'affecte plus du tout le positionnement des autres éléments ou texte autour. Il s'affiche donc « par-dessus » ou « par-dessous » les éléments l'entourant.

Tout seul « position: absolute » n'est pas très utile. Par contre, une fois qu'un élément est « position: absolute », on peut le déplacer facilement avec les propriétés « top, left, right, bottom »:

http://moodle.iutv.univ-paris13.fr/img/web/webs1-tp-5-3.png


Exercice JSON : noms

4.17 Correction

utilisateurs.css

...
#affichage
{
position: absolute;
display: none;
...

utilisateurs.js

console.log("Ce programme JS vient d'être chargé");
$(document).ready(function()
{
console.log("Le document est pret");
$('#utilisateurs li').mousedown(function(e)
{
console.log("Évènement mousedown sur li");
$('#affichage').hide();
$.get('http://localhost/~1234567/tp-6/utilisateurs.php',
{uid: $(this).attr('data-uid')},
function(reponse)
{
console.log("Réponse reçue du serveur: ",reponse);
if(reponse.ok)
{
$('#nom' ).text(reponse.nom);
$('#age' ).text(reponse.age);
$('#score').text(reponse.score);
$('#affichage').show();
$('#affichage').offset({left: e.pageX,top:e.pageY});
}
else
{
alert(reponse.message);
}
});
});

// Fermer la boite si on clique n'importe où dans la page (sauf sur un utilisateur)
$('html').mousedown(function(e)
{
console.log("Évènement mousedown sur html");
if(!$(e.target).is('#utilisateurs li'))
{
$('#affichage').hide();
}
});


console.log("La mise en place est finie. En attente d'événements...");
});

5. Cours: DOM

5.1 Cours: DOM

Si vous venez d'assister au cours magistral, passez à la section suivante.

Cours: DOM

5.2 jQuery vs DOM

Jusqu'ici on a écrit nos programmes en utilisant presqu'exclusivement jQuery. jQuery est une surcouche par-dessus le DOM. Le DOM est l'API native permettant d’interagir avec le navigateur. jQuery n'est pas indispensable.

jQuery facilite énormément le travail. Non seulement le code est beaucoup plus simple et court à écrire, mais en plus, jQuery s'occupe des différences entre navigateurs (ie, Firefox, Chrome, ...).

Cependant, jQuery a un prix:- le téléchargement de jQuery peut prendre quelque temps.- le traitement / exécution de jQuery peut être long sur des machines peu puissantes (mobile 400ms!).

Même si on utilise jQuery, on a parfois besoin d'accéder à des propriétés ou des fonctions du DOM.

La manipulation de texte nécessite de manipuler les Text Node du DOM.

Dans des environnements où jQuery n'est pas disponible (ex: extension Firefox, page critique performance).

Cours: DOM

5.3 Navigateurs

Le développement JS nécessite de vérifier en permanence le bon fonctionnement du code sur les principaux navigateurs du public visé. jQuery masque beaucoup de différences.

Le support des versions anciennes de ie ou certains mobiles peut-être une difficulté majeure qui peut modifier profondément des choix de développement.

Des différences, moindres, mais significatives existent entre Chrome, Firefox, Safari et aussi entre entre différentes versions de chacun de ces navigateurs.

Cours: DOM

5.4 Compatibilité

Des sites comme caniuse.com ou MDN fournissent des tables de compatibilité pour chaque technologie et pour chaque navigateur.

Il est indispensable de consulter ces tables quand on utilise une fonctionnalité (JS ou CSS), surtout si la fonctionnalité est récente.

Cours: DOM

5.5 Principaux objets DOM

Voici 3 types d'objets DOM importants:

- window : la fenêtre d'un document. S'il y a plusieurs onglets, chaque onglet a son window.

- document : à l'intérieur du window, contient l'arbre DOM issu du HTML.

- HTMLElement : la plupart des noeuds de l'arbre qu'on manipulera sont de type HTMLElement

Cours: DOM

5.6 Window & Document

L'objet "window" contient de nombreuses propriétés et méthodes. L'une d’entre-elles s’appelle "document" et donne accès à l’arbre DOM.

document est la racine de l'arbre DOM. Il ne figure pas dans le code HTML. Dans le DOM, il se trouve au-dessus de l'élément <html>.

document fourni aussi de nombreuses propriétés et méthodes. Certaines permettent d'accéder aux éléments de l'arbre DOM.

Cours: DOM

5.7 document.getElementById()

La fonction getElementById() permet de chercher l'élément ayant un id fourni en argument. Par définition cet élément est unique.

Ici "d" est un objet DOM.

L'équivalent en jQuery est $('#photo').

Remarquez que le type est différent. "j" est une liste jQuery (avec un seul élément), alors que "d" est un objet DOM.

On verra plus tard que l'on peut passer d'un type à l'autre.

Cours: DOM

5.8 document.createElement()

La fonction .createElement() permet de créer un élément.

Il est important de bien garder à l'esprit que cet élément n'est pas encore inséré dans l'arbre DOM. Pour l'instant il existe tout seul, sans parents, ni enfants.

jQuery permet d'obtenir un résultat similaire avec $('<p></p>'). jQuery est beaucoup plus puissant: on peut spécifier du code HTML complexe et donc créer directement de nombreux éléments.

Une fois de plus, "j" est une liste jQuery (avec un seul élément), alors que "d" est un objet DOM.

Cours: DOM

5.9 node.appendChild()

Une fois qu'un élément est crée, on peut l'insérer dans l'arbre DOM.

La fonction DOM appendChild() permet de le faire. Remarquez que dans cet exemple on utilise document.body qui permet d’accéder directement à l'élément <body>.

En jQuery, on obtient un résultat similaire avec .append()

Cours: DOM

5.10 DOM & jQuery

On peut facilement passer d'une liste jQuery contenant un seul élément à l'objet DOM.

Cours: DOM

5.11 Node / HTMLElement

Le DOM est une norme indépendante du langage de programmation qui défini une hiérarchie de classes (la notion de classe n’existe pas telle quelle en JS).

La plupart du temps on manipulera des objets DOM de type HTMLElement.

Node est l'interface définissant les opérations d'arbre (parent, enfants, frères).

Text représente du texte.

Un HTMLElement "est un" Node.

Un document "est un" Node.Un Text "est un" Node.

Ces trois types peuvent donc être insérés dans un arbre.

Cours: DOM

5.12 Text

Dans les schémas d'arbre DOM on omet souvent de montrer le texte.

En réalité, dans l'arbre DOM, le texte est contenu dans des Text Node.

On peut manipuler les Text Node comme les autres Node.

jQuery ne fourni qu'un accès très limité aux Text Node.

Quand on veut manipuler du texte (par exemple couper le texte d'un paragraphe en deux paragraphes), on utilise le DOM plutôt que jQuery.

Cours: DOM

5.13 Node & HTMLElement

Node et HTMLElement fournissent de très nombreuse propriétés et méthodes.

Cours: DOM

5.14 element.className

En HTML, l'attribut class peut contenir plusieurs classes séparées par des espaces.

Pour accéder à la classe d'un élément DOM on utilise className (en effet, "class" est un nom réservé du JS).

className donne la classe en entier. Ce n'est pas très pratique pour manipuler des classes multiples.

jQuery fourni des fonctions beaucoup plus pratiques, pour vérifier, ajouter et retirer des classes.

Cours: DOM

5.15 node.parentNode

Le parcours de l'arbre DOM est une opération de base, très fréquente.

Ici on veut remonter au parent d'un élément.

Cours: DOM

5.16 node.children

Les fils directs (fils immédiats) sont donnés par .children ou .childNodes ".children" omet les Text Nodes.

Ces deux propriétés donnent une liste, qui peut-être manipulée comme un tableau (liste.length liste[n] ...)

Cours: DOM

5.17 element.addEventListener()

La fonction addEventListener permet d'ajouter un gestionnaire d'événements à un élément. (Rappel: le gestionnaire d'événements est une fonction qui est appelée quand un événement survient.)

addEventListener() ajoute un gestionnaire à un seul élément. Il faut donc appeler addEventListener() sur chaque élément visé.

L'approche jQuery est beaucoup plus pratique.

6. Questions DOM

6.1 Questions DOM

On va commencer cette partie avec quelques questions sur le cours précédent.

Questions DOM

6.2 Navigateurs

Quel est le navigateur le plus utilisé en ce moment (2018) ?

Questions DOM

6.3 Mobile

En moyenne, quel pourcentage des visiteurs d'un site web sont sur un navigateur mobile ?

(nombre approximatif entre 0 et 100)

Questions DOM

6.4 Can I Use

A partir de quelle version de Internet Explorer (IE) peut-on utiliser la fonctionnalité appelée " XMLHttpRequest" (level 2 / advanced features) ?

Vous pouvez chercher sur :
http://caniuse.com/

Questions DOM

6.5 Can I use ?


Sur quels navigateurs peut-on utiliser un champs input de type color (Color input type) ?

HTML:
<input type="color"/>

(exemple d'affichage à droite)

Questions DOM

6.6 DOM

Dans l'arbre DOM, quel est l'élément parent de l'élément <body> ?

(juste le nom)


Questions DOM

6.7 Arbre DOM

Dans l'arbre DOM, quel est l'élément parent de l'élément <html> ?

(juste le nom)

Questions DOM

6.8 jQuery équivalent DOM

Quel est l'équivalent DOM de l'expression jQuery suivante :

$('#affichage')



Questions DOM

6.9 DOM: className

var d=document.getElementById('affichage');
XXXX

Que faut-il écrire en DOM à la place de XXXX pour transformer ceci:

<div id="affichage">...</div>

en ceci:

<div id="affichage" class="urgent">...</div>

(sans utiliser jQuery)

Questions DOM

6.10 parentNode()

var d=document.getElementById('affichage');
XXXX

Que faut-il écrire en DOM à la place de XXXX pour transformer ceci:

<div>
<div id="affichage">...</div>
</div>

en ceci:

<div class="urgent">
<div id="affichage">...</div>
<div>

(sans utiliser jQuery)

Indication: il faut enchaîner des opérations.

Questions DOM

6.11 children

var d=document.getElementById('affichage');
XXXX

Que faut-il écrire en DOM à la place de XXXX pour transformer ceci:

<div id="affichage">
<span></span>
<span></span>
<span></span>
</div>

en ceci:

<div id="affichage">
<span></span>
<span class="urgent"></span>
<span></span>
</div>

(sans utiliser jQuery)

Indication: il faut enchaîner des opérations

Questions DOM

6.12 addEventListener

var d=document.getElementById('affichage');
XXXX

function reagir_click()
{
console.log("L'utilisateur a cliqué sur le div");
}

HTML:

<div id="affichage"></div>

Quel faut-il écrire en DOM à la place de XXXX pour que la fonction reagir_click soit appelée quand l'utilisateur clique sur ce div.
(sans utiliser jQuery)

7. Hello DOM world

7.1 Hello DOM world

Dans les pages suivantes, nous allons écrire, ensemble, un premier programme DOM très simple.


Hello DOM world

7.2 Fichiers

Créez les deux fichiers suivants:

hello-dom.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>hello-dom</title>
<script src="hello-dom.js"></script>
</head>
<body>
<!--------------------->
<h1 id="titre">Hello DOM world !</h1>
<!--------------------->
</body>
</html>

hello-dom.js

console.log("Ce programme JS vient d'être chargé");


Hello DOM world

7.3 Document ready

En jQuery on écrivait :

$(document).ready(function(){ ... });

Ceci dit au navigateur : « appelle ma fonction quand le document sera prêt ».

Si on n'attendait pas, le JS serait exécuté tout de suite, avant même que l'arbre DOM soit construit.
On ne pourrais donc pas accèder à l'arbre DOM...

"ready" n'est pas un "vrai" événement DOM. C'est une simplification de jQuery.
En DOM on utilise un événement appelée "DOMContentLoaded" .

On a vu en cours la fonction "addEventListener" qui permet de gérer les événements.

Complétez hello-dom.js  pour afficher "Le document est pret" dans la console, quand le document est pret.

Hello DOM world

7.4 Correction

hello-dom.js

console.log("Ce programme JS vient d'être chargé");

document.addEventListener("DOMContentLoaded", function()
{
console.log("Le document est pret");
});

Remarque: ceci ne marche pas sur IE 8 ou antérieur.

Hello DOM world

7.5 Click -> rouge

Quand l'utilisateur clique sur le titre, on voudrait changer sa couleur en rouge.

Indications

Les éléments DOM ont une propriété appelée style qui correspond à l'attribut style de l'élément HTML.

Par exemple :

<div id="exemple">...</div>

Avec :

var d=document.getElementById('exemple');
d.style.margin="20px";

le HTML devient

<div id="exemple" style="margin: 20px">...</div>

Pour les propriétés CSS ayant des noms contenant des tirets, on utilise soit:

d.style.marginLeft="20px";

soit

d.style['margin-left']="20px";




Hello DOM world

7.6 Correction


console.log("Ce programme JS vient d'être chargé");

document.addEventListener("DOMContentLoaded", function()
{
console.log("Le document est pret");

var titre=document.getElementById('titre');

titre.addEventListener("mousedown", function(e)
{
console.log("Le bouton de la souris a été enfoncé.");
this.style.color="red";
});

});

8. Morpion DOM

8.1 Morpion DOM

Dans les pages suivantes, nous allons re-écrire, ensemble, le programme morpion, sans utiliser jQuery.


Morpion DOM

8.2 Fichiers

Créez les 3 fichiers suivants:

morpion.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>morpion</title>
<link type="text/css" rel="stylesheet" href="morpion.css"/>
<script src="morpion.js"></script>
</head>
<body>
<!--------------------->
<table id="morpion">
<tr><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td></tr>
</table>
<!--------------------->
</body>
</html>

morpion.css

#morpion 
{
border-collapse: collapse;
}

#morpion td
{
border: 1px solid black;
width: 40px;
height: 40px;
font-size: 30px;
text-align: center;
cursor: pointer;
}

#morpion td:hover
{
background-color: #ffc;
}

morpion.js

console.log("Ce programme JS vient d'être chargé");

document.addEventListener("DOMContentLoaded", function()
{
console.log("Le document est pret");
var joueur="X";

});

Morpion DOM

8.3 jQuery: multiple

En jQuery nous avions géré l'événement mousedown sur les cases du tableau comme ceci:

	$('#morpion td').mousedown(function(){...});

A combien d'éléments est affecté le gestionnaire d'événements ?

Morpion DOM

8.4 Gestionnaire d’événements

En effet, en interne, jQuery parcourt toute la liste des 9 cases et installe appelle addEventListener sur chaque case.

C'est un peu lourd à faire en DOM.

On va utiliser une astuce : le bubbling.

On va utiliser un seul addEventListener sur le tableau lui-même.
Les événements sur les cases remontent (bubbling) jusqu'au tableau.
Pensez à utiliser "event.target" et non pas "this"

Inspirez vous de la version jQuery.

Indication:

pour lire ou modifier le texte dans un élément, utilisez element.textContent


Morpion DOM

8.5 Correction

morpion.js

console.log("Ce programme JS vient d'être chargé");

document.addEventListener("DOMContentLoaded", function()
{
console.log("Le document est pret");
var joueur="X";
document.getElementById('morpion').addEventListener("mousedown", function(e)
{
console.log("Le bouton de la souris a été enfoncé.");
var td=e.target;
if(td.textContent!==''){return;}
td.textContent=joueur;
joueur=(joueur==="X" ? 'O' : 'X');
});

});

9. Commentaires : formulaire AJAX

9.1 Commentaires : formulaire AJAX


Dans les pages suivantes, on va créer, ensemble, un formulaire AJAX permettant d'ajouter un commentaire dans un forum.

(On utilisera jQuery)


Commentaires : formulaire AJAX

9.2 Fichiers

Créez les fichiers suivants :

(Les parties modifiées par rapport au TP-5 sont en noir)

commentaires.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>commentaires</title>
<link type="text/css" rel="stylesheet" href="commentaires.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="commentaires.js"></script>
</head>
<body>
<!--------------------->
<div id="principal">
<h2>Cours de JavaScript : Ajax</h2>
<img src="http://moodle.iutv.univ-paris13.fr/img/js/exo-commentaires-video.png"/>
</div>
<div id="block-commentaires">
<h3>Commentaires</h3>
<select id="pages">
<option value="0" > 1 à 5</option>
<option value="5" > 6 à 10</option>
<option value="10">11 à 15</option>
<option value="15">16 à 20</option>
</select>
<div id="commentaires">
</div>
<a id="reinitialiser" href="commentaires.php?reinitialiser">réinitialiser</a>
</div>
<div id="formulaire">
<p><label>Nom : <input id="nom" type="text"/></label></p>
<p><label>Commentaire :<br/><textarea id="contenu" ></textarea></p>
<p><input id="ajouter" type="button" value="ajouter"/></p>
</div>

<!--------------------->
</body>
</html>

commentaires.css

body
{
font-family: sans;
width: 600px;
margin-left: auto;
margin-right: auto;
background-color: #eee;
}
#principal
{
background-color: white;
padding: 10px;
}

#principal img
{
width: 580px;
height: auto;
}

#block-commentaires
{
background-color: white;
min-height: 300px;
padding: 10px;
margin-top: 10px;
font-size: 14px;
}

#pages-commentaires
{
}

#commentaires
{
margin-top: 10px;
}

.commentaire
{
margin: 19px 0;
}
.commentaire .nom
{
color: #2793E6;
font-weight: bold;
margin-right: 13px;
}
.commentaire .date
{
color: #888;
}

.commentaire .contenu-com
{
margin: 3px 0;
}

.commentaire .pied-com
{
font-size: 11px;
color: #888;
line-height: 20px;
}

.commentaire .repondre
{
font-weight: bold;
}

.commentaire .jaime
{
font-size: 13px;
color: #2793E6;
}

.commentaire .jaime-plus
{
display: inline-block;
width: 18px;
height: 18px;
background-image: url(http://moodle.iutv.univ-paris13.fr/img/js/ytp.png);
vertical-align: middle;
}

.commentaire .jaime-moins
{
display: inline-block;
width: 18px;
height: 18px;
background-image: url(http://moodle.iutv.univ-paris13.fr/img/js/ytm.png);
vertical-align: middle;
}

#reinitialiser
{
font-size: 10px;
float: right;
}

#formulaire
{
background-color: white;
width: 300px;
border: 1px solid #aaa;
box-shadow: 1px 1px 2px rgba(0,0,0,.2);
padding: 10px;
}
#formulaire p
{
margin: 5px 0;
}
#nom
{
width: 230px;
}

#contenu
{
width: 100%;
}
#contenu
{
width: 290px;
}

commentaires.js (pas de modification)

console.log("Ce programme JS vient d'être chargé");
$(document).ready(function()
{
console.log("Le document est pret");
$('#pages').change(function()
{
$.get('http://localhost/~1234567/tp-6/commentaires.php',
{debut: parseInt($('#pages').val()),
fin: parseInt($('#pages').val())+4,
},
function(reponse)
{
console.log("Une réponse a été reçue du serveur");
$('#commentaires').html(reponse);
});
});
$('#pages').change();

$('#commentaires').on('mousedown','.jaime-plus',function(e)
{
// éviter la sélection désagréable quand on clique
e.preventDefault();
var commentaire=$(this).parent().parent();
var idCommentaire=parseInt(commentaire.attr('data-com-id'));
$.post('http://localhost/~1234567/tp-6/commentaires-jaime.php',
{
id: idCommentaire,
sens: 1,
},
function(reponse)
{
console.log('Réponse recue:',reponse);
if(reponse==='ok')
{
var jaime=commentaire.find('.jaime');
var val=jaime.text()==='' ? 0 : parseInt(jaime.text());
jaime.text(val+1);
}
});
});
});

commentaires.php (pas de modification)

<?php

session_start();
setlocale(LC_TIME, "fr_FR.utf8");
header('Content-Type: text/html; charset=utf-8');
require_once 'commentaires-fonctions.php';

// Cas particulier: réinitialiser les commentaires
if(isset($_GET['reinitialiser']))
{
reinitialiser_commentaires();
die('Commentaires réinitialisés ok.');
}

// Chercher tous les commentaires et trier
$commentaires=commentaires();
$commentaires=trier_par_date($commentaires);

// Lire les données GET envoyées par le client
$debut=(int)$_GET['debut'];
$fin =(int)$_GET['fin' ];

// Construire le HTML à envoyer au client
$html='';
for($i=$debut;$i<=$fin;$i++)
{
$com=$commentaires[$i];
$html.=commentaire_rendu_en_html($com);
$html.="\n";
}
// Envoyer le HTML au client
echo $html;

commentaires-fonctions.php (pas de modification)

<?php

// Racourci pour éviter les problèmes d'affichage des caractères HTML (<>&'") et les failles de sécurité XSS
function e($texte)
{
return htmlspecialchars($texte,ENT_QUOTES,'UTF-8');
}

// Trier par date déscendante
function trier_par_date($c)
{
usort($c,'s');
return $c;
}

function s($a, $b){return $a['date'] == $b['date'] ? 0 : (($a['date'] < $b['date']) ? 1 : -1);}

// La liste des commentaires.
// Les commentaires sont stockés dans la variable de SESSION.
// C'est pratique pour le TP, ca nous évite d'avoir besoin d'une base de données.
// Bien évidemment, ca ne marche pas du tout pour une vraie application.
function commentaires()
{
if(!isset($_SESSION['commentaires']))
{
$_SESSION['commentaires']=liste_initiale_commentaires();
}
return $_SESSION['commentaires'];
}

function reinitialiser_commentaires()
{
$_SESSION['commentaires']=liste_initiale_commentaires();
}

// Enregister la liste des commentaires.
// Les commentaires sont stockés dans la variable de SESSION.
// C'est pratique pour le TP, ca nous évite d'avoir besoin d'une base de données.
// Bien évidemment, ca ne marche pas du tout pour une vraie application.
function enregistrer_commentaires($commentaires)
{
$_SESSION['commentaires']=$commentaires;
}

function liste_initiale_commentaires()
{
return
array(
array('id'=>101,'nom'=>'Karim','date'=>1425283400,'contenu'=>"J'aime beaucoup ces cours de JavaScript !",'jaime'=>5),
array('id'=>102,'nom'=>'Joe' ,'date'=>1425283700,'contenu'=>"Ah bon ? Moi je préfère les tartes aux fraises.",'jaime'=>-1),
array('id'=>103,'nom'=>'Karim','date'=>1425284060,'contenu'=>"T'es pas sur Marmiton là...",'jaime'=>-4),
array('id'=>104,'nom'=>'Driss','date'=>1425284080,'contenu'=>"T'as compris quelque chose à Ajax ?",'jaime'=>0),
array('id'=>105,'nom'=>'Lian' ,'date'=>1425284120,'contenu'=>"Ouais... c'est facile avec jQuery.",'jaime'=>2),
array('id'=>106,'nom'=>'Naïma','date'=>1425284320,'contenu'=>"Ces trucs de client / serveur ca m'embrouille.",'jaime'=>0),
array('id'=>107,'nom'=>'Lian' ,'date'=>1425284520,'contenu'=>"C'est simple... le client c'est le JS ... et le serveur le PHP.",'jaime'=>1),
array('id'=>108,'nom'=>'Naïma','date'=>1425284620,'contenu'=>"Oui, mais le HTML, il est où ?",'jaime'=>0),
array('id'=>109,'nom'=>'Driss','date'=>1425284820,'contenu'=>"Dans la base de données, évidemment.",'jaime'=>-8),
array('id'=>110,'nom'=>'Karim','date'=>1425284920,'contenu'=>"Mais non! T'as rien compris.",'jaime'=>-1),
array('id'=>111,'nom'=>'Lian' ,'date'=>1425285120,'contenu'=>"Le HTML est envoyé par le serveur au navigateur.",'jaime'=>1),
array('id'=>112,'nom'=>'Driss','date'=>1425285180,'contenu'=>"Elle sert à quoi alors la BDD ?",'jaime'=>0),
array('id'=>113,'nom'=>'Karim','date'=>1425285120,'contenu'=>"Le PHP prend les infos de la BDD, fait du HTML avec et l'envoie au navigateur.",'jaime'=>5),
array('id'=>114,'nom'=>'Joe' ,'date'=>1425285220,'contenu'=>"J'ai faim.",'jaime'=>-5),
array('id'=>115,'nom'=>'Naïma','date'=>1425285320,'contenu'=>"C'est bientot la pause ?",'jaime'=>2),
array('id'=>116,'nom'=>'Joe' ,'date'=>1425285420,'contenu'=>"Encore 5 minutes...",'jaime'=>0),
array('id'=>117,'nom'=>'Lian' ,'date'=>1425285620,'contenu'=>"Vous pensez qu'à manger.",'jaime'=>0),
array('id'=>118,'nom'=>'Karim','date'=>1425285720,'contenu'=>"C'est la pause :-)",'jaime'=>10),
array('id'=>119,'nom'=>'Lian' ,'date'=>1425285750,'contenu'=>"Moi je reste travailler.",'jaime'=>-4),
array('id'=>120,'nom'=>'Naïma','date'=>1425285770,'contenu'=>"Chacun son truc...",'jaime'=>0),
);
}

// Renvoyer l'indice dans le tableau du commentaire ayant l'id $id
function commentaires_chercher_cle_de_id($commentaires,$id)
{
foreach($commentaires as $k=>$c){if($c['id']==$id){return $k;}}
return false;
}

// Retourne le HTML nécessaire pour afficher un seul commentaire.
function commentaire_rendu_en_html($com)
{
return
'<div class="commentaire" data-com-id="'.$com['id'].'">'."\n".
' <div class="entete-com">'."\n".
' <span class="nom" >'.e($com['nom']).'</span>'."\n".
' <span class="date">'.strftime('%e %b, %H:%M',$com['date']).'</span></div>'."\n".
' <div class="contenu-com">'.e($com['contenu']).'</div>'."\n".
' <div class="pied-com">'."\n".
' <span class="repondre">Répondre</span> '."\n".
' <span class="jaime">'.($com['jaime']!==0 ? $com['jaime'] : '').'</span> '."\n".
' <span class="jaime-plus"></span> '."\n".
' <span class="jaime-moins"></span> '."\n".
' </div>'."\n".
'</div>'."\n";
}

commentaires-jaime.php (pas de modification)

<?php

session_start();
require_once 'commentaires-fonctions.php';

// Chercher tous les commentaires
$commentaires=commentaires();

$id=(int)$_POST['id'];
$cle=commentaires_chercher_cle_de_id($commentaires,$id);
if($cle===false){echo 'erreur';exit(1);}
$sens=(int)$_POST['sens'];
if($sens!==1 && $sens!==-1){echo 'erreur';exit(1);}
$commentaires[$cle]['jaime']+=$sens;

enregistrer_commentaires($commentaires);

echo 'ok';

commentaires-ajouter.php (nouveau fichier)

<?php

session_start();
require_once 'commentaires-fonctions.php';

// Chercher tous les commentaires
$commentaires=commentaires();

// ...

enregistrer_commentaires($commentaires);

echo 'ok';

Commentaires : formulaire AJAX

9.3 Popup

Dans ces exercices, travaillez toujours sur le serveur, y compris pour les fichiers html
 http://localhost/~1234567/.../commentaires.html

Actuellement, le formulaire est affiché en bas de la page.

On voudrait qu'il soit caché par défaut.

Quand l'utilisateur clique sur un des <span> "Répondre", on voudrait afficher le formulaire dnas un "popup" à l'endroit où l'utilisateur à cliqué.

En vous inspirant de l'exercice au début du TP-6, ajoutez le CSS et le JS nécessaire.

Indications :

Souvenez-vous que les commentaires affichés sont crées après le démarrage de la page.
Vous ne pouvez donc pas ajouter directement ajouter un gestionnaire d'événements aux <span> "Répondre".
Utilisez la fonction .on() vue au TP-5 (il y a déjà un exemple dans commentaires.js)

Comme le même formulaire peut-être réutilisé, pensez à effacer son contenu avant de l'afficher.



Commentaires : formulaire AJAX

9.4 Correction

commentaires.css

...
#formulaire
{
position: absolute;
display: none;
...

commentaires.js

...
$('#commentaires').on('mousedown','.repondre',function(e)
{
$('#nom').val('');
$('#contenu').val('');
$('#formulaire').show();
$('#formulaire').offset({left: e.pageX,top: e.pageY});
});
...

Commentaires : formulaire AJAX

9.5 Bouton ajouter

Quand l'utilisateur clique sur le bouton ajouter, on voudrait envoyer le contenu du formulaire au serveur en utilisant une requête AJAX.

Quel méthode faut-il utiliser ?

Commentaires : formulaire AJAX

9.6 Bouton ajouter

Quand l'utilisateur clique sur le bouton ajouter, on voudrait envoyer le contenu du formulaire au serveur en utilisant une requête AJAX.

Coté client

On doit :

1) Faire une requête POST  vers commentaires-ajouter.php

2) Envoyer  dans cette requête les données contenus dans les champs nom et contenu du formulaire

3) Quand la réponse du serveur arrive on doit cacher le formulaire et re-afficher les commentaires (utilisez la même astuce qu'au démarrage de la page)

Coté serveur

Dans commentaires-ajouter.php on doit :

1) Recevoir les données POST

2) Créer un nouveau commentaire avec les données nécessaires

3) ajouter ce commentaire à la liste de tous les commentaires

Indications pour l'étape serveur 2) :

Utilisez la fonction PHP time() pour obtenir l'heure actuelle (en secondes depuis le 1/1/1970)
Pour le champs id, calculez l'id maximum de tous les commentaires existants et ajoutez 1.


Commentaires : formulaire AJAX

9.7 Correction

commentaires.js

console.log("Ce programme JS vient d'être chargé");
$(document).ready(function()
{
console.log("Le document est pret");
$('#pages').change(function()
{
$.get('http://localhost/~1234567/tp-6/commentaires.php',
{debut: parseInt($('#pages').val()),
fin: parseInt($('#pages').val())+4,
},
function(reponse)
{
console.log("Une réponse a été reçue du serveur");
$('#commentaires').html(reponse);
});
});
$('#pages').change();

$('#commentaires').on('mousedown','.jaime-plus',function(e)
{
// éviter la sélection désagréable quand on clique
e.preventDefault();
var commentaire=$(this).parent().parent();
var idCommentaire=parseInt(commentaire.attr('data-com-id'));
$.post('http://localhost/~1234567/tp-6/commentaires-jaime.php',
{
id: idCommentaire,
sens: 1,
},
function(reponse)
{
console.log('Réponse recue:',reponse);
if(reponse==='ok')
{
var jaime=commentaire.find('.jaime');
var val=jaime.text()==='' ? 0 : parseInt(jaime.text());
jaime.text(val+1);
}
});
});

$('#commentaires').on('mousedown','.repondre',function(e)
{
// Seulement bouton souris gauche
if(e.which!==1){return;}
$('#nom').val('');
$('#contenu').val('');
$('#formulaire').show();
$('#formulaire').offset({left: e.pageX,top: e.pageY});
});

$('#ajouter').click(function(e)
{
$.post('http://localhost/~1234567/tp-6/commentaires-ajouter.php',
{
nom: $('#nom').val(),
contenu: $('#contenu').val()
},
function(reponse)
{
$('#formulaire').hide();
$('#pages').change();
});
});

});

commentaires-ajouter.php

<?php

session_start();
require_once 'commentaires-fonctions.php';

// Chercher tous les commentaires
$commentaires=commentaires();

$nom =$_POST['nom'];
$contenu=$_POST['contenu'];
$maxId=0;
foreach($commentaires as $commentaire){$maxId=max($maxId,$commentaire['id']);}
$commentaire=array('id'=>$maxId+1,
'nom'=>$nom,
'date'=>time(),
'contenu'=>$contenu,
'jaime'=>0);
$commentaires[]=$commentaire;
enregistrer_commentaires($commentaires);

echo 'ok';