Sélectionner une page

Informations (très) utiles sur DataTable

DataTable dispose de beaucoup d’options; Voici celles qu’il est recommandé d’utiliser dans notre contexte :

Le bon usage des COLUMNS/RENDER #

Les solutions automatisées (sans render) sont pratiques, mais très limitées. Elles sont faites pour prendre l’outil en mains, mais les vraies solutions pour des applications sérieuses et flexibles dépendent de l’utilisation de COLMUNS, COLUMNSDEF et RENDER.

Si les données viennent de SqlForJson.asp #

Lorsque les données viennent de SqlForJson, la source est une requête (souvent simple). Les données sont donc brut et correspondent exactement à ce qui se trouve dans les champs de la requête. L’affichage des informations issues de ce type de Json peut nécessiter de nombreuses transformations côté client, ce qui justifie parfois des renders relativement longs, et des imbrications complexes.

Si les données viennent de RecordsetForJson.asp #

Il y a deux raisons pour lesquels on peut être amené à utiliser un RecordsetForJson :

  • Transformer les données issues d’une ou plusieurs requêtes, car une requête sql simple ne peut pas fournir les données attendues.
  • Transformer les données (même d’une seule requête), dans le but de fournir un json simple et épuré (pour simplifier les renders).

Résultat :

  • L’intervention devient plus facile côté client
  • Régis peut trouver des ressources plus facilement (on trouve beaucoup plus des développeurs Javascript que de développeurs ASP Classic).
  • Si on doit changer de techno côté serveur (la bascule vers du full .Net est evisageable), il y aura peu de choses à faire (il suffira de générer le fichier JSON à l’aide de la nouvelle technologie, et de l’envoyer au client. le fichier html sera exécuté de la même manière.

Dans la plupart des cas, nous avons privilégié SqlForJson lorsque c’était possible, et dès que RecordsetForJson s’avérait nécessaire, nous en avons profité pour tranformer les données côté serveur, afin que le client ait un minimum de lignes dans ses renders.

Si les données viennent d’une fonction sur un objet .Net #

Techniquement, Il s’agit d’un cas équivalent à RecordsetForJson, mais avec les bénéfices que procure .Net en termes de codage et de rapidité d’exécution. Cette solution nécessitant une refonte profonde du code, elle n’a pas été adoptée partout.

Elle est opérationnelle sur :

  • study.getPatientsFolders(user,sqlTab) : donne la liste des dossiers d’un utilisateur en utilisant comme source initiale la requêtes sqlTab (données à tranformer). Cette fonction rend une liste de PatientFolder dont les propriétés sont faciles à modifier /debugger pour les développeurs .Net.

Utiliser data tant que possible #

data permet de faire abstraction du nom du champ associé à la colonne en cours. On peut ainsi écrire If(data<18){return « Mineur »}, si on se trouve dans la colonne age. L’alternative est d’utiliser row.age, mais dans le cas où le nom de la propriété viendrait à changer, il faudrait intervenir sur plusieurs lignes de code. Avec data, il suffit d’annoncer une fois (avat le render) le nouveau nom de la propriété.

La fonction afterDataTable() #

J’ai apporté les adaptations nécessaire à DataTable pour qu’il soit compatible avec populate() et d’autres pratiques que nous avons adoptées. La fonction afterDataTable s’exécute une fois que DataTable() a tracé le tableau. Elle permet d’apporter quelques modifications sur la page en cours immédiatement après le traçage. Le besoin de créer cette fonction n’est pas courant, mais c’est le moyen idéal de s’assurer que l’exécution se fera au bon moment. Tant que possible, afterDataTable() est préférable à setTimeOut, dont le délai est difficile à évaluer (il dépend du device et de la taille du tableau).

Le <thead> associé à populate() #

La fonction populate crée automatiquement un thead en fonction des colonnes présentes dans le code html. Il n’est donc plus nécessaire de créer de thead manuellement. Cette solution permet aussi d’ajouter, supprimer, inveser simplement des colonnes dans columns pour que celles-ci s’ajoutent automatiquement au tableau (sans changer la section thead du html).

TODO : réécrire la suite en remplaçant data-search (html) par le paramètre json correspondant.

data-search : permet de placer un champ de recherche qui ne concerne que la clonne en cours.

<th data-search="text">Code Produit</th>

Les trois valeurs possible du daa-serach sont :

text : pour saisir ce qu’on cherche dans une zone de texte

select : pour sélectionner ce qu’on cherche dans une liste précise (par défaut, elle contient les différentes valeurs comprises dans la colonne en cours, mais il est possible de l’enrichir ou de supprimer certaines options).

select withEmpty : ajoute à la liste la possibilité de rechercher les cellules vies ou non vides

check : permet de faire une recheche sur une colonne contenant des checkbox

Exemple #

<thead>
    <tr>
        <th data-search="check">{lbl:1348}<!--Disponible pour le centre--></th>
        <th data-search="text">{lbl:1409}<!--Code produit--></th>
        <th data-search="select">{lbl:346}<!--Status--></th>
        <th data-search="select withEmpty">{lbl:631}<!--Center--></th>
        <th data-search="select">{lbl:6}<!--Treatment Group--></th>
        <th data-search="select withEmpty">{lbl:1349}<!--Batch--></th>
        <th data-search="text">DLC<!--DLC--></th>
        <th style="border-bottom:0"><!--Modifier--></th>
    </tr>
</thead>

Toujours utiliser un DT_RowId dans la requête source #

Dès que nous utilisons un tableau avec des boutons ou des liens, nous devons retrouver des informations se trouvant dans la base de données afin de traiter la bonne ligne.

Nos requêtes contiennent toutes le champ clé de la base de données, mais il faut penser à renommer le champ clé DT_RowId (en ajoutant « AS DT_RowId » sur cette colonne-là). Il est également préférable que DT_RowId Soit toujours le premier champ dans une source JSON (et donc dans le requête SQL qui le construit).

En l’utilisant systématiquement, on peut simplifier nos fonctions :

Dans le render #

Dans les RENDER, l’utilisation de DT_RowId se fait sur les évènements. Il permet d’appeler la fonction liée à l’évènement avec le bon argument

"<button ... onlClick='maFonction(" + row.DT_RowId + ">)"

Dans la fonction appelée par l’évènement #

Dans la fonction on peut savoir quelle ligne a été cliquée grâce à ce code :

function maFonction(id) {
   var $row = $("#idDatatable").DataTable().row("#" + id)
   ...
}

Attention : la variable $row ne représente pas le même objet que $(« # » + id) :

  • $row désigne un objet ligne de la DataTable, qui est très riche en termes de propriétés, de méthodes et d’évènements.
  • $(« # » + id) fait uniquement référence à la « <tr> » du DOM

Ceci signifie que pour modifier $(« # » + id), il faudra également toucher au DOM… C’est ce que nous avons fait sur nos premières pages (sur l’admin), et qui a demandé beaucoup d’efforts.

L’objet $row est beaucoup plus manipulable et demande moins d’effortds de programmation :

Utilisation del’objet $row #

On peut demander la valeur de n’importe quel champ de cette ligne :

if ($row.data().NomChamp=="toto"){...}

On peut aussi modifier ces valeurs en les réaffectant :

$row.data().NomChamp = "toto"

Lorsque la donnée change, cela n’affecte pas le tableau, car on ne touche pas à son rendu. Ce qui est modifié, c’est la donnée uniquement. Pour que le tableau soit impacté, il faut retracer la ligne :

$row.invalidate().draw()

Cette instruction est TRES utile, car elle réexécute le render de chaque colonne de $row. Elle retrace donc l’intégralité de la ligne en fonction de la nouvelle donnée. Si le champ affecté concerne le rendu de plusieurs colonnes, toutes ces colonnes changeront d’apparence en fonction des règles données dans chaque render. C’est un gain de temps énrome comprativment au travail nécesaire sur le DOM.

Astuce : si on veut modifier plusieurs lignes en une seule instruction, c’est possible en appliquant .invalidate() sur chacune d’entre-elles, sans faire de draw() :

$row.invalidate()

Ensuite, il est possible d’utiliser rows().draw() sur la DataTable, ce qui aura pour effet de retracer toutes les lignes invalidées préalablement :

$("#idDatatable").DataTable().rows().draw()

Exemples #

L’exemple le plus évocateur au moment de l’écriture de ce document se trouve dans Gestion_produits_arc.asp. Pratiquement tout est designé côté client. La v1 de cette page a été allégée de 95%. Le serveur s’occupe principalement de fournir la bon flux JSON pour nourrir le tableau. Le gain de temps utilisateur est également ressenti grâce au fait que les actions n’appellent pas le serveur pour retracer l’ensemble du tableau, mais uniquement quelques lignes.

(il es tpossible au’au moment de votre lecture, la page ne soit pas complètement terminée, mais vous pouvez observer le code sur les render, ainsi que l’appel aux fonctions Ajax pour vous en inspirer).

Powered by BetterDocs