Cet exemple d'utilisation d'AJAX est organisé comme il se doit en quatre fichiers.

Trois s'exécutent côté Client (navigateur) et sont écrits respectivement en HTML, en CSS et en Javascript (et avec la bibliothèque Jquery) :

  • index.html
  • index.css
  • index.js

Le dernier ajaxTest.php est  écrit en PHP et  s'exécute côté serveur.

Dans cet exemple, l'utilisateur clique sur le bouton  "c'est parti" pour afficher la liste des enregistrements de la table "classe" d'une base de données.

Comme le montre l'image ci-contre, le programme affiche en grisé avec un liseret rouge à droite les informations brutes que renvoit le serveur (utiles pour le développeur) et entre les deux traits horizontaux, les données mises en forme pour l'utilisateur.

Le contenu de ces quatre fichiers est présenté ci-dessous.

 

index.html

Ce code est le coeur de l'exemple.
Dans les entêtes s'effectue la liaison avec les "bibliothèques" javascript (jquery.js et index.js) et css ( jquery-ui.css et index.css).
Dans le corps, les identifiants "test" et "test2" réservent l'espace pour afficher les réponses fournies pour le script index.js

Le code "html"

<?php
# FileName="index.php"
# etude de AJAX      
#
header('Content-Type: text/html; charset=UTF-8');
?>

<html>
<head>
    <meta http-equiv="Content-Type" content="charset=utf-8"/>
    <title> Test des ajaxEvent </title>
    <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/cupertino/j...">
    <link rel="stylesheet" href="index.css">

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
    <script src="../jquery/jquery-ui.js"></script>

    <script src="index.js"></script>

</head>
<body>
    <div>
        <div  class="colonne"
            <div id="loading" class="colonne"">
                <img src="loading.gif" width="100px" >
            </div>
            <div id="test" class="colonne"">
                <!-- complété par le script   info pour le développeur-->
            
               

            </div>
        </div>
        <hr/>
        <div id="test2">
                <!-- complété par le script  info pour l'utilisateur-->
        </div>
        <hr/>
        <form id="bySamClasseForm"  name="form1" action="" method="POST">
            <input type="button" id="btnSubmit" value="C'est parti..." />
        </form>
        
        
    </div>
</body>

index.css

