Jusqu'à présent, tout ce qu'on a fait dans les chapitres précédents ne concernait que le client (le navigateur). C'est normal, c'est le principe de JavaScript.
Mais cette approche est encore trop limitée, c'est pour ça qu'on a inventé AJAX (littéralement : Javascript et XML Asynchrones). AJAX c'est le pont entre les langages serveur (PHP, .NET...) et JavaScript, cette technologie permet de faire communiquer les deux de manière asynchrone, c'est-à-dire qu'on a plus besoin de recharger toute la page mais seulement une partie de la page, en y insérant des informations qui viennent directement du serveur.
Principe
Le fonctionnement d'AJAX est très simple :
Javascript peut effectuer des requêtes HTTP (de type GET ou POST), et récupérer le texte retourné par le serveur grâce à une fonction callback.
Et XML dans tout ça ?
Pour transférer les données entre le JavaScript et PHP par exemple, on a besoin d'adopter des conventions, une sorte de protocole respecté des deux côtés, pour que JavaScript puisse interpréter ce qui est retourné par le serveur.
Et c'est XML qui a d'abord été utilisé pour ça. Mais aujourd'hui il existe d'autres formats plus simples à utiliser, notamment JSON, qui peuvent remplacer XML.
Exemple
On va tout de suite passer à la pratique, c'est ce qu'il y a de plus facile.
Donc il va nous falloir 2 choses :
- un script PHP côté serveur
- du javascript pour envoyer et utiliser le résultat de la requête AJAX
PHP
Pour que vous compreniez bien le principe, j'ai imaginé un scénario très simple où le client appelle le script PHP en lui passant en paramètre une chaîne de caractère (chaine).
Le script PHP met cette chaine en majuscule et la retourne au client, avec différentes informations en plus :
- date et heure courante
- version de PHP
Le tout est ensuite envoyé au client encodé en JSON (il existe 2 fonctions bien pratiques pour ça en PHP 5.2 : json_encode et json_decode).
<?php /* * Script PHP qui traite les requêtes AJAX envoyées par le client **/ // Récupération des paramètres $chaine = ''; if( isset($_GET['chaine']) ){ $chaine = $_GET['chaine']; } // Traitements $retour = array( 'chaine' => strtoupper($chaine), 'date' => date('d/m/Y H:i:s'), 'phpversion'=> phpversion() ); // Envoi du retour (on renvoi le tableau $retour encodé en JSON) header('Content-type: application/json'); echo json_encode($retour); ?>
Voici un exemple de retour de ce script :
{ "chaine":"BONJOUR", "date":"15\/04\/2011 17:46:46", "phpversion":"5.2.10" }
jQuery
Maintenant qu'on dispose de notre script PHP sur le serveur, il ne reste plus qu'à l'appeler côté client, en Javascript, avec jQuery !
Ça tombe bien, jQuery propose plein de fonctions pour faire de l'AJAX. Mais quoi qu'il arrive, le schéma reste toujours identique :
- Javascript envoi une requête HTTP GET ou POST au serveur
(il peut y joindre des paramètres, exactement comme quand on post un formulaire HTML banal). - Le serveur exécute le script (ex: PHP) et retourne des informations au client dans un format de votre choix :
- Texte brut
- XML
- JSON
- ...
- Ce retour d'informations peut être récupéré en Javascript par une fonction qu'on qualifie de callback (littéralement : fonction de rappel), que l'on spécifie au moment de l'appel AJAX.
Alors LA fonction à connaître quand on fait de l'AJAX et qu'on utilise jQuery, c'est jQuery.ajax() (ouais, c'est original !).
Cette fonction est assez complexe puisqu'elle propose un nombre important de paramètres, de modes de fonctionnement différents. En particulier :
- type
Tout simplement le type de requête HTTP : GET ou POST.
Cela n'a pas tellement d'importance, en général on utilise POST, ici j'ai utilisé GET parce que c'est plus simple pour apprendre.
La seule chose à garder en tête c'est que l'accès aux paramètres envoyés par Javascript sera différent côté serveur.
Par exemple en PHP, si vous envoyez votre requête AJAX en mode GET, il faudra utiliser la variable $_GET, et si vous êtes en mode POST, il faudra utiliser... $_POST.
- dataType
C'est le format du retour, ce que nous renvoie le serveur.
En effet, si vous spécifiez dans votre appel, en Javascript, que le retour est en texte brut, alors que le serveur vous retourne du JSON, vous n'aurez pas d'erreur, mais vous obtiendez une simple chaîne de caractère dans le callback.
Alors que si on met JSON, on aura un objet Javascript construit à partir de ce code JSON, qu'on peut manipuler comme n'importe quel autre objet Javascript, en faisant :monObjet.monAttribut
.
Et c'est exactement la même pour XML : soit vous récupérez le code XML dans une chaine de caractère, soit vous récupérez un objet construit à partir de ce XML.
Par défaut, jQuery utilise le mode Intelligent Guess, c'est-à-dire que jQuery va essayer de deviner automatiquement le format de retour, avec les headers HTTP (Content-type).
- success
il s'agit de la fameuse fonction callback qui est exécutée lorsque le client à reçu la réponse du serveur. Cette fonction peut prendre en paramètre une variable qu'on nomme souvent data, et qui contient les données retournées par le serveur.
Selon ce que vous avez spécifié dans dataType, il peut d'agir d'une chaine de caractère ou d'un objet Javascript.
Bref, je vous invite à aller lire la documentation de la fonction jQuery.ajax() sur le site officiel, vous y trouverez le détail de chaque paramètre et des exemples de code.
Comme vous le voyez, la fonction .ajax() c'est un peu une usine à gaz. Alors chez jQuery ils ont eu une idée : créer toute un série de petites fonctions dérivées de .ajax() qui sont moins riches mais qui sont en contrepartie beaucoup plus simples à utiliser.
Voici les plus importantes :
.get(url, data, success)
Elle envoie la requête en mode GET vers url avec les paramètres qui sont spécifiés dans l'objet data (tableau associatif), et prend en 3ème paramètre la fonction de callback.
.post(url, data, success)
Exactement pareil que .get(), mais la méthode est POST et non pas GET.
.getJSON(url, data, success)
Pareil que .get(), à la seule différente que le type du retour est JSON. Ça évite les problèmes du mode Intelligent Guess qui peut se tromper si le serveur envoie de mauvais headers, comme c'est souvent le cas...
Ici, je vais utiliser la fonction jQuery.getJSON() pour mon appel AJAX. C'est une fonction qui, comme son nom l'indique, envoi la requête en GET et prend en retour du JSON :
<form id="form"> <input name="chaine" type="text" id="chaine" value="Bonjour" /> <input type="submit" value="Envoyer" id="handle" /> </form> <div id="retour"> <i>vide</i> </div>
jQuery(document).ready(function($){ $('#form').submit(function(e){ // On désactive le comportement par défaut du navigateur // (qui consiste à appeler la page action du formulaire) e.preventDefault(); // On envoi la requête AJAX $.getJSON( 'ch6_exemple1_ajax.php', {chaine: $('#chaine').val()}, function(data){ $('#retour').hide(); $('#retour').html('') .append('<b>Paramètre en majuscule</b> : '+data.chaine+'<br/>') .append('<b>Date</b> : '+data.date+'<br/>') .append('<b>Version PHP</b> : '+data.phpversion+'<br/>'); $('#retour').fadeIn(); } ); }); });
Note : Souvenez-vous de ce que vous avez lu dans les premiers chapitres : Firebug peut vous aider grâce à la console.
Chaque requête AJAX (dans le jargon on appelle ça des requêtes XHR en référence à l'objet XmlHttpRequest utilisé par le navigateur pour envoyer ces requêtes) apparaît à la fois dans l'onglet Console et dans l'onglet Réseau :
Console Firebug, requête XHR
En pratique...
L'exemple que l'on vient de voir n'aurait aucun intérêt en pratique. En effet, que ce soit pour mettre une chaine en majuscule ou pour connaitre la date et l'heure, on n'a pas besoin du serveur. Javascript propose déjà des fonctions pour faire cela.
Dans la pratique, on utilise souvent AJAX au niveau des formulaires.
AJAX peut par exemple servir à vérifier la validité d'une adresse postale et même vous suggérer des valeurs comme le fait google :
L'intérêt de l'AJAX réside essentiellement dans l'ergonomie.
On peut faire certaines vérifications (de formulaire) plus tôt et donc prévenir l'utilisateur tout de suite, c'est moins frustrant que de devoir valider un formulaire, lire les éventuels messages style "champ XXX incorrect" puis revenir à la page précédente pour corriger...
En plus ça permet d'alléger la charge du serveur et du réseau (quelques lignes de JSON c'est moins lourd qu'un gros fichier HTML...).
Pour conclure ce chapitre et ouvrir sur le suivant, je vais vous envoyer vers un de mes sites consacré aux disques ssd sur lequel j'ai utilisé jQuery UI et de l'AJAX pour créer un comparateur de modèles :
À chaque fois qu'un des champs du formulaire de recherche est modifié, ça envoie une requête AJAX au serveur qui retourne la liste des disques SSD qui répondent aux critères de recherche, sans qu'on ait besoin de cliquer sur un bouton pour envoyer le formulaire...
Et justement, dans le prochain chapitre on va voir comment utiliser jQuery UI pour créer de véritables interfaces graphiques interactives sur une page web, comme dans une application de bureau !
Allez donc jeter un oeil sur cette page : créez une icône en 3d.
Ce tutoriel fait partie d'un cours : aller au sommaire pour voir les autres chapitres.
var el = document.getElementById('div2').elements;
$.ajax({
type: "POST",
url: 'insertion_question.php',
data: {
"question":$('#question').val(),
"description":$('#description').val(),
"type_s":document.getElementById('type_s').selectedIndex
for(var i=1; i<el.length; i++){
"ch":$('#choix'+(i)).val()}
},
success: function(msg){
alert(msg);
}
});
et merci d'avance
Il faut que tu initialise ton tableau data d'abord, et ensuite tu le passe en paramètre à $.ajax :
monTableau = {
"question": $('#question').val(),
"description": $('#description').val(),
"type_s": document.getElementById('type_s').selectedIndex
};
for(var i=1; i<4; i++){
monTableau["ch"+i] = $('#choix'+(i)).val();
}
Cf: http://jsbin.com/eregir/edit#javascript,html
<?php
mysql_connect("localhost","root","");
mysql_select_db("enquete");
//session_start();
$question=$_POST['question'];
$description=$_POST['description'];
$type_s=$_POST['type_s'];
$requete="insert into question (nom_qestion,description,id_type_q) values('".$question."','".$description."','".$type_s."')";
$sql=mysql_query($requete);
$req=mysql_query("select * from question");
echo(nom_qestion);
echo($R);
//$radio=$_POST['radio1'];
if(isset($_POST['choix'])){
$choix=$_POST['choix'];
var_dump($choix);
while($tab=mysql_fetch_object($req)){
if ($tab->id_type_q == 3){
$selection=mysql_query("select id_question as selection from question where id_type_q=3");
while(list($key,$val)=@each($choix)){
for($i=0;$i<$key;$i++){
$insertion="insert into choix_critere (id_choix_c,id_question,nom ) values('".$i."','".$selection."','".$val."') ";
echo($insertion);
$res=mysql_query($insertion);
}
}
}
}
}
?>
merci d'avance
Dans les commentaires c'est pas pratique...
disons que j'ai une balise div dans laquelle se trouve des elements.
<div id="momo">
<input id="monIp" name="alu"> <select id="sel1"><option>opt1</option><option>opt1</option></select>
</div>
si je fais ainsi dans le jquery.
var maVariable=$("#momo").clone();
comment pourrais-je proceder pour modifier l'attribut name de #monIP qui vient d'être créer par clonage?
Merci d'avance.
je fais une application professionnelle dans laquelle j'utilise le dataTable de jquery pour un tableau avec pagination et filtres sur toutes les colonnes dans le footer. Mais j'ai un probleme car toutes mes lignes sont chargées dès le depart puis c'est du javascript finalement qui me permet de trier, filtrer.... Si j'ai trop de lignes dans ce tableau ca devrait trop lent. Donc j'aurais voulu faire de l'ajax comme dans ton site et je n'ai pas compris comment tu faisais ta pagination... Serait-il possible d'avoir ton code source ? Je te remercie par avance car là je ne m'en sors pas du tout !
Le probl
De l'AJAX comme sur Finalclap ?
Où ça, quelle pagination ? (news, stockmotion ?)
en fait j'ai etudié le code source de ton site "comparateur de disque dur SSD" et j'essaie de faire quelque chose dans le même style afin de trier mon tableau. Ce dernier se trouve sur une page php à part et ce qui me manque, c'est le code de ta page php nommée "ajax-comparateur.php" pour voir comment tu récupères les paramètres que tu envoies en ajax (ceux de data).
Je te remercie par avance
Bonne journée.
caro
Ben c'est pas très compliqué, quand l'utilisateur utilise le filtre (choix d'une marque, utilisation des sliders prix ou capacité...), j'envoi une requête AJAX (en GET) avec jQuery :
Ca envoi une requête de ce style sur le serveur :
Exemple d'une recherche des SSD intel format 1.8 pouces :
[...] ajax-comparateur.php?id_marque=4&prix_min=0&prix_max=unlimited&capacite=0&format=1.8
Donc dans le script PHP je récupère les variables GET comme d'habitude, via le tableau $_GET :
Après j'utilise ces variables pour construire une requête SQL qui me retourne la liste des modèles de SSD qui correspondent aux conditions, et j'envoi au client (le navigateur) directement le code html du tableau qui présente les résultats :
Quand je récupère ça côté client (slot
complete:
), je remplace le contenu du <table> par les nouveaux résultat (c'est le empty() et le append() que tu peux voir dans ma fonctionsubmitForm()).
Cette méthode qui consiste à retourner directement du HTML à une requête AJAX n'est pas très "propre", idéalement ça serait mieux que le serveur retourne juste les données (encodé en JSON par exemple), au lieu de retourner les de l'HTML qui contient à la fois les données et la mise en forme, mais elle a le mérite d'être plus rapide et facile à mettre en oeuvre, y'a pas besoin de traiter le JSON côté client pour mettre à jour la page.
merci pour ta reponse. C'est bien ce que je pensais mais pour moi ca ne marche pas donc il doit y avoir un pb qqpart...
j'ai une page menu qui contient :
$(function() {
function submitForm(){
$.ajax({ //fonction permettant de faire de l'ajax
url: "./includes/zones-affichage/ajax-tabArticle.php", //url du fichier php
type: "GET", //methode de transmission des données au fichier php
data: ({ //données à transmettre
id_art: $("#filtre_num").val(),
ref: $("#filtre_ref").val(),
fam: $("#filtre_fam").val(),
design: $("#filtre_desig").val(),
cond: $("#filtre_cond").val(),
stock: $("#filtre_stock").val()
}),
dataType: "html",
complete: function(data){
$("#tablearticle").empty(); //on vide le tableau
$("#tablearticle").append(data.responseText); //on colle les nouvelles données dans le tableau
}
});
}
$('#filtre_num').keyup( function(event){ submitForm(); });
$('#filtre_ref').keyup( function(event){ submitForm(); });
$('#filtre_fam').keyup( function(event){ submitForm(); });
$('#filtre_desig').keyup( function(event){ submitForm(); });
$('#filtre_cond').keyup( function(event){ submitForm(); });
$('#filtre_stock').keyup( function(event){ submitForm(); });
}
je fais des includes de div un peu partout et celle qui nous interesse est celle ci :
<div id="zone19" style="display: none">
<h1>Liste des articles</h1>
<!-- RAPPEL DES CRITERES DE FILTRAGE -->
<!-- <div class="consultation">
<p class="center">Rappel des critères de recherche : <strong>Valeur1,Valeur 2, Valeur 3</strong></p>
</div> -->
<!--
===========================================
Ligne de filtrage
===========================================
-->
<div class="tableau" id="filtre">
<table style="width: 100%;" cellpadding="0" cellspacing="0">
<tr>
<th width="7%"><input type="text" id="filtre_num" value=""></th>
<th width="12%"><input type="text" id="filtre_ref" value=""></th>
<th width="25%"><input type="text" id="filtre_fam" value=""></th>
<th width="20%"><input type="text" id="filtre_desig" value=""></th>
<th width="15%"><input type="text" id="filtre_cond" value=""></th>
<th width="10%"><input type="text" id="filtre_stock" value=""></th>
<th width="5%"></th>
</tr>
<tr>
<th id="retablir" colspan=7>
<button type="reset" class="bouton_intermediaire" title="Cliquer ici pour supprimer tous les filtres" tabindex="2">
<span class="btn">
<span><span>Rétablir</span></span>
</span>
</button>
</th>
</tr>
</table>
</div>
<!--
===========================================
Tableau d'articles
===========================================
-->
<div class="tableau" id="tabart">
<?php include('./includes/zones-affichage/ajax-tabArticle.php'); ?>
</div>
</div> <!-- zone 19 -->
avec comme tu le vois un table pour les filtres et qui inclus une div qui contient l'autre table correspond à mon tableau (nom page php : ajax-tabArticle.php) :
<table id="tablearticle" class="tablesorter" style="width: 100%;" cellpadding="0" cellspacing="0">
<!-- TITRES DES COLONNES -->
<thead>
<tr>
<th width="7%">Numero</th>
<th width="12%">Référence</th>
<th width="25%">Famille</th>
<th width="20%">Désignation</th>
<th width="15%">Conditionnement</th>
<th width="10%">stock</th>
<th class="headerloupe" width="5%"></th>
</tr>
</thead>
<tbody>
<?php
$id_art=$_GET['id_art'];
$ref=$_GET['ref'];
$fam=$_GET['fam'];
$design=$_GET['design'];
$cond=$_GET['cond'];
$stock=$_GET['stock'];
$sql="select * from sages_article,sages_famille,sages_conditionnement";
$sql.=" where sages_article.cond_num=sages_conditionnement.cond_num";
$sql.= " and sages_article.fam_num=sages_famille.fam_num";
/* ajout ajax */
if ($id_art!=0)
$sql.= " and sages_article.art_num=".$id_art;
if ($ref!="")
$sql.= " and sages_article.reference='".$ref."'";
if ($fam!="")
$sql.= " and sages_famille.lib_famille='".$fam."'";
if ($design!="")
$sql.= " and sages_article.designation='".$design."'";
if ($cond!="")
$sql.= " and sages_conditionnement.cond_lib='".$cond."'";
if ($stock!=0)
$sql.= " and sages_article.stock=".$stock;
/* fin ajout ajax */
$sql.= " ORDER BY lib_famille";
$mysql3->query($sql);
if(!$mysql3){
echo("Problème sur lecture de la table article");
exit;
}
for($i=0; $i<$mysql3->nombre(); $i++){
$j=$i+1;
$mysql3->next();
?>
<tr class="row_selected" id=<?php echo($mysql3->art_num);?>>
<td><?php echo($mysql3->art_num);?></td>
<td><?php echo($mysql3->reference);?></td>
<td><?php echo($mysql3->lib_famille);?></td>
<td><?php echo(substr($mysql3->designation,0,30));?></td>
<td><?php echo($mysql3->cond_lib);?></td>
<td><?php echo($mysql3->stock);?></td>
<!-- <td class="pictogramme"><a href="#" class="vue-detail" onclick="openbox('zone26',0,<?php //echo($mysql3->art_num);?>)"></a></td> -->
<td class="pictogramme"><a href="#" id="loupearticle" class="vue-detail"></a></td>
</tr>
<?php
}?>
</tbody>
</table>
et quand je saisie 5 dans le premier filtre, qui correspond à un num article dans ma base, aucun message n'apparait et il ne reste plus de mon tableau que les entetes... Je ne m'en sors pas !
Si tu vois où est le probleme, ca serait vraiment sympa
Bon aprem.
Caro