DataTables Edit avec x-editable

Introduction

Ce tutoriel n'est en fait pas tout à fait un tutoriel, mais on va plutôt voir comment intégrer le plugin x-editable, qui permet d'éditer des cellules du tableau.


Je pense que beaucoup d'entre vous connaissent le plugin x-editable.

Présentation

Comme le montre les images ci-dessous, j'ai intégré ce plugin dans un tableau DataTables, mais on pourrait utiliser aussi un tableau classique.

Cependant, l'intégration n'est pas trop difficile.

presentation

combobox

datepicker

Présentation du plugin x-editable

Comme moi vous avez sans doute regardé la démo, mais un détail, et non des moindres saute aux yeux, lorsque que l'on consulte le code source.

En effet, chaque liens sur la donnée (dynamique) et de format différent (date, datetime, select, text) ont tous un id dans le lien, et aucune démo ne présente la génération de ces données dynamiques dans une boucle. Et pour cause, imaginez, une table de 4 colonnes contenant dix enregistrements, tous cela mis dans une boucle (while) générera forcément 10 blocs <tr> contenant nos 4 <td>, et qui forcément générera 10 x 4 = 40 id dont dix seront indentiques.
Tous le monde sait qu'un id doit être unique dans une page, comme dans du code.

Oui mais !

Le fichier (jqueryui-editable.js) qui contient des milliers de lignes, est basé sur l'id.
Donc, si on laisse tel quelle, notre application n'est pas valide.
De plus, j'ai pas trouvé, c'est pas faute d'avoir cherché dans la doc, comment contrer l'attribution de cet id.

Vous allez me dire, vos images représentant votre appli de démo n'est pas fonctionnelle. Je vous dirais que si.
Car dans ce fichier que je viens de citer, si on regarde la ligne 1493, on y voit ceci (this.options.name = this.options.name || this.$element.attr('id');).
Ce qui veut dire que les éléments doivent être tous basés sur un id, pour un seul ca va, mais pas dans une boucle.
NOTA : j'ai pas regardé celui de Bootstrap, à vous de chercher.

Intégration

Je vais vous montrer comment j'ai intégré ce plugin dans le tableau.

Intégration avec des id

Ce code n'est pas à utiliser Vous pouvez imaginer ce qui se passera lorsque la boucle aura fini son traitement, faite le test, et généré le code source, vous allez vite comprendre.

           <tbody>
              <?php
              while ($datas = $sql->fetch(PDO::FETCH_ASSOC)) {  
              ?>
              <tr>
                 <td><?php echo $datas['ID']; ?></td>
                 <td><a href="#" id="MAT" data-type="text" data-pk="<?php echo $datas['ID']; ?>" data-url="edit/ajax.php" ><?php echo $datas['MAT']; ?></a></td>
                 <td><a href="#" id="NOM" data-type="text" data-pk="<?php echo $datas['ID']; ?>" data-url="edit/ajax.php"><?php echo $datas['NOM']; ?></a></td>
                 <td><a href="#" id="SRV" data-type="text" data-pk="<?php echo $datas['ID']; ?>" data-url="edit/ajax.php"><?php echo $datas['SRV']; ?></a></td>
                 <td><a href="#" id="POSTE" data-type="select" data-source="{'1': 'PROGRAMMEUR', '2': 'CHEF SERVICE', '3': 'CONCEPTEUR', '4': 'DEVELOPPEUR', '5': 'OPERATEUR', '6': 'COMPTABLE'}" data-pk="<?php echo $datas['ID']; ?>" data-url="ajax.php"><?php echo $datas['POSTE']; ?></a></td>
                  <td>
                  <?php 
                  $dates = $datas['DAT'];
                  $date_fr = strftime('%d-%m-%Y', strtotime($dates));
                  ?>
                  <a href="#" class="DAT" data-type="date" data-original-title="Selectionner une date" data-pk="<?php echo $datas['ID']; ?>" data-url="edit/ajax.php"><?php echo $date_fr; ?></a>
                  </td>
                  <td><?php echo $datas['MEMBRE']; ?></td>
                  <td><a class="delete" href="#"></a></td>
              </tr>
              <?php
               }
              ?>
            </tbody>
        
Intégration avec des class