Ce code est responsable de la mise en forme (gestion des 2 colonnes pour l'affichage du message d'attente puis pour l'affichage des informations "développeur").

le code CSS

        .colonne {
            display : table-cell;
            padding :10px;
        }
        
        .colonne:first-child{
            background:#F7F7EF;
            width : 19%;
            vertical-align: middle;
            border-right-color: red;
            border-right-style: groove;
        }
        .colonne + .colonne {
            border-left : 2px solid #fff;
            width :80%;
            vertical-align :middle;
        }

En fonctionnement normal, la fonction ajaxSuccess ("  $(document).ajaxSuccess (function(event, req, settings, donnee ){}"),  du fichier index.js complète le code html de la balise "div" identifiée" test2" par la portion de code "{ ... $("#test2").append( ...};". Pour comprendre le morceau de code " $("#test2").append", lire ce billet.
Cette fonction est déclenchée dès que la fonction $.ajax en  a terminé son exécution sans erreur. Cette dernière est elle même appelée par la fonction $.listeTest avec deux paramètres lorsque l'utilisateur clique sur le bouton ( identifié "btnSubmit") du formulaire.

La fonction ajaxComplete  ( "$(document).ajaxComplete(function (event,req,settings){..  $("#test").html( msg ); ....}) complète le code html de la balise "div" identifiée" test". Pour comprendre le morceau de code " $("#test").html()", lire ce billet.
Elle est déclenchée dès que la fonction $.ajax a terminé son exécution.

La fonction ajaxSend ("$(document).ajaxSend(function(event,req,settings){..  } ") est appelée au déclenchement de la fonction $.ajax et permet l'affichage d'une image "loading" pour faire patienter l'utilisateur.

Les fonctions  ajaxError, ajaxStop sont appelées par $.ajax selon les résultats de son exécution.

Par exemple, le résultat produit lorsque le mot de passe est mal renseigné dans le ficher ajaxTest.php est présenté ci-dessous :

Tout d'abord, affichage de la fenêtre d'alerte déclenchée par  ajaxError ("$(document).ajaxError (function(event, req,settings , err ){
        alert("dans " + settings.extra + " " + err);  });")


 

Puis l''affichage final produit  par ajaxComplete.
 

 

index.js

Ce code donne l'aspect dynamique de la page.
Il est expliqué plus en détail dans le paragraphe suivant.

 

le code JS

/*
 * index.js
 * script pour index.php
 *
 */
 
$(function(){
    
// mes fonctions

    $.listeTest = function(operation, name) {
        console.log ('dans listeEtudiant : operation = ' + operation );
        $.ajax({    
            //voir ajaxSetup non recommandée par api.jquery
            type: 'POST',
            url: 'ajaxTest.php'
            extra: 'listeTest',
            data: {
                op  : operation,
                nom : name,
            },
            dataType: 'json'
        });
        return true;
    };
    
    //fin mes fonctions

    
    $("#loading").hide();
    $(document).ajaxSend(function(event,req,settings){
        $("#loading").show();
        $("#test").text("Lancement de la requête " +  settings.url  );    
    });
    
    $(document).ajaxSuccess (function(event, req, settings, donnee ){
        var rows = donnee;
        console.log ('dans ' + settings.extra + ' : data = ' + settings.data);
        if (settings.extra == 'listeTest'){
            for (var i in rows) {
                $("#test2").append(rows.NomClasse + " : " + rows.NumClasse + " : " + rows.Libelle  + '<br/>');
            }
        };

    });
    $(document).ajaxError (function(event, req,settings , err ){
        alert("dans " + settings.extra + " " + err);
    });
    $(document).ajaxStop (function(event, req, settings){
        $("#loading").hide();
    });

$(document).ajaxComplete(function (event,req,settings){

        var msg = "Déclenché par le gestionnaire ajaxComplete :  ";
        msg += "</br>requête : " + req.status + " -:- " + req.statusText;
        msg += "</br>réponse reçue : "+ req.responseText;
        msg += "</br>settings :";
        msg += "</br>&nbsp;&nbsp;&nbsp; url :  " + settings.url;
        msg += "</br>&nbsp;&nbsp;&nbsp;type : " + settings.type;
        msg += "</br>&nbsp;&nbsp;&nbsp;data : " + settings.data;
    });
    
    $('#btnSubmit').on('click', function(e) {
        $.listeTest('selectClasse','abcdefcghiklmnopqrstuvwxyz');
    });
});

Ce code établit la connexion avec la base de données et renvoie les résultats sous l'encodage Json.

Coté serveur : le code PHP et la requête SQL

<?php
    # FileName="ajaxTest.php"    # Type="MYSQL"
    header('Content-Type: text/html; charset=UTF-8');

    //connection à la BD
    $hostname = "localhost";
    $database = "gestconv";
    $username = "xxxxxx";
    $password = "**************";

    $mysqli = new mysqli($hostname, $username, $password, $database);

    // Check connection
    if (mysqli_connect_errno())
    {
        $msg = "HTTP/1.1 428 Failed to connect to MySQL:" . mysqli_connect_error();
        header($msg);
        exit();
    }

    // Change character set to utf8
    mysqli_set_charset($mysqli,"utf8");
     //--------------------------------------------------------------------------
    // 2) Query database for data
    //--------------------------------------------------------------------------

    if (!(isset($_POST) && strlen($_POST)>0)){
        $msg="HTTP/1.1 427 requete trop mal formulee ! : l'argument opération est inattendu : ";
        header($msg);
        exit();
    }
    
    //sanitize post value, PHP filter FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH Strip tags, encode special characters.
    $op = filter_var($_POST,FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH);
  

switch ($op){
        case "selectClasse":
            // la requête SQL
            $sql = "SELECT NumClasse, NomClasse, Libelle, PourcentageReussite FROM classe ORDER BY NomClasse ASC ";
            $result = $mysqli
                ->query($sql);
                
            $data = array();  
            if ($result->num_rows > 0) {
                // output data of each row
                while($row = $result->fetch_assoc()) {
                    $data = $row;
                }
            }
            else {
                //pas d'enregistrement associé
                $data = "vide";
            };
            $mysqli->close();
            echo json_encode( $data );
            //echo $data;            
            break;

        default :
            $msg="HTTP/1.1 426 requete trop mal formulee ! : l'argument operation est inattendu : " . $op;
            header($msg);
            break;
    }

?>

Les "handler"  des appels des gestionnaires Ajax

Ils sont  de la forme function(event, request, settings, opt) dans lesquels

  • event : de  type object
  • request : la requête de type object
  • settings : les paramètres de la fonction ajax de type object
  • opt ; dépend du gestionnaire
    •  err : pour le gestionnaire ajaxError() ; de type object;
      • contient l'erreur générée par le fichier php appelé par ajax : (ex :     HTTP/1.1 426 requete trop mal formulee ! : l'argument operation est inattendu : select)      
    • data : pour le gestionnaire ajaxSucess(); de type string
      • contient les données générées par le fichier php appelé par ajax
    • n'existe pas sinon

