skip to main | skip to sidebar
Code 18
Manuel du savoir-faire à l'usage des geeks et des curieux
RSS
  • Accueil
  • Le web au Québec
  • Liens
  • Twitter
  • Facebook
  • À propos

lundi 2 novembre 2009

Façon élégante de créer des tables dynamiques

Publié par Infinite Loop, à 19 h 43 4 commentaires

Il m'arrive parfois de travailler avec des programmeurs qui comptent moins d'expérience (et parfois) et fait surprenant, il semblerait que ça soit le cauchemar de tous et chacun lorsque vient le temps de générer une table HTML dynamique. Par dynamique, j'entends qu'elle est créée par programmation, par exemple en PHP.

Habituellement, le code est parsemé de "if", de flags pour indiquer où on est rendu et des instructions echo qui impriment une portion du code HTML ici et là. Bref, rien de facile à suivre et le résultat s'apparente rapidement à l'image qu'on se fait du code spaghetti.

De plus, ça arrive très souvent que la validation HTML ne respecte pas les standards d'évaluation de Tidy, SGML Parser ou W3C (ce que j'ai vu le plus souvent est un </td> ou </tr> qui ne ferme pas parce que le bris de séquence est mal construit).

Pour contrer cela, il existe plusieurs moyens mais je suggère une solution simple et originale : créer le tableau avant de l'afficher. Une fois que la structure du tableau (array) illustre la représentation de la table HTML, il suffira de faire une première boucle pour afficher les rangées et une deuxième imbriquée pour lister les colonnes.

Imaginons les données suivantes qui pourraient provenir d'une base de données :

$data = array(
array('id' => 10, 'value' => 'a'),
array('id' => 20, 'value' => 'b'),
array('id' => 30, 'value' => 'c'),
array('id' => 40, 'value' => 'd'),
array('id' => 50, 'value' => 'e'),
array('id' => 60, 'value' => 'f'),
array('id' => 70, 'value' => 'g')
);
Je définis une constante qui me servira à faire les calculs nécessaires pour construire un tableau à 3 colonnes.
DEFINE('NB_COLS', 3);
Ensuite, c'est là que la magie s'opère. L'idée est de créer une matrice où chaque indice de l'array principal représentera une rangée (TR) du tableau. À l'intérieur de chaque rangée sera créé un array qui représente les colonnes (TD) et son contenu. Pour avoir une matrice complète, il sera peut-être nécessaire d'ajouter des cellules vides au tableau.
# 7 éléments au total
$nbElems = count($data);

# créer des regroupements de 3 éléments
$rows = array_chunk($data, NB_COLS);

# $rows contient 3 rangées
# (deux pleines et une avec un seul élément)
$nbRows = count($rows);

# 3 rangées de 3 colonnes = 9 cellules
$totalTableCells = NB_COLS * $nbRows;

# combien de cellules vides doit-on créer ?
$nbEmptyCells = $totalTableCells - $nbElems;

# ajouter les cellules vides au bon endroit
for($i=0 ; $i < NB_COLS ; $i++){
# dernière colonne
if( !isset($rows[$nbRows-1][$i]) ){
$rows[$nbRows-1][$i] = array();
}
}
Pour bien comprendre ce qui se passe, je vous suggère de faire un print_r($rows) après l'appel de array_chunk(), et avant/après la boucle for. Vous aurez une meilleure idée des changements qui se sont opérés pour construire la bonne structure.

Enfin, deux boucles imbriquées feront générer le tableau HTML. Remarquez à quel point le code source est clair.
<?php if( count($rows) > 0 ){ ?>
<table>
<?php foreach($rows as $tr){ ?>
<tr>
<?php foreach($tr as $td){ ?>
<td>
<?php if( !empty($td) ){ ?>
<?php echo $td['id']; ?>
<?php } ?>
</td>
<?php } ?>
</tr>
<?php } ?>
</table>
<?php } ?>
Vous pouvez reprendre cet exemple dans d'autres langages, le principe demeure le même. Maintenant, je vous lance un petit défi : tentez de trouver une alternative à la boucle for qui ajoute les cellules vides dans la dernière rangée du tableau.


Tags: PHP, Programmation

