AJAX est une technologie qui permet d’apporter une plus grande richesse dans l’interface et l’ergonomie d’un site.
Si il est bon de ne pas en abuser au risque de dénaturer le document web, on peut se laisser aller à la tentation d’apporter quelques fonctionnalités intéressantes.
Celle que je vous propose ici consiste à intégrer un moteur de recherche à la manière d’un Google Suggest. Sauf qu’ici vous pourrez avoir un code lisible ^^
Je ne vais pas aborder le concept d’AJAX car certains en parlent déjà très bien. Je vous recommande d’ailleur de lire cet article (Anglophobe, s’abstenir).
PS: Ce billet remplace celui qui s’appelle désormais Introduction à XMLHttpRequest et PHP
Principe
Il faut réunir trois principes pour concevoir cet élément d’application. Tout d’abord nous avons besoin de Javascript et de XMLHttpRequest afin de pouvoir communiquer en arrière plan avec le serveur. Nous allons utiliser la classe XHRConnection pour nous faciliter la vie. Ensuite, il est nécessaire d’avoir un service web se chargera de construire le document XML que nous parserons avec l’API DOM. Enfin afin que l’effet visuel soit efficace nous devrons utiliser les CSS.
Le moteur comprendra une zone de résultat (balise ul) qui ne contiendra pas d’élément de liste. C’est cette liste que nous construirons selon le fichier XML généré et renvoyé par le serveur. Selon que la recherche soit prolifique ou non, la zone de résultat sera cachée ou montrée.
Payes ton code
Vous allez voir, c’est en fait très simple à mettre en place. Voici tout d’abord le formulaire :
<form id="formulaire" action="index.php" method="post"> <fieldset> <p> <label for="foo">Saisissez les chaines à rechercher dans le champ de formulaire ci-desous :</label> <input type="text" name="foo" id="foo" value="" onkeyup="loadData();" /> </p> <ul id="zoneResultats" style="visibility: hidden;"></ul> <p> Texte à placer pour tester que les réponses s'affichent par dessus... Lorem ipsum ... </p> </fieldset> </form>
Voici le code javascript dont vous aurez besoin :
<script type="text/javascript">
// Déclaration de la fonction de Callback
// + ----------------------------------------------------------------------------------
// + afficherResultats
// + Affiche ou non le conteneur en fonction du résultat de la recherche
// + ----------------------------------------------------------------------------------
function afficherResultats(obj) {
// Construction des noeuds
var tabResult = obj.responseXML.getElementsByTagName('resultat');
document.getElementById('zoneResultats').innerHTML = '';
if (tabResult.length > 0) {
// On définit la hauteur de la liste en fonction du nombre de rsultats et de la hauteur de ligne
var hauteur = tabResult.length * 22;
with(document.getElementById('zoneResultats').style) {
visibility = 'visible';
height = hauteur + 'px';
};
for (var i = 0; i < tabResult.length; i++) {
resultat = tabResult.item(i);
var egt = document.createElement('li');
var lnk = document.createElement('a');
var texte = document.createTextNode(resultat.getAttribute('titre'));
lnk.appendChild(texte);
lnk.setAttribute('href', resultat.getAttribute('url'));
lnk.setAttribute('title', resultat.getAttribute('titre'));
egt.appendChild(lnk);
document.getElementById('zoneResultats').appendChild(egt);
}
}
else {
document.getElementById('zoneResultats').style.visibility = 'hidden';
}
}
// Déclaration de la fonction qui lance la recherche
function loadData() {
// Création de l'objet
var XHR = new XHRConnection();
XHR.appendData("foo", document.getElementById('foo').value);
// On soumet la requête
// Signification des paramètres:
// + On indique à l'objet qu'il faut appeler le fichier search.php
// + On utilise la méthode POST, adaptée l'envoi d'information
// + On indique quelle fonction appeler lorsque l'opération a été effectuée
XHR.sendAndLoad("search.php", "POST", afficherResultats);
}
</script>
Coté serveur, nous avons ce petit script PHP :
[php]
header("Pragma: no-cache");
header("Expires: 0");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-cache, must-revalidate");
header("Content-type: application/xml");
if(!empty($_REQUEST["foo"])) {
$rqListBillet = "
SELECT *
FROM `blog_blabla`
WHERE `titre` like '" . $_REQUEST["foo"] . "%'
ORDER BY `date_parution` DESC";
$rsListBillet = mysql_query($rqListBillet);
$xml = "
if (mysql_num_rows($rsListBillet) > 0) {
while ($billet = mysql_fetch_object($rsListBillet)) {
$xml .= "\n
}
}
}
else {
$xml = "
}
$xml .= "\n
echo utf8_encode($xml);
[/php]
Pour la mise en page, veuillez vous référer au fichier suivant: styles.css.
N'oubliez pas de tester le formulaire, ça se passe ici




















