INIT2

Initiation à Ajax avec Jquery (partie 2)

Cette 2ème et dernière partie sur l’initiation à Ajax va consister à réaliser un petit système de Tchat. Nous allons plus précisément apprendre ici à récupérer des informations formatées en XML (en l’occurence des messages), puis de les intégrer dans notre tchat.

 

 

 

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']) &amp;&amp; $_GET['id']&gt;0){
    $requete = 'SELECT * FROM demo_chat WHERE id &gt; '.$_GET['id'].' ORDER BY id DESC';
  }
  else{
    exit();
  }
  $result = mysql_query($requete);
  echo '&lt;?xml version="1.0" encoding="utf-8"?&gt;
          &lt;tchat&gt;';
  while($element = mysql_fetch_assoc($result)){
     echo '
        &lt;message&gt;
          &lt;id&gt;'.$element['id'].'&lt;/id&gt;
          &lt;pseudo&gt;'.stripslashes($element['pseudo']).'&lt;/pseudo&gt;
          &lt;texte&gt;'.stripslashes($element['texte']).'&lt;/texte&gt;
          &lt;date&gt;'.date('d/m à H\hi:s',strtotime($element['date'])).'&lt;/date&gt;
        &lt;/message&gt;';
  }
  echo '&lt;/tchat&gt;';
  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.

15 commentaires