4 réponses à "Façon élégante de créer des tables dynamiques"

  1. Anonyme a dit...
    3 novembre 2009 à 04 h 54

    Le code reste quand même pas mal dégueulasse.
    L'utilisation de templates est quand même plus propre.

    Infinite Loop a dit...
    3 novembre 2009 à 06 h 36

    Tu veux dire avec Smarty par exemple ? Oui, ça peut être une option intéressante mais ça implique aussi que le programmeur débutant doit apprendre le fonctionnement d'un engin de template en plus de ne pas se perdre dans sa logique PHP. Ça peut avoir l'air de rien mais pour quelqu'un de moins expérimenté ou un intégrateur, tu lui en demandes beaucoup. Pour pouvoir comprendre les avantages d'une meilleure méthode à mettre en place, le programmeur évolue généralement dans ce sens :

    1. code spaghetti avec bris de séquence

    2. construction d'une représentation interne qui facilite l'affichage

    3. utilisation d'abstraction lorsque nécessaire (ici les templates)

    Smarty toucherait seulement la troisième étape pour remplacer l'affichage du code HTML (il faudra quand même construire une structure interne appropriée si on ne veut pas oublier les TD vides à la fin de la table). De plus, il ne réduirait en rien la quantité du code et n'améliorerait pas nécessairement sa lisibilité puisqu'on y ajouterait une couche d'abstraction supplémentaire. Si vous comptez utiliser les templates, vous pouvez voir comment convertir l'affichage HTML avec Smarty (j'ai publié un exemple avec une table qui fait sensiblement la même chose). Il ne faut pas oublier que PHP est lui-même un engin de template et qu'il est bon de juger si on en a besoin ou non d'un deuxième.

    Anonyme a dit...
    8 novembre 2009 à 03 h 50

    Le fait est que l'un des buts du programmeur doit être de découpler du mieux possible le fond de la forme pour pouvoir traiter/modifier indépendamment l'une de l'autre si nécessaire.

    Pour preuve, les taglibs et les expressions languages ont été inventés pour réduire l'insertion de code java pur dans les pages jsp (tout comme on injecte du code pur dans des pages php). Après, je présume qu'il existe des moteurs plus simples que Smarty.

    Il est vrai, je l'admets, qu'il y a plus de code au final. Cependant, c'est le prix à payer pour un minimum de modularité, un peu comme utiliser un framework de développement structuré (ActionScriptFoundry, par exemple).

    Certes l'apprentissage demande un investissement de départ (on peut estimer que ça fait partie du métier, après tout) mais le gain final est significatif.
    Bien entendu, ce gain ne va se ressentir que sur des projets de taille certaine (comme, par exemple, pour les pratiques CMMi).
    De plus, si l'écriture s'avère plus complexe au départ, elle simplifie l'évolution future du code (exemple tout bête : ajouter le support du th dans ta création de table).

    Ensuite, en découplant fond et forme de cette façon, il devient plus facile de séparer les tâches. Par exemple, j'ai vu des entreprises dans lesquels les graphistes écrivaient les templates (langage plus simple, manipulation de la forme, etc.) et les programmeurs plus expérimentés écrivaient le code qui y était associé.

    Enfin, PHP est une sorte de moteur de template tel que cela était pensé dans les années 90. Aujourd'hui, avec le recul, on sait qu'il est préférable, sur le long terme, de les intégrer au sein de modèles connus et éprouvés comme le Model-View-Controler ou le Presentation-Abstraction-Control (cf. les évolutions de JSP et d'ASP).

    Toutefois, il est certain qu'il faut doser en fonction des projets et de leurs contraintes (temps alloué, taille, compétences et moyens disponibles, choix éventuels effectués en amont, etc.) mais sans oublier, dès que cela est possible, de penser en terme d'évolution.

    Désolé pour ce long commentaire :S

    Infinite Loop a dit...
    8 novembre 2009 à 08 h 33

    Ton commentaire est long mais très pertinent. Je suis certain qu'il aidera les autres à prendre la meilleure décision.

    Au fond, comme le texte s'adresse surtout aux débutants pour les aider à améliorer la logique d'un code spaghetti, j'aurais dû illustrer l'exemple avec le code avant/après.

    Ton dernier paragraphe résume bien l'idée. Parfois, nous avons des projets "jetables", réalisables en quelques dizaines d'heures et qui sont d'une durée de vie limitée. Dans ce cas, on fait volontairement le choix de garder le code le plus élémentaire possible.

    Lorsqu'un projet est de grande envergure, il est judicieux d'accorder plus de temps à la structure et c'est là qu'on doit se doter des meilleures pratiques et outils de programmation.


Publier un commentaire

Message plus récent Messages plus anciens Accueil
S'abonner à : Publier des commentaires (Atom)
    Suivre @code18 sur Twitter

    Catégories

    • Apache (21)
    • Citations (167)
    • Club Vidéo (24)
    • Coffre à outils (56)
    • CSS (8)
    • Curiosités (117)
    • Design Pattern (2)
    • Drupal (8)
    • Easter Eggs (22)
    • Extensions Firefox (20)
    • GIMP (7)
    • Histoire (21)
    • HTML (32)
    • Humour (57)
    • Intégration (34)
    • iPod (12)
    • JavaScript (110)
    • Jeu de combat (6)
    • Le coin du geek (128)
    • Liens (12)
    • Linux (56)
    • Livres (78)
    • Lois et principes (46)
    • Marché des saveurs (26)
    • Mathématique (18)
    • Mobile (5)
    • Montréal (32)
    • Musique (112)
    • Pancartes et écriteaux (16)
    • Perl (8)
    • Pérou (1)
    • PHP (130)
    • PostgreSQL (44)
    • Programmation (105)
    • Saviez-vous que (55)
    • Sécurité (22)
    • SEO (5)
    • SQL Server (22)
    • Vieilles publicités (6)
    • Virtualisation (8)
    • Voyages (1)
    • Zend Framework (26)

    Divers

    Archives

    • ►  2015 (6)
      • ►  août 2015 (1)
      • ►  juillet 2015 (1)
      • ►  février 2015 (3)
      • ►  janvier 2015 (1)
    • ►  2014 (8)
      • ►  décembre 2014 (1)
      • ►  novembre 2014 (1)
      • ►  octobre 2014 (1)
      • ►  août 2014 (2)
      • ►  juillet 2014 (2)
      • ►  janvier 2014 (1)
    • ►  2013 (53)
      • ►  décembre 2013 (2)
      • ►  novembre 2013 (1)
      • ►  octobre 2013 (3)
      • ►  septembre 2013 (2)
      • ►  août 2013 (5)
      • ►  juillet 2013 (3)
      • ►  juin 2013 (5)
      • ►  mai 2013 (3)
      • ►  avril 2013 (7)
      • ►  mars 2013 (7)
      • ►  février 2013 (11)
      • ►  janvier 2013 (4)
    • ►  2012 (105)
      • ►  décembre 2012 (8)
      • ►  novembre 2012 (5)
      • ►  octobre 2012 (4)
      • ►  septembre 2012 (1)
      • ►  août 2012 (8)
      • ►  juillet 2012 (7)
      • ►  juin 2012 (7)
      • ►  mai 2012 (10)
      • ►  avril 2012 (13)
      • ►  mars 2012 (15)
      • ►  février 2012 (15)
      • ►  janvier 2012 (12)
    • ►  2011 (146)
      • ►  décembre 2011 (14)
      • ►  novembre 2011 (11)
      • ►  octobre 2011 (12)
      • ►  septembre 2011 (13)
      • ►  août 2011 (15)
      • ►  juillet 2011 (17)
      • ►  juin 2011 (18)
      • ►  mai 2011 (15)
      • ►  avril 2011 (9)
      • ►  mars 2011 (7)
      • ►  février 2011 (3)
      • ►  janvier 2011 (12)
    • ►  2010 (398)
      • ►  décembre 2010 (29)
      • ►  novembre 2010 (28)
      • ►  octobre 2010 (32)
      • ►  septembre 2010 (34)
      • ►  août 2010 (22)
      • ►  juillet 2010 (35)
      • ►  juin 2010 (42)
      • ►  mai 2010 (36)
      • ►  avril 2010 (37)
      • ►  mars 2010 (34)
      • ►  février 2010 (32)
      • ►  janvier 2010 (37)
    • ▼  2009 (430)
      • ►  décembre 2009 (32)
      • ▼  novembre 2009 (34)
        • Utilise les regex avant que je vire fou !
        • In Search of Stupidity
        • Citation no. 58 sur la confiance
        • Propriétaire d'une table PostgreSQL
        • Configurer le FTP dans Netbeans
        • Mais où s'en va la vie privée ?
        • Livres informatiques douteux
        • NoteCard, pour apprendre ses notes de musique
        • Citation no. 57 sur les ordinateurs
        • Mise à jour Ubuntu 9.10 sur mon netbook
        • Microsoft installera Chrome OS sur les ordinateurs ?
        • Notes sur le Pecha Kucha Montréal # 14
        • Cancer de la jambe droite ?
        • Que veut-dire le nom Corel ?
        • Skin iPod pour Songbird
        • Classement des binaires sous Linux
        • Citation no. 56 sur la curiosité
        • Faire apparaître Wanda The Fish dans Linux
        • CodeRun - Online IDE
        • Champ autocomplete avec YUI
        • Invitation gratuite pour Google Wave
        • Raccourci dans Firefox pour compléter le domaine
        • Ripoff du thème musical des Simpsons
        • Liste numérique HTML à ordre inversé
        • Copie du ShamWow au Dollorama
        • Citation no. 55 sur les problèmes
        • 10 petits secrets que vous devez savoir sur le tra...
        • Performance vs accès disque
        • Redimensionner des images en batch
        • SQL Injection sur DirectCanada.com ?
        • Carte postale Google AdSense
        • Façon élégante de créer des tables dynamiques
        • Changer la langue de l'interface de GIMP
        • Citation no. 54 sur les ennuis
      • ►  octobre 2009 (33)
      • ►  septembre 2009 (37)
      • ►  août 2009 (37)
      • ►  juillet 2009 (39)
      • ►  juin 2009 (38)
      • ►  mai 2009 (37)
      • ►  avril 2009 (35)
      • ►  mars 2009 (37)
      • ►  février 2009 (32)
      • ►  janvier 2009 (39)
    • ►  2008 (84)
      • ►  décembre 2008 (34)
      • ►  novembre 2008 (39)
      • ►  octobre 2008 (11)

    Abonnés

Copyright © All Rights Reserved. Code 18 | Converted into Blogger Templates by Theme Craft