4Code Logo
retour page 1/1

Maintenance de la BDD en Ajax

Bonjour,

Suite à la demande d'un internaute, j'ai monter ce petit tutos mélangeant PHP (non POO) et Javascript (simplifié) pour décrire le comportement d'une administration simplifiée d'une Base de Donnée en Ajax.

Je me suis une fois de plus appuyé sur Prototype pour certaines fonctions (Ajax surtout ^^) mais vous pourrez trés bien vous en passer ou utiliser une autre librairie !

Le principe de base est le suivant :

  • Nous avons une <table> contenant pour chacune de ses lignes une ligne de notre BDD,
  • Nous ajoutons pour chaque lignes 2 images (update et delete) servant à administrer la ligne de la BDD et contenant en identifiant id "'.$action.'_'.$idRow.'"
  • Nous ajoutons à notre page HTML un formulaire "masqué" (display:none) préfabriqué qui nous servira pour la mise à jour (update) de notre BDD.

Nous souhaitons que lors du click sur l'image update :

  • le formulaire s'affiche à l'endroit ou nous avons clické,
  • son input prenne en valeur celle contenue dans la table,
  • Et lors de la validation du formulaire, la BDD se mette à jour et notre Tableau aussi ^^ ... et tout ça, sans rechargement de la page !

Lors d'un click sur l'image delete :

  • après confirmation de l'internaute,
  • notre BDD efface la ligne correspondante au bouton,
  • Nous supprimons la ligne de notre tableau.

Je vais donc vous décrire ici le fonctionnement général en commençant par le HTML :

    <body>
        <div id="page">
            <table border="1">
                <thead>
                    <tr>
                        <th>Description</th>
                        <th>Action : </th>
                    </tr>
                </thead>
                <tbody><?
        //déclaration des lignes de notre tableau mises en forme à l'aide la fonction row()
        foreach ($array as $k => $desc){
            echo '
                    <tr>'.rows(array('id'=>$k, 'description'=>$desc)).'
                    </tr>';
        }
?>
                </tbody>
            </table>
            <!-- La div access contenant notre formulaire est masquée par défaut (display:none) -->
            <div id="access" style="display:none;position:fixed;background:white;border:2px black solid;padding:10px;text-align:center;">
                <!-- notre lien servant à fermer le formulaire lors du click sur la span, le style display de l'élément #access passe à "none" -->
                <div style="text-align:right;"><span onclick="javascript:$('access').hide();">Fermer</span></div>
                <!-- Notre formulaire -->
                <form id="formulaire" action="index.php" method="POST" enctype="multipart/form-data">
                    <label for="description">Description : </label>
                    <input type="text" name="description" id="description" value="" /><br />
                    <input type="submit" value="Envoyer" />
                </form>
            </div>
        </div>
    </body>

Je me suis aidé de la fonction row() en php présentée ci-dessous car nous en auront besoin pour mettre en forme notre réponse lors de l'update. Et tant qu'a faire, autant ne pas reproduire maintes fois la même mise en forme.