S'abonner au RSS des commentaires
  1. Spring Weafer
    Posté le 16/06/2011 à 9h42

    I really enjoy this theme youve got going on in your internet site. What is the name of the theme by the way? I was thinking of using this style for the site I am going to put together for my school project.

  2. Indien
    Posté le 06/11/2010 à 19h28

    merci pour vos travaux.

  3. Kaharon
    Posté le 31/07/2010 à 22h58

    Bonjours je cherche comment inverser l’ordre des messages le nouveau en bas. Car c’est complexe avec le système de récupération du dernier id.

    Merci de votre aide.
    Kaharon.

  4. Napster
    Posté le 15/01/2010 à 23h26

    Bonsoir ! J’ai un petit problème, les messages s’envoient mais ne s’affichent pas !
    j’ai mis le code pour recuperer les messages dans script.php il me semble que ça devrait fonctionner ! Quelqu’un peut – il m’aider ? Merci d’avance ! Et bonne soiré smile

  5. François
    Posté le 31/07/2009 à 21h58

    Salut
    As-tu bien vérifié la syntaxe des PHP pour l’écriture de variables dans une chaine (à savoir les echo ‘test ‘. $test .’ test’; ou echo "test ". $test ." test";

    C’est quasiment sûr que ca vienne de la…Tchao!

  6. sendo
    Posté le 31/07/2009 à 15h12

    Salut!
    meme si je vais paraitre noob (><), j’ai tente d’implementer ton chat en jquery.
    Malheureusement, je ne comprends pas pourquoi, dans l’affichage des messages il arrete pas de mettre "stripslashes($element['texte'])."
    Et en essayant d’envoyer des messages, ca me met toujours une erreur.

    Pourtant, il devrait pas y avoir d’erreur selon moi …

    ps : J’ai juste repris le code pour le tester.
    J’ai une base de donnees "test" et dedans jai cree la table demo_chat comme indique en haut.

    Si qqn pouvait m’aider … smile

  7. François
    Posté le 29/05/2009 à 0h31

    Je sais pas trop comment fonctionne ton script mais tant que tu as l’identifiant de la news en variable superglobal ($ GET) tu peux y faire appel partout dans tous tes codes…
    Après tout dépend comment tu t’organises et si tu veux par exemple afficher plusieurs news (avec plusieurs systèmes de commentaires) en meme temps…

  8. Visual3D
    Posté le 26/05/2009 à 11h26

    Je n’ai pas réussi…

    Je ne n’arrive pas à faire la liaison entre mon fichier voir.php qui contient le formulaire et le champ input et le script.php qui s’occupe du WHERE $id=?

    Je débute en php ^^ Bon je vais quand même persévérer! Je vais pas t’embetter encore une fois. J’espère que je suis sur la bonne voie!

    Si ta des petites précisions je suis preneur. Je te tiendrai au courant si j’arrive au résultat que je souhaite wink

  9. Visual3D
    Posté le 25/05/2009 à 13h50

    Re! Merçi pour ta rep, rapide en plus smile

    En effet avec un champ hidden j’avais testé mais en value je m’étais trompé (j’avais mis $donnees['id']). Je vais tester cela ce soir wink J’espère y arriver!

    Value="’.$_GET['id de ta news'].’" => ‘id de ta news’ est égal à mon champ ID de ma news c’est ca ? Dans mon cas : Value="’.$_GET['id'].’"

    Pas de soucis je te tiens au courant du résultat. Je te filerai l’adresse avec les modifs wink (si ça marche)

    @+

  10. François
    Posté le 25/05/2009 à 13h36

    [citation][de]Réponse à Visual3D:[/de]Slt, excellent tuto! J’ai essayé de faire passer ton chat en système de commentaire : a chaque news (en fonction de l’id de la news) on peut afficher un commentaire.

    J’ai essayé de la façon suivante : J’ajoute le champ id_news à la table demo_chat. Puis Je rajoute une ligne de connexion à ton script.php avec :

    $id=$_GET['id']
    SELECT * from demo_chat WHERE id_news=$id

    Mon but est de sélectionner l’id de la news(ID) de la table news pour afficher des commentaires dans la table demo_chat. Les commentaires ajoutés dans le champ id_news (table demo_chat) correspondront à l’id de la news(ID – table news)

    Après pour l’insertion faudra aussi que le champ id_news se remplisse automatiquement…C’est pas évident à expliquer. Je ne sais pas si tu peut m’aider ?[/citation]

    Salut à toi!
    En fait tu as plusieurs solutions dont celles-ci:
    - tu changes l’action de ton formulaire
    <form action="javascript:envoyerMessage(‘.$_GET['id de ta news'].’)">
    et après tu passes en paramètre dans ta requete ajax
    - ou alors tu ajoutes un <input type="hidden" value="’.$_GET['id de ta news'].’" name="idnews" id="idnews" />

    et tu la récupere dans ta fonction envoyer message comme ca: $(‘#idnews’).val();

    Voila je pense t’avoir donné quelques pistes…
    Sinon ca serait cool d’envoyer le lien de ton truc, c’est toujours sympa de voir que ca sert à des gens smile
    Tchao

  11. Visual3D
    Posté le 25/05/2009 à 10h09

    Slt, excellent tuto! J’ai essayé de faire passer ton chat en système de commentaire : a chaque news (en fonction de l’id de la news) on peut afficher un commentaire.

    J’ai essayé de la façon suivante : J’ajoute le champ id_news à la table demo_chat. Puis Je rajoute une ligne de connexion à ton script.php avec :

    $id=$_GET['id']
    SELECT * from demo_chat WHERE id_news=$id

    Mon but est de sélectionner l’id de la news(ID) de la table news pour afficher des commentaires dans la table demo_chat. Les commentaires ajoutés dans le champ id_news (table demo_chat) correspondront à l’id de la news(ID – table news)

    Après pour l’insertion faudra aussi que le champ id_news se remplisse automatiquement…C’est pas évident à expliquer. Je ne sais pas si tu peut m’aider ?

  12. rubixcube
    Posté le 19/05/2009 à 17h30

    merci pour cet excellent tuto !

  13. ynnad
    Posté le 18/05/2009 à 16h14

    bon comme tuto mais ce ke je trouve un peut difficile est ke les nom des pages ne sont pas donnés pour guider

    merci kan mêm.

    On se débrouillera

  14. michelfleith
    Posté le 18/05/2009 à 10h55

    Pour que ça marche sous IE il faut charger DOMXML.

    var data;
    if($.browser.msie){
    data = new ActivXObject("Microsoft.XMLDOM");

    data.async = false;
    data.loadXML(xml); //xml est la variable qui contient le retour de $.get
    }

    à partir de là le find fonctionne sous IE.

  15. Lutystrike
    Posté le 31/03/2009 à 19h09

    Magnifique tuto, continu comme ça!

Répondre à rubixcube Cancel reply

Votre e-mail ne sera jamais publié ni communiqué. Les champs obligatoires sont indiqués par *

*
*

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>