On utilise habituellement

  1. request.readyState
          rends 0 : requête non initialisée, 1 : en cours de chargement, 2 : chargée, 3 : en cours d'interaction, 4 : terminée
  2. request.status pour le n°  figurant dans le header retouné par l'exécution du fichier php (ex : 426);
  3. request.statusText pour le texte figurant dans ce header (ex : requete trop mal formulee ! : l'argument operation est inattendu : select);
  4. request.responseText pour la valeur ( en texte) de retour fournie par le fichier php ;
  5. request.responseHTML ;
  6. request.responseJSON ;
  7. settings.url pour l'url du fichier php appelé par ajax (ex : ajaxTest;php);
  8. setting.extra pour obtenir la valeur du paramètre extra que j'ai utilisé dans ma fonction ajax et distinguer parmi l'ensemble des appels ajax, celui qui a provoqué le déclenchement du "handler" (ex : selectClasse);
  9. settings.data pour obtenir la valeur du paramètre data. Dans mon exemple, il vaut : op=selectClasse&nom=abcdefgh (les données passées dans l'url, lorsque le fonctionnement ne retourne pas une erreur) ;
  10. event.type (ex : ajaxComplete) ;
  11. event.handleObj.handler : le handler passé au gestionnaire.

Pour obtenir la liste des propriétés d'un objet, il est possible de procéder avec la portion de code ci-dessous  utilisé pour l'objet "settings"

 

 

 

les propriétés de l'objet "settings"

Object.getOwnPropertyNames(settings).forEach(function(val, idx, array) {
    msg += val + ' -> ' + settings (val ) + '</br>';
});

On accède à la valeur de la propriété par exemple par settings.url

Les propriétés affichées :

url -> ajaxTest.php
type -> POST
isLocal -> false
global -> true
processData -> true
async -> true
contentType -> application/x-www-form-urlencoded; charset=UTF-8
accepts ->
contents ->
responseFields ->
converters ->
flatOptions ->
xhr -> function (){try{return new XMLHttpRequest}catch(a){}}
jsonp -> callback
jsonpCallback -> function (){var a=Fb.pop()||n.expando+"_"+cb++;return this=!0,a}
extra -> listeTest
data -> op=selectClasse&nom=abcdefcghiklmnopqrstuvwxyz
dataType -> json
dataTypes -> text,json
crossDomain -> false
hasContent -> true