Au niveau du traitement PHP (impérativement avant la déclaration du <!doctype> :

<?php
/**
 * fonction rows en charge de mettre en forme nos lignes du tableau (entre les éléments <tr> et </tr>
 * @param <array> $line de la forme array('id'=>$idKey, 'description'=>$description)
 * @return <string> retourne la chaine de caractère HTML mise en place avec les identifiant des images correctement formatés
 */
function rows($line){
    return '<td>'.$line['description'].'</td>
        <td>
            <img src="img/update.png" alt="update" id="update_'.$line['id'].'" />
            <img src="img/update.png" alt="delete" id="delete_'.$line['id'].'" />
        </td>';
}
/**
 * Fonction en charge d'éfectuer la mise à jour de notre BDD, ici nous ne faisons pas le traitement de la bdd
 *  mais décrivons le comportement pouvant etre mis en place
 * @param <array> $array tableau principal contenant tous les éléments issus de notre BDD de la forme :
 *        array( $idKeyRow1 => $descriptionRow1, $idKeyRow2 => $descriptionRow2, $idKeyRow3 => $descriptionRow3,...);
 * @param <string> $id est l'id de notre image, celle sur laquelle l'internaute à clické ....
 * @return <string> retourne la réponse du serveur suite au traitement de l'information contenue dans $id
 */
function updateArray($array, $id){
    // extraction de l'action et $idKey contenu dans l'id de notre image et séparés par "_"
    $action = explode('_', $id);
    // vérification de la validité de $idKey
    if(isset($action[1]) && !empty($array[$action[1]])){
        // lancement des opérations en fonction de l'action demandée
        switch($action[0]){
            case "update" :
                if(!empty($_POST['description'])){
                    // c'est ici que vous effectuez votre opération de mise à jour de la bdd en utilisant
                    //        $action[1] pour retrouver la ligne de votre tableau et
                    //        $_POST comme valeurs à mettre à jour ...
                    // puis vous retourner la ligne du tableau mise en forme à l'aide de notre fonction row()
                    // ici nous retournons directement les informations reçues, du fait que nous ne faisons pas
                    // de sauvegarde. mais vous devez vérifier la bonne mise à jour de la bdd avant de retourner ce quelle contient
                    return rows(array('id'=>$action[1], 'description' => $_POST['description']));
                }
            break;
            case "delete" :
                // ici vous effectuez votre requete servant à suprimmer de la bdd votre ligne en vous aidan de l'idantifiant $action[1]
                return 'TRUE';
            break;
            default :
                // si l'action demandée n'a pas été envisagée, nous retournons un message d'erreur qui sera affiché en alert()
                return "erreur : commande incomprise !";
            break;
        }
    } else
        // si l'identifiant est absant ou incohérant, nous retournons un message d'erreur qui sera affiché en alert()
        return "erreur : mauvais formatage des données";
}
// Notre tableau issu de notre BDD dans la forme array($idKeyRow => $DescriptionRow)
$array = array("0"=>"lineOne", "CeQueJaVeux"=>"lineTwo", "blabla"=>"lineThree");

// Nous vérifions la reception d'une variable 'Ajax' en method POST
if(!empty($_POST['Ajax'])){
    // lancement de nos opérations Ajax
    echo updateArray($array, $_POST['id']);
    // interruption du script pour ne pas retourner le HTML
    die();
}

?>

Donc, désormais nous savons comment fonctionne le serveur en cas de requête Ajax, mais aussi quels éléments HTML sont mis en place pour générer notre page, nous alons pouvoir voir en détail le fonctionnement Javascript

Mais avant toute chose, n'oubliez pas de lier votre script Prototype.js

     <head>
         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
         <title>Exemple de manipulation d'une table en Ajax</title>
         <script type="text/javascript" src="http://prototypejs.org/assets/2009/8/31/prototype.js"></script>
         <script type="text/javascript">
             /*
              * Nous initialisons les variables utilisées par plusieurs fonctions indépendantes.
              */
             var id;
             /*
              * function utilisée pour supprimer une ligne du tableau
              * @param event <object> evennement envoyé en attribut à la fonction lors de son appel
              */
             var useAjaxDelete = function(event){
                 //demande de confirmation par l'internaute
                 if (confirm('etes vous certain de vouloir supprimer cette ligne ?')) {
                     // initialisation de la variable id avec l'id de l'image sur laquelle l'utilisateur à clické
                     id = event.element().id;
                     // requete Ajax à destination de la page courante
                     new Ajax.Request(window.location.href, {
                         //paramètres envoyés en méthode POST :
                         // l'identifiant de l'image sur laquelle on a clickée et la variable _POST['Ajax'] servant à informer le serveur de notre Requête Ajax
                         parameters : {'id' : id, 'Ajax':1},
                         // fonction appelée lors de la récupération des données depuis le serveur
                         onComplete : function(xhr){
                             var response = xhr.responseText;
                             if(response == 'TRUE')
                                 // supression de la ligne du tableau
                                 $(id).ancestors()[1].remove();
                             // affichage en alert() de la réponse du serveur si celle ci est différante de 'TRUE'
                             else alert(xhr.responseText);
                         }
                     });
                 }
             }
             /*
              * fonction appelée lors du click sur l'image "update"
              */
             var useAjaxUpdate = function(event){
                 // initialisation de l'id à utiliser
                 id = event.element().id;
                 // affichage de l'élément #access (div contenant notre formulaire) et attribution aux styles top et left des coordonés du click de souris
                 $('access').show().setStyle({top:event.clientY+"px", left:event.clientX+"px"});
                 // atribution en valeur à notre champ input#description du contenu de la première cellule, de la ligne courante, du tableau
                 $('description').value = $(id).ancestors()[1].down('td').innerHTML;
             }
             /*
              * Fonction appelée lors de l'upload du formulaire
              */
             var updateForm = function(ev){
                 // interruption de l'envoi "normal" du formulaire, pour le remplacer par un envoi en ajax
                 ev.stop();
                 // fonction FORM.request() de prototype permettant d'envoyer automatiquement le formulaire en Ajax en utilisant sa cible et méthod.
                 $('formulaire').request({
                     // ajout de notre paramêtre id aux éléments envoyés et de la variable Ajax pour le traitement des données !
                     parameters : {'id' : id, 'Ajax':1},
                     // fonction callBack appelée après réception des données par la requête Ajax
                     onComplete : function(xhr){
                         var response = xhr.responseText;
                         // vérification que la réponse commence bien par la chaine "<td>"
                         if(response.substring(0,4) == "<td>"){
                             //Remplacement du html contenu dans la ligne "<tr>" courante de notre tableau
                             $(id).ancestors()[1].innerHTML = response;
                             // rechargement des écouteurs pour prendre en charge nos nouelles images
                             loadEventClick();
                         } else
                             //si la réponse n'es pas celle attendu, nous affichons la répose du serveur
                             alert(xhr.responseText);
                         $('access').hide();
                     }
                 });
             }
             /*
              * Fonction en charge de déclarer/nettoyer les écouteurs...
              */
             var loadEventClick = function(){
                 // supression des écouteurs pour éviter les doubons !
                 $$('.AjaxUseDelete').invoke('stopObserving', 'click');
                 $$('.AjaxUseUpdate').invoke('stopObserving', 'click');
                 $('formulaire').stopObserving('submit');
                 // Déclaration des écouteurs :
                     // sur les images delete => appeler la fonction useAjaxDelete
                     $$('.AjaxUseDelete').invoke('observe', 'click', useAjaxDelete);
                     // sur les images update => appeler la fonction useAjaxUpdate
                     $$('.AjaxUseUpdate').invoke('observe', 'click', useAjaxUpdate);
                     // pour la surveillance du Submit de notre formulaire
                     $('formulaire').observe('submit', updateForm);
             }
             // nous plaçon un écoutur sur le chargement de la page (onLoad)
             document.observe('dom:loaded', function(){
                 // initialisation de nos écouteurs
                 loadEventClick();
             });
         </script>
     </head>
 
 

Et voilà !.... vous pouvez tester cette petite fonction ici !...

N'hésitez pas à nous laisser vos commentaires, et/ou demandes d'aides sur un cas particulier, nous y répondrons ;)

@+ & BonCode ;)

par Nours312 le 05/02/2010 à 13:26

Commentaires des internautes :
difficilement digeste, mais sympa !... merci !

par visiteur le 08/02/2010 à 15:24

retour page 1/1