Hier, j’expliquais comment faire un système de commentaire avec jQuery, c’est-à-dire un système de commentaires sans rechargement de la page. Mais il manquait encore l’appel Ajax, j’entends par là, l’appel asynchrone à un script PHP qui enregistre le commentaire ajouté dans une base de données. C’est aujourd’hui chose faites ! J’en profite pour expliquer les différents tests que j’ai effectué avec getJSON et post en mode JSON et XML.
Première étape : getJSON
Je rappelle l’idée de ce script : un utilisateur peut remplir un formulaire pseudo+commentaire et lorsqu’il l’envoie, hop son message apparait sans rechargement de la page en tête des autres commentaires. Son commentaire a été enregistré dans une base de données entre temps. Du coup :
- on a besoin d’envoyer 2 données au script PHP : le pseudo et le contenu du commentaire
- on a besoin que le script PHP nous renvoie 3 données : le pseudo et le contenu du commentaire (qu’on a sécurisé et affiné si besoin) et une valeur de retour (1 si ok, 0 si problème)
Et la, si vous êtes que moi et que vous ne connaissez pas JSON, vous avez le droit de vous demander quoi faire.
En effet, dans un précédent billet Utiliser une fonction PHP avec jQuery et get(), j’expliquais le fonctionnement de get()
, mais on voit bien qu’on ne peut récupérer 3 variables avec cette méhode ! Mais comme d’hab, la doc jQuery est là pour nous sauver et nous présente : getJSON ! Cette méthode nous permet de faire un appel asynchrone à PHP, ce dernier nous renvoie un fichier au format JSON(exemple ci-dessous), que l’on interprète ensuite facilement en jQuery pour récupérer les variables désirées.
{ "var1": "data1", "var2": "data2", "var3": "data3" }
Voici donc ce que donne le script jQuery (j’ai repris la version simple d’hier pour commencer) :
$(document).ready(function() { // Au submit du formulaire $('#form').submit( function() { var pseudo = $('#pseudo').val(); var commentaire = $('#contenu').val(); if (pseudo != '' && commentaire != '') { // On fait l'appel Ajax $.getJSON('include/ajax/commentaire.php', {pseudo:pseudo, commentaire:commentaire}, function(data){ if (data.ret) { // On ajoute le nouvel élément $('#commentaire').prepend('<p class="last"><strong>'+data.pseudo+'</strong> a dit :<br />'+data.commentaire+'</p>'); } else { $('#contenu').after('<span class="erreur">Erreur lors de l\'ajout du commentaire</span>'); $('.ok').hide().fadeIn('slow'); } }); } // On retourne false pour ne pas recharger la page return false; }); });
On peut voir que l’on fournit le contenu des champs pseudo et commentaire au script PHP, on les récupérera à l’aide de $_GET['nomVariable']
. Quant aux variables que nous renvoi PHP, on les récupère avec data.nomVariable. Bref, le fonctionnement est vraiment simple ! Le fichier commentaire.php correspondant est :
if (isset($_GET['pseudo']) && isset($_GET['commentaire'])) { echo '{ "ret" : 1, "pseudo" : "'.$_GET['pseudo'].'", "commentaire" : "'.nl2br($_GET['commentaire']).'" }'; } else { echo '{"ret" : 0}'; }
Deuxième étape : post en XML
Le script ci-dessus fonctionne très bien tant que l’on écrit par des scripts sur plusieurs lignes. En effet, si ce n’est pas le cas, on ne respecte plus le format JSON que l’on renvoie en PHP, donc on ne renvoit pas du JSON, donc ça bug. Moralité, au lieu de renvoyer du JSON, on va renvoyer du XML ! Et pour cela, il faut utiliser la méthode post() ! (à noter qu’on pourrait également l’utiliser en mode JSON, et dans ce cas là, le code est sensiblement le même que précédemment)
$(document).ready(function() { // Au submit du formulaire $('#form').submit( function() { var pseudo = $('#pseudo').val(); var commentaire = $('#contenu').val(); // On supprime les anciens messages d'erreurs ou de succès $('.erreur').remove(); $('.ok').remove(); // Si on a commentaire à ajouter if (pseudo != '' && commentaire != '') { // On affiche le loader $('#contenu').after('<img src="<?php echo DEFAULT_THEME_PATH; ?>/img/loader.gif" alt="Chargement..." class="loader" />'); // On compte le nombre de commentaire déjà présent + celui qui va être créé var nbCom=1; $('#commentaire p').each(function() { nbCom++; }); // On enlève la class "last" à l'ancien dernier $('.last').removeClass('last'); // On fait l'appel Ajax $.post('include/ajax/commentaire.php', {pseudo:pseudo, commentaire:commentaire}, function(data){ var xmlData = data.getElementsByTagName('com')[0]; var ret = xmlData.getElementsByTagName('ret')[0].firstChild.nodeValue; var xmlPseudo = xmlData.getElementsByTagName('pseudo')[0].firstChild.nodeValue; var xmlCommentaire = xmlData.getElementsByTagName('commentaire')[0].firstChild.nodeValue; if (ret) { // On ajoute le nouvel élément $('#commentaire').prepend('<p class="last" id="com_'+nbCom+'"><strong>'+xmlPseudo+'</strong> a dit :<br />'+xmlCommentaire+'</p>'); // On le met pair ou impair if ($('.last').next().is('.pair')) $('.last').addClass('impair'); else $('.last').addClass('pair'); if (!$('.last').next().is('p')) $('.last').addClass('first'); // On efface le contenu du formulaire $('#contenu').val('').focus(); $('.loader').remove(); $('#contenu').after('<span class="ok">Commentaire ajouté avec succès</span>'); $('.ok').hide().fadeIn('slow'); } else { $('.loader').remove(); $('#contenu').after('<span class="erreur">Erreur lors de l\'ajout du commentaire</span>'); $('.ok').hide().fadeIn('slow'); } }, 'xml'); } else { if (pseudo == '') $('#pseudo').after('<span class="erreur">Champ requis</span>'); if (commentaire == '') $('#contenu').after('<span class="erreur">Champ requis</span>'); $('.erreur').hide().fadeIn('slow'); } // On retourne false pour ne pas recharger la page return false; }); });
Comme vous pouvez le voir, il faut s’amuser un petit peu pour récupérer la variable que l’on souhaite. Avec mes connaissances actuelles, je ne vois pas comment faire autrement en jQuery pour récupérer du XML. Le script PHP correspondant est :
header("Content-Type: text/xml"); echo "<?xml version='1.0' encoding='UTF-8' ?>"; if (isset($_POST['pseudo']) && isset($_POST['commentaire'])) { echo '<com> <ret>1</ret> <pseudo>'.$_POST['pseudo'].'</pseudo> <commentaire><![CDATA['.nl2br(htmlspecialchars($_POST['commentaire'], ENT_QUOTES, 'UTF-8')).']]></commentaire> </com>'; } else { echo '<com> <ret>0</ret> <pseudo>no</pseudo> <commentaire>no no</commentaire> </com>'; }
Cette fois-ci, il a fallu préciser que le fichier généré est un fichier XML. Il faut aussi remarquer que j’ai entourer le commentaire de la balise @@@@, afin d’obtenir un document XML valide si jamais il y a des balises HTML. Seul le contenu de cette balise est renvoyé par text()
, elle n’apparait donc pas dans le code HTML !
Dernière étape : le test
Et voilà un petit script bien fini ! Reste à créer le fichier CSS qui va bien, mais ça, ce sera pour une prochaine fois.
Ping : Un système de commentaires avec jQuery (1) - 30 minutes par jour
Ping : Utiliser une fonction PHP avec jQuery get - 30 minutes par jour