Etape 1: Comment va fonctionner notre script?
Tout d’abord nous allons réaliser une fonction Javascript qui effectuera une requête Ajax de type GET et qui ajoutera dynamiquement dans la BDD un message. Au passage, notre table comportera les champs id, date, pseudo et texte. Voici son script pour la créer:
[SQL]CREATE TABLE `demo_chat` (
`id` int(10) unsigned NOT NULL auto_increment,
`pseudo` varchar(50) NOT NULL default »,
`texte` tinytext NOT NULL,
`date` datetime NOT NULL default ’0000-00-00 00:00:00′,
PRIMARY KEY (`id`)
) TYPE=MyISAM AUTO_INCREMENT=1 ;
[/SQL]
Puis toutes les 2 secondes nous allons demander au serveur d’afficher les messages qui sont nouveaux: Il y ‘aura donc 2 cas: soit le script vient de se lancer et l’on veut récupérer les 5 derniers messages, soit on veut récupérer les messages supérieurs à un identifiant donné (et auquel cas on devra connaître précisément cet identifiant).
Etape 2: Création de la base HTML
Voici le document HTML sur lequel nous allons nous baser, vous pouvez noter que j’inclus la librairie Jquery 1.3.1 comme dans le tuto précédent mais aussi un autre fichier tchat.js qui comportera les différentes fonctions javascript propre au tchat que nous allons réaliser par la suite.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr" dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Tchat Jquery</title>
<link rel="stylesheet" href="design.css" type="text/css" media="screen, projection" />
<script src="jquery-1.3.1.min.js" type="text/javascript"></script>
<script src="tchat.js" type="text/javascript"></script>
</head>
<body>
<div id="chat">
<h2>Chat cool</h2>
<ul id="listemessages">
</ul>
<form action="javascript:envoyerMessage()">
<input type="text" value="Pseudo" id="pseudo" />
<textarea id="texte">Votre message ici </textarea>
<input type="submit" value="Envoyer" />
</form>
Et enfin voici la CSS correspondante:
#chat{
margin:0 auto;
padding:0;
width:220px;
min-height:300px;
background-color:#fafafa;
border-radius:1em;
border:1px solid #ccc;
-moz-border-radius:1em;
font-family:arial;
color:#888;
}
#chat h2{
margin:0;
text-indent:-9999px;
width:137px;
height:20px;
background:url('snoupix-tchat.png') no-repeat;
margin:5px auto;
}
#listemessages{
list-style-type:none;
padding:0;
margin:0 auto;
width:200px;
font-size:0.8em;
}
#listemessages .pseudo{
font-weight:bold;
}
#listemessages .date{
font-size:0.8em;
}
#listemessages p{
margin:0;
margin-bottom:5px;
padding:0;
}
form{
margin:auto;
}
form *{
font-family:'arial';
font-size:0.7em;
}
form input, form textarea{
display:block;
width:200px;
margin:5px auto;
padding:0;
border:1px solid #ccc;
}
Etape 3: Ajout d’un message dans la BDD
Vous l’aurez peut-être remarqué dans le code HTML, le formulaire possède un attribut action qui renvoit vers une fonction javascript, le navigateur peut le différencier car on lui ajoute la valeur « javascript: » devant la fonction.
Cette étape va donc consister à compléter la fonction envoyerMessage(), qui récupèrera les valeurs du formulaire et demandera au serveur de les ajouter dans la BDD. Cette fonction se trouve dans le fichier tchat.js:
function envoyerMessage(){
$.get('script.php',{
pseudo: $('#pseudo').val(),
texte: $('#texte').val()
},function(data){
if(data != '1'){
alert('Votre message n\'a pas été correctement transmis');
}
});
}
Cette requête va être très semblable à celle effectuée dans le tuto précédent, à la seule différence qu’au lieu de supprimer dans la BDD, nous allons ajouter (faire un INSERT INTO en SQL). Notre script PHP nous renverra 1 si l’insertion s’est correctement passée:
<?php require 'config.php'; $connect = mysql_connect(MYHOST,MYUSER,MYPASS); mysql_select_db(MYDB); if($_GET['pseudo']){ $pseudo = mysql_escape_string($_GET['pseudo']); $texte = mysql_escape_string($_GET['texte']); $requete = "INSERT INTO demo_chat(pseudo,texte,date) VALUES('".$pseudo."','".$texte."','".date('Y-m-d H:i:s')."')"; if(mysql_query($requete)) echo '1'; else echo '2'; mysql_close($connect); } ?>
Le fichier config.php pour se connecter est semblable au tutoriel précédent. Ici, nous effectuerons simplement une requête de type INSERT INTO en reprenant nos variables issues de la superglobale GET, et en insérant de la même façon la date actuelle, à l’aide de la fonction date() prenant en paramètre le format (ici le format SQL (année-mois-jour heure:minute:secondes)).
Etape 4: Raffraichir les messages
Le principe ici est d’éxécuter une fonction javascript toutes les 2 secondes qui va récupérer tous les nouveaux messages dans un format XML. Dans notre fichier tchat.js nous aurons donc ce type de code:
$(document).ready(function(){
raffraichirMessages(0);
setInterval('raffraichirMessages()',2000);
});
function raffraichirMessages(id){
//code à venir
}
$(document).ready(function()… sera éxécuté dés la fin du chargement de la page, nous incluerons donc la fonction raffraichirMessages(0) (qui initialisera les messages), la fonction raffraichirMessages prend en paramètre l’identifiant du dernier message se trouvant déjà dans notre page, étant donné qu’on en a aucun, on le met à 0…
Etape 5: Récupérer les messages
Nous allons commencer par voir le code PHP qui récupère et transmet les messages:
if($_GET['action'] == 'select'){
if($_GET['id']==0){
$requete = 'SELECT * FROM demo_chat ORDER BY id DESC LIMIT 0,5';
}
elseif(is_numeric($_GET['id']) && $_GET['id']>0){
$requete = 'SELECT * FROM demo_chat WHERE id > '.$_GET['id'].' ORDER BY id DESC';
}
else{
exit();
}
$result = mysql_query($requete);
echo '<?xml version="1.0" encoding="utf-8"?>
<tchat>';
while($element = mysql_fetch_assoc($result)){
echo '
<message>
<id>'.$element['id'].'</id>
<pseudo>'.stripslashes($element['pseudo']).'</pseudo>
<texte>'.stripslashes($element['texte']).'</texte>
<date>'.date('d/m à H\hi:s',strtotime($element['date'])).'</date>
</message>';
}
echo '</tchat>';
mysql_close();
}
Vous pouvez remarquez que la requête sera différente selon l’identifiant envoyé. Lorsque la requête est éxécutée on parcourt le tableau comme si l’on écrivait un document XML. L’élemént racine étant , Celui ci devra être écrit en dehors de la boucle qui parcourt les lignes de notre requête. Notre balise sera composée des balises (qui servira à reconnaître le numéro du dernier message), et des balises , et (qui lui sera convertit dans un format un peu plus lisible pour l’internaute).
Au passage, vous vous demandez peut-être pourquoi on formate les données en XML si c’est après pour les mettre en xHTML. Les 2 méthodes sont correctes mais cependant, le fait de formater ces données XML isole complètement la couche serveur qui transmet des données, à la couche navigateur qui va ensuite donner un sens à ces données. Si par exemple un autre site veut utiliser votre système de tchat avec vos données et qu’il ne veut pas mettre les messages dans des li, mais plutôt la jouer très futé avec des
. C’est là que ca pose problème…
Enfin voici la fonction Javascript raffraichirMessages() avec les commentaires nécéssaires à sa compréhension:
[/js] var dernierid = 0 ;//identifiant du dernier message
var i=0; //nombre de messages récupérés par la requête
var messages = ''; //ensemble des messages en code HTML à insérer
function raffraichirMessages(id){
// éxécute script.php?id=mondernieridentifiant&action=select
$.get('script.php',{
action : 'select',
id: dernierid
},function(xml){ //bout de code qui sera éxécutée lorsque la réponse aura été chargée
$(xml).find('message').each(function(){ //on fait une boucle sur toutes les balises "message" trouvées
if(i==0){
//On considère que le premier de la boucle est le dernier message inscris.
dernierid = $(this).find('id').text()
}
i = i+1;
messages += '<li><span class="pseudo">'+ $(this).find('pseudo').text()+ '</span><span class="date"> - '+ $(this).find('date').text()+ '</span><p>'+ $(this).find('texte').text()+ '</p></li>';
});
//on ajoute les messages
$('#listemessages').prepend(messages);
//puis on les cache (li:lt(i)) correspond aux balises li qui viennent d'être ajoutées
$('#listemessages li:lt('+i+')').css('display','none');
//puis on les ajoute avec un effet cool
$('#listemessages li:lt('+i+')').slideDown();
messages = '';
//supprime les messages si il y'en a plus de 5
$('#listemessages li:gt((5)').slideUp(500,function(){
$(this).remove();
});
i=0;
});
}
[js]
Vous l’aurez remarqué, ce bout de code est plus difficile à appréhender car on doit récupérer l’identifiant du dernier message et effectué un traitement pour l’afficher progressivement.
Sinon pour traiter le XML obtenu, rien de plus simple avec Jquery. On effectue une boucle each qui fonctionne de la même manière que foreach en PHP.
Pour récupérer la balise message et son contenu, à l’intèrieur de la boucle, on utilise $(this) qui correspondra à une balise message. Ensuite si l’on veut par exemple récupérer le pseudo, on utilise les fonctions find(‘pseudo’) et text() qui renvoient le contenu textuel de la balise pseudo.
J’ai ajouté au code quelques fonctionnalités pour supprimer les messages si il y’en a plus de 5, afficher les nouveaux messages progressivement, et quelques autres choses… mais ce n’est pas l’objet de ce tuto. En tout cas j’espère que vous aurez appris et compris l’intérêt d’Ajax à travers cette très courte série de tutoriels.



