DataTable edition cellule avec Ajax

Introduction

Avec ce tutoriel, voici une autre façon d'effectuer l'édion de certaines cellules du tableau en HTML 5 et PHP / PDO.
Il existe beaucoup de plugin qui fournissent des fonctionnalités d'édition de données.
Pour le cas ici, j'ai pris un tableau mis en forme avec DataTables, mais on pourrait tout aussi bien utiliser un tableau classique mis en forme en CSS.

Voici un aperçu de ce tableau

data edition

Ci-dessus les cellules dont les données sont en rouge (pour l'exemple).
Pour éditer une des données (en rouge) il suffit juste de cliquer dans la cellule pour la rendre modifiable, ainsi la cellule à le focus et le curseur (|) apparait en clignotant.
Modifier ensuite la valeur et cliquer hors de la cellule, la mise à jour en base de données est modifiée.
NOTA : Ce genre de script n'est pas à utiliser coté utilisateur, mais plutôt dans un back office.

Mise en place du code HTML

Dans un premier temps, placer ce code (<div id="msg" class="alert"></div>) au dessus de votre tableau.

Passons maintenant au code HTML des cellules (td) et de la ligne (tr).

Pour la ligne (tr) ajouter un id dynamique , id qui est la clé primaire de votre table (<tr data-row-id="<?php echo $datas['ID']; ?>">).

Pour les cellules (td).

<td class="editable-col" contenteditable="true" col-index='0' oldVal ="<?php echo $datas['MAT'];?>"><?php echo $datas['MAT']; ?></td>
<td class="editable-col" contenteditable="true" col-index='1' oldVal ="<?php echo $datas['NOM'];?>"><?php echo $datas['NOM']; ?></td>
<td class="editable-col" contenteditable="true" col-index='2' oldVal ="<?php echo $datas['SRV'];?>"><?php echo $datas['SRV']; ?></td>
<td class="editable-col" contenteditable="true" col-index='3' oldVal ="<?php echo $datas['POSTE'];?>"><?php echo $datas['POSTE']; ?></td>

Les cellules ont toutes la même classe.
Ont toutes l'attribut (contenteditable à true).
La première cellule qui contient la données dynamique de la première colonne de la table MySQL porte l'attribut (col-index à 0
et ainsi de suite pour les cellules suivantes concernant les données dynamiques des colonnes suivantes de la table MySQL

Script JavaScript

Ce code sera à placer à la fin de la page et avant la balise de fermeture </body>

          $(document).ready(function(){
            $('td.editable-col').on('focusout', function() {
              data = {};
              data['val'] = $(this).text();
              data['id'] = $(this).parent('tr').attr('data-row-id');
              data['index'] = $(this).attr('col-index');
                if($(this).attr('oldVal') === data['val'])
              return false;
              
              $.ajax({   
                    
                    type: "POST",  
                    url: "modif_ajax.php",
                    cache:false,  
                    data: data,
                    dataType: "json",       
                    success: function(response)  
                    {   
                      if(response.status) {
                        $("#msg").removeClass('alert-danger');
                        $("#msg").addClass('alert-success').html(response.msg);
                      } else {
                        $("#msg").removeClass('alert-danger');
                        $("#msg").addClass('alert-success').html(response.msg);
                      }
                    }   
                  });
            });
          });
        

La page (modif_ajax.php)

Cette page va transmettre où plutôt mettre à jour la ou les nouvelles données modifiées dans la table MySQL.
Le code ci-dessous est réalisé en PDO

          <?php 
            //definition des index des colonnes
            // nom des colonnes de la table dans l'ordre
            $columns = array(
              0 =>'MAT',
              1 =>'NOM',
              2 =>'SRV',
              3 =>'POSTE'
            );
            $error = true;
            $colVal = '';
            $colIndex = $rowId = 0;
            
            $msg = array('status' => !$error, 'msg' => 'Echec mise à jour');
          
            if(isset($_POST)){
              if(isset($_POST['val']) && !empty($_POST['val']) && $error) {
                $colVal = $_POST['val'];
                $error = false;
                
              } else {
                $error = true;
              }
              if(isset($_POST['index']) && $_POST['index'] >= 0 &&  $error) {
                $colIndex = $_POST['index'];
                $error = false;
              } else {
                $error = true;
              }
              if(isset($_POST['id']) && $_POST['id'] > 0 && $error) {
                $rowId = $_POST['id'];
                $error = false;
              } else {
                $error = true;
              }
            
              if(!$error) {
                  $sql = $PDO->prepare("UPDATE employes SET ".$columns[$colIndex]." = '".$colVal."' WHERE ID='".$rowId."'");
                  $sql->execute();
                  $msg = array('status' => !$error, 'msg' => 'Success! mise à jour réussies');
              }
            }
            
            // retour des donnes envoyes avec le format json
            echo json_encode($msg);
            
          ?>
        

Code CSS

Le code CSS fait référence au bloc div #msg et à la couleur des données des (td) ayant (contenteditable).

          .alert {padding: 15px;margin-bottom: 20px; border: 1px solid transparent;border-radius: 4px;}
          .alert-success {color: #3c763d;font-weight:bold; background-color: #dff0d8; border-color: #d6e9c6;}
          .alert-danger {color: #a94442;font-weight:bold;background-color: #f2dede;border-color: #ebccd1;}
          td[contenteditable="true"] {color: #F00; font-weight:bold;}
        

Script dynamique

Maintenant imaginons que vous souhaitiez appliquer ce script à tous les pages de votre back-end ? Comment faire ?
Si l'on regarde le script, je parle celui du JavaScript on a (url: "modif_ajax.php",) c'est à dire qu'il fait référence à une page donnée, pour une table MySQL donnée.
Or à priori, il n'est pas possible d'appliquer ce script (mis dans un fichier externe) qui soit appellé dans chacune des pages de votre back-end.
Puisque l'url soit (modif_ajax.php) ne correspondrait pas du tout, et qui fait référence à une seule page.

Le principe, et de rendre l'url dynamique, oui, mais comment ?
Nous avons vu que dans chaque cellule nous avions des attributs. Il suffit de rajouter un attribut de ce type (data-href="votre_fichier.php").
Puis dans le script JS de déclarer celui-ci (var url = $(this).attr("data-href");).
Puis de définir dans la fonction ($.ajax), l'élément (url) par (url: url,).
Ainsi, à chaque clique sur une cellule, ce dernier appelera votre fichier php (votre_fichier.php) correspondant à la page pour lequel il est destiné.
Bien sur, il suffira de redéfinir le code comme nous l'avons vu dans le fichier (modif_ajax.php).

Pourquoi faire ceci, en fait cela est simple, cela évite de copier le script JS une multitude fois dans vos pages, car il suffira de faire simplement l'appel de ce fichier ( <script src="js/editable.js"></script> ) dans vos pages, sans vous souciez de l'url.

 

Bon dev.