A quand GeSHi pour ton blog ?
Il était là un temps. Le temps que je me dise que j’allais m’en passer
Très intéressant. Merci pour ce tutoriel.
Ca fait un moment que je tourne là dessus pour arriver à faire un truc correct, et en fait mon prob est que ma base de données sur la quelle je tape comporte 150000 articles, donc ca fait un peu lourd à afficher
J’essaye donc ta méthode, en te remerciant de la clarté du site et des rédactions qui y sont effectuées.
@+
Arnaud
Salut a tous
voila je suis débutant et je c pas comment utilser les code si je doit tout méttre dans la méme page ou séparer et le nom des page aussi
si qulqun peut me répondre.
merci
Bonjour Alle,
je te proposes de formuler ton besoin sur le forum dreamweaver de http://www.media-box.net
A bientôt.
Bonjour a tous,
Vous n’avez pas peur que cela fasse un peu bcp de requete sur votre server mysql si tu ne passe pas par un cacheSQL … fait un like% a chaque lettre tapé ca peux vite saturer ton sql, sans compter les scripts malfaisant pour flooder ta base.
Salut,
Super pratique, mais j’ai ça ne fonctionne pas si je base ma recherche sur 2 tables (table mot-cles et une autre mot-associes)
Je lance ma recherche sur tot donc j’ai une 1ere requete sur ‘toto%’ (table mot-cles), je recupere l’id de ce mot-cles et je fais ensuite une autre requete (table mot-associes)(imbrique dans un while de la 1ere requete) sur cette id et c’est sur cette 2ème requette que je fais ton tuto.
ça ne fonctionne pas….
::whistle
Sais-tu pkoi ?? ou est-ce limité que sur une table ??
Merci de ta réponse
Salut nicolas,
je te proposes de soumettre ton code sur ce forum:
http://dreamweaver.media-box.net
Denis Cabasson (www.developper.com) dans son article (tutoriel) du 10 février 2006 (Ajax – une autocomplétion pas à pas) fait une très bonne approche, quoi qu\’un peu complexe à mon goût, de la création d\’une liste déroulante en AJAX.Le…
:]
Un truc m’échappe : à quel moment se connecte-t-on à la base ?titre) . « \ » url=\ »/blog/ » . $billet->url_page . « .html\ » /> »;
De plus je ne comprends pas bien cette ligne :
»
$xml .= « \n
«
@Pierre,
il n’est pas fait ici de détails concernant la connexion à la base de données. Mais il faut le faire bien sûr
Merci, en regardant le code de plus près j’ai mieux compris… Par contre je galère pour débugguer le script PHP, pour lequel je ne parviens pas à voir les erreurs.
Au passage : félicitations
Excelent
Merci pour ce script et le travail que tu fourni …
Bonjour,
Comment faire pour afficher la valeur sélectionnée de la liste dans la zone du formulaire avant le script me redirige sur une autre page.
merci de votre aide
bonjour, ce framework va t’il encore évoluer?
je fais actuellement une étude sur les frameworks ajax existant et la pérennité est un point essentiel aux différents critères de sélections
Bonjour,
j’envisage depuis un certain temps d’ajouter quelques méthodes. Ce n’est pas pour tout de suite mais c’est effectivement dans les tuyaux
Merci pour le tuyaux
Bonjour merci pour ce script il est vraiment très bien cependant si l’on tape un % dans la zone de recherche on voit que la liste descend tres bas comment faire via la css pour limiter à (par exemple) 20 reponses et qu’il y ai un scroll pour descendre plus bas ??
Martial,
tu peux faire un LIMIT 0, 20 du coté de la requête MySQL
Excelent, merci.
http://www.portia.pl