Posté le 10 Novembre 2006 à 18:45
Dans cet article je vais essayer d'expliquer le plus clairement possible comment fonctionne le système de recherche en live du blog. Le fonctionnement étant assez simple ça ne devrait pas être trop compliquer à expliquer clairement, cependant, pour comprendre le contenu de l'article, il faut avoir déjà quelques bases en HTML, JavaScript et PHP/MySQL.1/ Le principe de fonctionnement
Quand le champ de recherche prend le focus, on lance une fonction JavaScript. Cette fonction a pour rôle de lancer la recherche mais seulement à certaines conditions :- le champ contient au moins trois caractères
- le contenu du champ a changé depuis la dernière recherche lancée
- le champ de recherche a le focus (ça parait évident, mais si on ne vérifie pas ça, la recherche continuerait indéfiniment même lorsque le champ de recherche perd le focus).
2/ Mise en place du formulaire de recherche
Dans ce formulaire on a besoin de :- un champ de recherche (non ? :-D)
- un moyen de stocker le contenu du champ de manière temporaire
- un moyen de savoir si le champ de recherche a le focus.
→ Code : le formulaire
1 2
3
4
5
6
7
<form action="index.php" method="get" onsubmit="return false" id="search_form">
<p>
<input type="text" name="s" value="" id="s" size="20" />
<input type="hidden" name="livestop" value="" id="livestop" />
<input type="hidden" name="old_s" value="" id="old_s" />
</p>
</form>
<form> :action="index.php" method="get": cette partie la ne sert pas à grand chose pour une recherche live mais est là pour être conforme au normes XHTML 1.1 du W3C, car ces attributs sont obligatoires.onsubmit="return false": on empêche le formulaire d'être validé.id="search_form": un identifiant unique pour avoir accès aux champs du formulaire plus facilement en JavaScript.
Celui appelé "livestop" servira à mémoriser le statut du champ de recherche ("live" si il a le focus et que la recherche doit être continuée, "stop" si le champ de recherche perd le focus et que la recherche doit être arrêté).
Celui appelé "old_s" servira à mémoriser le contenu du champ de recherche pour pouvoir le comparer au nouveau contenu du champ de recherche et n'effectuer la recherche que si ces valeurs diffèrent.
Nous reviendrons plus tard sur la manière de faire tout ça.
3/ Le JavaScript
D'abord le code, ensuite je l'explique. → Code : la fonction JavaScript
1 2
3
4
5
6
7
8
9
function livesearch (s, livestop, olds) {
if (s.length >= 3 && s != olds && livestop == 'live') {
document.getElementById('search_form').old_s.value = s;
xajax_livesearch(s);
}
if (livestop == 'live') {
setTimeout("livesearch(document.getElementById('search_form').s.value, document.getElementById('search_form').livestop.value, document.getElementById('search_form').old_s.value)", 500);
}
}
Ligne 1 : la fonction prend trois arguments qui sont tout simplement les trois champs du formulaire.
Ligne 2 : on vérifie que les conditions pour effectuer la recherche sont vérifiées.
Ligne 3 : on mémorise la valeur de du champ de recherche (le champ "s") dans le champ "old_s".
Ligne 4 : explications plus tard ;-)
Ligne 6 : si la recherche doit continuer...
Ligne 7 : ...on lance un compteur qui relance la fonction 1/2 seconde (c'est en millisecondes) plus tard (le second argument de la fonction
setTimeout est le temps en millisecondes à attendre avant d'exécuter le premier argument de la fonction).Vous êtes sûrement en train de vous demander comment est ce qu'on appelle cette fonction la première fois ?
Tout simplement en ajoutant des évènements JavaScript dans le formulaire.
→ Code : le formulaire avec les évènements JavaScript
1 2
3
4
5
6
7
<form action="index.php" method="get" onsubmit="return false" id="search_form">
<p>
<input type="text" name="s" value="" id="s" size="20" onfocus="livesearch(this.value, 'live', document.getElementById('search_form').old_s.value); document.getElementById('livestop').value='live';" onblur="document.getElementById('livestop').value='stop';" />
<input type="hidden" name="livestop" value="" id="livestop" />
<input type="hidden" name="old_s" value="" id="old_s" />
</p>
</form>
Le premier,
onfocus, qui s'exécute quand le champ texte prend le focus, se décompose en deux :livesearch(this.value, 'live', document.getElementById('search_form').old_s.value);est l'appel à la fonction de recherche.document.getElementById('livestop').value='live';est la mémorisation dans le champ caché "livestop" du fait que la recherche doit continuer.
onblur, qui s'exécute quand le champ texte perd le focus :document.getElementById('livestop').value='stop'; est la mémorisation dans le champ caché "livestop" du fait que la recherche doit s'arrêter.4/ xajax : AJAX facile en PHP
Dans cette partie je vais vous présenter les fonctions de la librairie PHP xajax utiles à la réalisation de notre recherche en live.La librairie xajax se présente sous la forme de deux classes. La classe
xajax est celle qui sert à mettre en place AJAX, la classe xajaxResponse sert elle à traiter les retours des fonctions PHP. Ce n'est peut-être pas clair pour l'instant, mais vous comprendrez en lisant la suite de ce document.Utiliser des classes plutôt qu'un ensemble de fonctions en vrac dans un fichier est avantageux. Un des avantages, c'est que toutes les méthodes (fonctions) d'une même classe peuvent s'échanger facilement des variables (appelées attributs). L'inconvénient, c'est que si vous ne connaissez rien à la programmation orienté objet en PHP, vous allez peut-être avoir du mal à comprendre la suite, mais je vais essayer d'être le plus clair possible et de fournir le plus d'explications possibles.
Encore une fois, je vais afficher le code, et l'expliquer ensuite.
→ Code : explications xajax
1 2
3
4
5
6
7
8
9
10
11
<!-- ceci doit être fait avant d'envoyer une quelconque information au navigateur, avant même le doctype de votre fichier ! -->
<?php
require_once('./chemin/vers-le-fichier/xajax.inc.php');
$xajax = new xajax();
$xajax->registerFunction('livesearch');
$xajax->processRequests();
?>
<!-- le code qui suit doit être placé entre <head> et </head> -->
<?php
$xajax->printJavascript("", 'chemin/vers-le-fichier/xajax_js/xajax.js');
?>
Les lignes 3 à 6 doivent absolument être placées au tout début de votre fichier !
Ligne 3 : on inclut le fichier xajax.inc.php, qui contient le code php nécessaire à l'utilisation de la classe xajax.
Ligne 4 : on créer un instante de la classe xajax (une instance de classe sert à pouvoir accéder aux méthodes et aux attributs de cette classe).
Ligne 5 : on appelle la méthode
registerFunction(); de la classe xajax, cette méthode sert à déclarer les fonctions PHP que l'on veut pouvoir utiliser sans recharger la page (ici déclare la fonction PHP livesearch(); que l'on créera plus tard.Ligne 6 : la méthode
processRequests(); est une des méthodes les plus importante c'est celle qui permet d'utiliser l'objet principal de AJAX : XmlHttpRequest dans les pages ou elle est appelée.Ligne 10 : cette méthode doit être placée entre
<head> et </head>, c'est elle qui génère le JavaScript.Les fonctions PHP déclarées avec xajax sont ensuite accessible en JavaScript sous le nom
xajax_nomDeLaFonctionPHP();. C'est le nom par défaut, il peut être changé mais il est très bien :-).Vous comprenez maintenant ce qu'était le
xajax_livesearch(s); à la ligne 4 dans le code de la fonction JavaScript, c'est un appel � la fonction PHP livesearch(); que nous allons voir maintenant, en découvrant au passage d'autres fonctionnalités utiles à la réalisation de la recherche en live de la librairie xajax.5/ La fonction PHP et présentation de la classe xajaxResponse
Un : code, deux : explications. :-p → Code : la fonction PHP
1 2
3
4
5
6
7
8
function livesearch ($string)
{
$reponse = new xajaxResponse();
$retour = '<h2>Resultat(s) de la recherche</h2>';
$retour .= doQueryAndFormatResults("SELECT `title` FORM `blog_posts` WHERE `content` LIKE '%$string%' OR `title` LIKE '%$string%' ORDER BY `id` DESC LIMIT 15");
$reponse->addAssign('searchResultDiv', 'innerHTML', $retour);
return $reponse->getXML();
}
On crée en premier un instance de la classe
xajaxResponse.Ensuite on stocke dans la variable
$retour les résultats de la recherche. La fonction doQueryAndFormatResults(); n'existe pas vraiment chez moi, c'est juste pour vous éviter la connexion à la base de données, la requête, la déconnexion, la mise en forme des résultats...Ensuite on utilise la méthode
addAssign(); de la classe xajaxResponse. Cette méthode prend trois arguments :- le premier et l'
idde l'élément html que l'on veut modifier. Ici c'est<div id="searchResultDiv"></div>. Cet élément html doit exister dans la page. - le second est ce qu'on veut modifier. Ici on utilise
innerHTMLpour modifier ce qui est entre les balises d'ouverture et de fermeture de l'élément. (On peut utiliser aussivaluepour modifier le contenu d'un champ de formulaire par exemple). - le troisième et dernier argument est ce qu'on veut mettre à l'endroit qu'on a défini avec les deux premiers arguments.
Enfin la fonction doit retourner l'appel à la méthode
getXML(); qui retourne le xml que xajax va traiter en JavaScript. J'insiste sur le doit car toutes les fonctions que vous appellerez via xajax doivent retourner ça, sinon ça ne marchera pas.Et voilà, la recherche en live est prête à être utilisée !
Cependant, il faut encore améliorer quelques petites choses : par exemple lorsque l'utilisateur entre "php xajax" dans le champ de recherche, la fonction va rechercher la chaîne "php xajax" et pas comme on le voudrait les articles qui contiennent "php" ET "xajax", mais pas forcément les deux mots l'un à côté de l'autre.
Une piste quand même : la fonction php
explode(' ', $string); puis un petit foreach ;-)Voici deux autres méthodes de la classe xajaxResponse qui pourraient vous être utiles :
addAppend();: elle prend les même arguments queaddAssign();mais elle ajoute le contenu du troisième et dernier argument là où on le lui à dit avec les deux premier arguments plutôt que de remplacer le contenu.addPrepend();: vous vous en doutez, elle fait la même chose queaddAppend();mais en plaçant le contenu du troisième et dernier argument au début du contenu.addScript();: Cette méthode est très pratique, elle prend en argument une chaîne de caractères qui est un script javascript qu'elle va exécuter. Cela permet d'utiliser conjointement avec xajax une librairie comme script.aculo.us.
6/ Dernières petites choses
Vous pouvez utiliser cet article pour le mettre sur votre site à condition de me citer et de mettre un lien vers cet article (il est sous licence Creative Commons by-nc-sa).De même, si vous créez une recherche en live pour votre blog (ou site), un article avec un lien vers celui-ci serait sympa ;-)
Ah oui, si vous trouvez une faute d'orthographe ou de grammaire dans l'article (à mon avis il y en a un bon paquet... #-D), merci de les relever (utilisez les commentaires).
cookiewarrior :
Donc bravo, beau boulot...
Pour les fautes :-x, juste une qui me gêne:
le contenu du champ a changé depuis la dernière recherche lancée
dans le 1/...
Je bookmarke...
cookiewarrior :
popogendarme :