Comme vous l'aurez compris, pour utiliser ce tableau avec des class, il faut modifier la ligne 1493 du fichier (jqueryui-editable.js) et remplacer (id) par (class).

            <tbody>
                  <?php
                  while ($datas = $sql->fetch(PDO::FETCH_ASSOC)) {  
                  ?>
                  <tr>
                     <td><?php echo $datas['ID']; ?></td>
                     <td><a href="#" class="MAT" data-type="text" data-pk="<?php echo $datas['ID']; ?>" data-url="edit/ajax.php" ><?php echo $datas['MAT']; ?></a></td>
                     <td><a href="#" class="NOM" data-type="text" data-pk="<?php echo $datas['ID']; ?>" data-url="edit/ajax.php"><?php echo $datas['NOM']; ?></a></td>
                     <td><a href="#" class="SRV" data-type="text" data-pk="<?php echo $datas['ID']; ?>" data-url="edit/ajax.php"><?php echo $datas['SRV']; ?></a></td>
                     <td><a href="#" class="POSTE" data-type="select" data-source="{'1': 'PROGRAMMEUR', '2': 'CHEF SERVICE', '3': 'CONCEPTEUR', '4': 'DEVELOPPEUR', '5': 'OPERATEUR', '6': 'COMPTABLE'}" data-pk="<?php echo $datas['ID']; ?>" data-url="ajax.php"><?php echo $datas['POSTE']; ?></a></td>
                      <td>
                      <?php 
                      $dates = $datas['DAT'];
                      $date_fr = strftime('%d-%m-%Y', strtotime($dates));
                      ?>
                      <a href="#" class="DAT" data-type="date" data-original-title="Selectionner une date" data-pk="<?php echo $datas['ID']; ?>" data-url="edit/ajax.php"><?php echo $date_fr; ?></a>
                      </td>
                      <td><?php echo $datas['MEMBRE']; ?></td>
                      <td><a class="delete" href="#"></a></td>
                  </tr>
                  <?php
                   }
                  ?>
                </tbody>
         

Intégration avec l'attribut (data-*) (MAJ le 27/03/2017)

Récemment, j'ai découvert que l'utilisation comme je le faisais, était ardu, il suffisait en fait d'utiliser dans le lien l'attribut (data-name) ayant comme valeur exactement le nom (caractères semblables) de la colonne de votre table de votre base de données.

Explication du code

Dans le code ci-dessus, les noms des champs de la table MySQL sont en majuscules.
Ensuite pour chaque cellules, que l'on veut modifier, il suffit, de déclarer un lien, avec une (class), le nom de cette classe doit ABSOLUMENT être identique au nom de la colonne de la table MySQL.
Puis, de définir (data-type) soit (text, date, select) il y en a d'autres.
De définir la valeur de (data-pk), pk pour primary key.
Puis de définir (data-url) en indiquant le chemin du fichier qui exécutera un UPDATE de la valeur.

Code JavaScript

Dans ce script, on y défini que les cellules ayant un lien (a) dans l'id du tableau(#menuTable) seront éditable.
Le second script, fait référence au lien, avec la fonction (datepicker).

           <script type="text/javascript">
                $(document).ready(function() {
                  $.fn.editable.defaults.mode = 'inline';  
                    $('#menuTable a').editable();
                    
                    $('a.DAT').editable({
                        format : 'yyyy-mm-dd',
                        viewformat : 'dd-mm-yyyy',
                        datepicker : {
                            //weekStart : 1,
                            showAnim: "slide"
                        }
                    });
                });
          </script>
        

Les fichiers

Pour récupérer les fichiers cités ci-dessous, veuillez vous rendre à cette adresse, (https://vitalets.github.io/x-editable/)

Attention, les liens en commentaire, sont ceux pour bootstrap, de plus vous remarquerez les liens (1) et (2), dont un est pour les éléments avec 1 seul id, et le second pour les éléments avec des class.

          <link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet" type="text/css" />
          <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.10/css/dataTables.jqueryui.min.css">
          
          <link rel="stylesheet" type="text/css" href="edit/css/jqueryui-editable.css"> 
          <!--<link href="css/bootstrap.min.css" rel="stylesheet" type="text/css">-->
          
          
          <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
          <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
          <script src="https://cdn.datatables.net/1.10.11/js/jquery.dataTables.min.js"></script>
          <script src="https://cdn.datatables.net/1.10.11/js/dataTables.jqueryui.min.js"></script>
          
          (1)<!--<script type="text/javascript" src="js/jqueryui-editable_id.js"></script>-->
          (2)<script type="text/javascript" src="edit/js/jqueryui-editable_class.js"></script> 
          <script type="text/javascript" src="edit/js/ui.datepicker-fr.js"></script>
          <!-- 
          <script src="js/bootstrap.min.js"></script>
          <script src="js/bootstrap-editable.js" type="text/javascript"></script> 
          -->
        

Fichier (ajax.php)

Sans ce fichier, le plugin ne sert à rien. Ce code fonctionne avec PDO, car l'extension (mysql_) devient obsolète.

          <?php
          require_once('../pdo.php');
          if(isset($_POST['name'])){
              $column=$_POST['name'];
              $new_value=$_POST['value'];
              $id=$_POST['pk'];
              
              try
              {
              $update = $PDO->prepare("UPDATE employes SET $column='$new_value' WHERE ID='$id'");
              $update->execute(); 
              }
              catch(PDOException $e) {
                        $msg = 'ERREUR PDO dans ' . $e->getFile() . ' L.' . $e->getLine() . ' : ' . $e->getMessage();
                        die($msg);
                      }
              
              echo $id;
              echo '<br>';
              echo $new_value;
              echo '<br>';
              echo $column;
          }
          ?>       
        

Conclusion

Je vous ai présenté ma méthode ici, mais peut être y a t'il mieux, en tout cas dans mon back-end cela fonctionne.

Bon dev