blog actif depuis 1328 jours.

retours d'expériences, codes sources, réflexions, humeurs... d'un webmaster

 

Dim.

27

Sept.

 

Voici une classe pour l'affichage de listes à partir de résultats de requêtes sur une base de données.
Elle permet notamment :
- le tri par colonne
- la pagination
Le contenu des cellules est entièrement paramétrable :  vous pouvez afficher plusieurs champs dans une même cellule et vous pouvez utiliser des fonctions complexes pour générer le contenu d'une cellule.
Enfin, la liste est mise en forme entièrement par CSS.

Voici donc un exemple d'utilisation de la classe : l'affichage de la liste des départements de France à partir d'infos contenus dans une table 'departements'. La requête exécutée est la suivante :
SELECT SQL_CALC_FOUND_ROWS code_departement, nom_departement,
nom_chef_lieu, nombre_arrondissements, nombre_communes FROM departements

Instantiation et paramètres de la classe :
$obj_liste = new classe_liste();
$obj_liste->setPas(10);                  // nombre de lignes affichées par page
$obj_liste->setNbPagesNavig(5);  // nombre de pages affichées dans la pagination

Passage des données à la classe

Le premier traitement consiste à transformer le résultat de la requête en un tableau exploitable par la classe, grâce à la fonction PHP mysql_fetch_array().
Le tableau ainsi créé est passé à la classe :
$obj_liste->setDatas($datas);

Ajout des colonnes

On ajoute les colonnes une à une à l'aide de la méthode addColonne, qui reçoit comme arguments : le nom du champ, le libellé de l'entête de colonne (<th>) et un troisieme argument optionnel qui est le contenu des cellules (<td>) de chaque ligne de résultat pour cette colonne :
- contenu formaté
- si ce dernier n'est pas précisé, la cellule contiendra le résultat de la requête
- s'il est vide, la cellule sera vide

ainsi pour afficher simplement les 4 colonnes nom_departement, nom_chef_lieu, nombre_arrondissements et nombre_communes :
$obj_liste->addColonne("nom_departement","D&eacute;partement");
$obj_liste->addColonne("nom_chef_lieu","Chef-lieu");
$obj_liste->addColonne("nombre_arrondissements","Nombre d'arrond.");
$obj_liste->addColonne("nombre_communes","Nombre de communes");



Maintenant, on va ajouter le numéro de département et un lien sur le nom du département vers la page wikipedia correspondante sur la colonne nom_departement :
$obj_liste->addColonne("nom_departement","D&eacute;partement","[code_departement] - <a href="http://fr.wikipedia.org/wiki/[nom_departement]_(d&eacute;partement)" target="_blank">[nom_departement]</a>");

Le troisième argument contient le format de la chaine à retourner. Les valeurs dynamiques remplaceront les champs placés entre crochets. ainsi [nom_departement] sera remplacé à chaque ligne par le résultat de la requête correspondant.



Ajout de contenu

Vous pouvez ajouter du contenu à votre colonne à l'aide de la methode $obj_liste->addContenu();

Traitement du contenu à l'aide de fonctions complexes

Pour ajouter du contenu, utilisez la méthode addContenuFonction(), qui reçoit 2 arguments : le nom de la colonne et la fonction à passer, avec ses arguments.

Par exemple, j'ajoute une colonne blason avec l'image correspondante (le nom de l'image étant de la forme "nom_du_departement.png"). Cette colonne ne doit pas être triée. Un traitement est nécessaire pour récupérer le nom de l'image à partie du nom du département (suppression des accents, remplacement des "-", " " et ' par "_", ...).

Je crée donc un fonction que j'appelle getBlason(nom_departement) qui
s'occupe de ce traitement. Dans la classe liste, cela se traduit par :
$obj_liste->addColonne("blason","Blason","");
$obj_liste->addContenuFonction("blason","getBlason([nom_departement]);");
$obj_liste->noTri();



Mise en forme

Le tableau est entièrement mis en forme par du CSS.
Les différents éléments de la liste sont accessibles par leur id, construit à partir du nom de colonne.
Ainsi, l'entête de la colonne 'nom_département' est nommé th_nom_departement.

Tri et pagination

L'affichage de la navigation se fait par la méthode suivante :
$obj_liste->afficheNavig();

Le tri se fait en cliquant sur les entêtes de colonnes. Les paramètres de tri sont mis en session, dans le tableau $_SESSION['classe liste'](pareil pour les éléments de pagination) :
[classe_liste] => Array
(
[pas] => 10
[min] => 0
[ord] => nom_departement
[sens] => Array
(
[nom_departement] => ASC
)
[page] => 1
)

Ces valeurs sont donc à prendre en compte dans la construction de la requête SQL.

Pour télécharger la classe et le code source de l'exemple, rendez vous sur l'espace téléchargement

 

Commentaires

Ce code fonctionne à merveille, Merci !
Une idée pour paramétrer l'affichage par rapport au tableau : au dessus , en dessous ou les deux ?

29/09/2009

C'est fait :
- $obj_liste->afficheNavig() positionne la navigation en haut et en bas
- $obj_liste->afficheNavig("bas") positionne la navigation en bas
- $obj_liste->afficheNavig("haut") positionne la navigation en haut

29/09/2009

Merci beaucoup, très bonne utilisation de la fonction SQL_CALC_FOUND_ROWS, le côté serveur vous dit merci infiniement.

01/10/2009

Tout simplement MAGNIFIQUE !!!
Un grand MERCI pour ce partage, je retourne étudier ton code de suite ;)

07/10/2009

Salut,
Attention dans l'utilisation deSQL_CALC_FOUND_ROWS apparemment tout le monde n'est pas d'accord sur les gains de performance.
lire http://www.mysqlperformanceblog.com/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/

Une fois de plus tout dépend du contexte.

25/11/2009

bien vu mrbinr, très intéressant cet article.
va falloir que je teste ça de plus près, avec/sans index, en utilisant les procédures stockées...

25/11/2009

Bonjour , 1* je vous remercie infiniment pour le code ;c'est magnifique .
2* j'ai un souci les numéro de page ne s'affiche pas mais lorsque je tape dans url page=1 ou 2 il par vers 'autre page ??

20/01/2010

Bonjour aaa.
l'affichage des liens de navigation se fait avec la méthode $obj_liste->afficheNavig();

21/01/2010

Bonjour,
Tout d'abord je tenais à te remercier pour ton travail de très grande qualité. Tu m'as fait gagné des heures et des heures de travail et je t'en remercie.
Juste un petit bémol, car ta classe n'est pas totalement compatible avec tous les SGBD qui par exemple n'accepte pas la fonction LIMIT.
Bonne journée.
Cordialement,
robertjul

27/01/2010

Bonjour robertjul
tu as raison, la fonction LIMIT n'est pas une fonction SQL ANSI, elle est propre à MySQL.
Cependant la classe liste est totalement indépendante d'un SGDB. Elle ne fait qu'afficher une liste d'éléments. Dans mon exemple, je récupère les éléments (départements) stockés dans une base MySQL, mais cette sélection se fait en amont. On aurait tout aussi bien pu passer un tableau PHP.

27/01/2010

Bonjour,
Encore merci pour ta réponse.
J'ai encore deux questions si possible :
-es-il possible de mettre le contenu d'une colonne si une condition est vrai ?
-Comment ferais-tu pour faire fonctionner la pagination sans la fonction LIMIT.
Bonne fin de journée.
Cordialement,
robertjul

01/02/2010

1 - oui, en passant par la méthode addContenuFonction : tu crées une fonction qui retourne le champ si ta condition est vérifiée dans cette fonction, sinon un espace  
2 - ça dépend de ton SGDB, faut voir dans les fonctions propres au SGDB utilisé

02/02/2010

Bonjour,
Encore merci pour ta réponse rapide, précise et clair. J'en suis ravi!
1-Merci beaucoup pour l'indication, j'ai en effet oublié de regarder de se côté. Néanmoins, j'ai résolu mon souci se qui m'a permis de beaucoup mieux comprendre ton code.
2-Le SGBD que j'utilise est SQLserveur (parce que j'ai pas le choix^^)
Cordialement,
robertjul

02/02/2010

Bonjour,
Comment faut-il que je paramètre pour avoir:
- par page, 20 lignes
- la barre de navigation tient compte de tous les enregistrements
J'ai essayé mais je n'arrive pas car le processus ne prend pas tous les enregistrements.

Merci pour la réponse

10/03/2010

Bonjour Carquois
pour avoir 20 lignes par page, on utilise : $obj_liste->setPas(20);
qui va inialiser les variables de session 'min' et 'pas' que l'on utilisera dans le LIMIT de la requête :
" LIMIT ".$_SESSION['classe_liste']['min'].",".$_SESSION['classe_liste']['pas'];

10/03/2010

salut et merci pour ton code. juste une petite précision, est-ce que systèmatiquement le nom de la première colonne ne permet pas de faire un tri, etc, sur elle (comme le fait blason). Deuxièmement, j'ai un décalage entre les TH et les colonnes est-ce normal? merci

17/03/2010

Bonjour Wad
On peut bien sur faire un tri sur la première colonne. Dans l'exemple le tri est désactivé.
La taille des th et td est réglable dans le CSS.

17/03/2010

Merci. Excellente la classe, c'est pile ce qui me fallait, le seule petit problème que j'ai c'est au niveau validation W3C mais je vais m'en sortir. Sinon tu souhaites que je laisse ton nom dans le code?
PS: il fera parti d'un projet dans un cadre scolaire donc pas de "diffusion" sur internet...
Cordialement et encore merci.

17/03/2010

bonjour wad
effectivement, un peu de pub, ça serait sympa.
merci à toi

17/03/2010

Bonjour.
Je ne sais pas si tu l'as remarqué, mais étant donné que des variables de $_SESSION sont utilisées pour stocker les informations relatives au tri et à la pagination, l'affichage de plusieurs liste sur la même page cause des "bug" (du genre quand on classe un tableau, ils sont tous classés, ou quand on passe sur une page suivante sur un tableau, ça les modifie tous et si certain n'ont pas d'info ça renvoie pas de données)...

20/03/2010

Bonjour wad
Je sais, c'est un problème qui est corrigé dans la prochaine version, qui permettra d'afficher plusieurs listes.
J'essaie de mettre cette version en ligne rapidement, elle intègrera entre autre, la possibilité d'exporter les listes en CSV, XLS...
en intégrant phpExcel.
Et désolé pour le temps de réponse, la semaine a été chargée.

28/03/2010

Bonjour Romualb,
tout d'abord merci pour ce code, c'est vraiment très bon, j'ai simplement un problème:
lorsque j'essaye de faire des requètes sur plusieurs tables cela ne fonctionne plus,
je crois que c'est du aux points, exemple:
SELECT sortie.reference , reassort.date_de_livraison
FROM sortie, reassort

dans ce cas je crois que le point est mal interprété par ton code et fait partie des signes qui servent à différencier les champs de ma table

mes connaissances en php sont trop limitées pour comprendre l'intégralité de ton code

est ce que tu pourrais m'éclairer sur ce sujet, merci de ton aide!

02/04/2010

Bonjour Léo
les résultats retournés par mysql ne contiennent pas les noms des tables, il faut juste indiquer les noms des champs (reference et date_de_livraison). Si tu as des champs de même nom dans les 2 tables, il faut les renommer (SELECT table.champ AS champ1, table2.champ AS champ2 FROM table, table2).

02/04/2010

Merci génial, pour info j'ai modifié ton code en faisant de ta fonction une fonction à plusieurs variables:

tableauRequete ( $table, $champsrequete, $alias, $libeles, $where )
et en sortant le include class... de la fonction

je te le conseille c'est plus rapide à réutiliser, et j'attends avec impatience la version avec plusieurs affichages,
je l'ai fait en faisant (entre autres manipulations) supprimer les variables de session entre les tableaux, du coup seul le premier peut être trié...
Bon courage thx

06/04/2010

Bonjour,
Merci beaucoup pour cette classe, elle fonctionne niquel.
J'ai juste un petit problème j'aimerai mettre une checkbox dans une colonne comme si dessous



Ce qui me retourne une erreur a cause de name="tableau[]"

Aurais-tu une idée de la solution à mon problème ?

Encore merci pour cette classe et bonne continuation.

20/07/2010

@Lowlo : effectivement, c'est pas prévu mais ça peut être intéressant... je regarde ça et je te tiens au courant par mail

21/07/2010

J'ai trouvé la solution pour ce problème.

Il faut juste mettre un espace entre les deux [] et ca passe.

Encore merci pour ce joli code.

21/07/2010

merci à toi pour l'info

21/07/2010

très heureux de voir une si belle classe continué à évoluer! Merci beaucoup à toi

03/08/2010

Très bien conçu pour moi un débutant. Ton script écrit toutes les données de ma table bien,c'est le but.
Moi j'ai une liste de joueurs de rugby qui ont marqué sur plusieurs matchs. Je ne voudrais faire apparaître qu'une fois le nom d'un joueur mais avec le total des points qu'il a marqué.

30/10/2010

@jojo: bonjour, peux tu être plus précis ? ton pb se trouve au niveau de la requête ou de l'affichage du résultat de ta requête ?

31/10/2010

Cette classe est super!
Mais comment adapter ce code pour une connexion sur une table Access en ODBC?
Je crois que odbc_fetch_array() ne renvoie pas la même chose que mysql_fetch_array.

01/02/2011

@Lanannie : merci, mais la classe ne gère pas l'exploitation des bases de données. Elle ne fait qu'afficher un résultat à partir d'un tableau de données. Donc la connexion en ODBC se fait en amont.

02/02/2011

Bonjour,

Merci pour cette classe bien utile.
Je souhaiterai créer une colonne "produit" avec un lien. La même chose que les départements mais sans l'ouverture d'une nouvelle fenêtre. Après plusieurs tentatives, je n'y arrive pas.

Merci de ton aide

05/06/2011

@sylvain:voici par exemple comment faire un lien vers un produit en passant l'id du produit :

$obj_liste->addColonne("produit","Produit","<a href=\"mapage.php?id=[champ_id_produit]\">");

avec champ_id_produit le nom du champ id récupéré dans le résultat de votre requête SQL

05/06/2011

Bonjour,

Merci pour ce type de code tres bien pense.
J'ai un problème lorsuqe je fourni dans les données une date, j'ai un retour erreur sur le navigateur:
Notice: Undefined index: date in E:wampwwwCRM_Templatelibsclasse_listes.php on line 333

C'est la ligne correspondant à if (strlen($content['format'])>0 && strlen($data[$content['champ']])>0)

Comment contouner cette erreur?

Merci de ton aide

24/11/2011

@Yvo : je pense que tu essaies d'afficher une colonne appelée 'date' (initialisée avec $obj_liste->addColonne("date",...) et qu'il n'y a pas de champ 'date' dans ton tableau passé à la liste via $obj_liste->setDatas();

25/11/2011

Bonsoir Romuab
Merci de ton attention.
En fait, j'ai une fonction qui me retourne un tableau multidimensionnels (séparation métier & présentation). Avant d'utiliser ta classe,j'affiche le tableau de la manière suivante (et les 3 colonnes nom, email et date s'affiche correctement):... Merci encore de ton aide

26/11/2011

@yvo : vérifie que tu appelles bien la méthode $obj_liste->addColonne("date_inscription",...) et non $obj_liste->addColonne("date",...)

27/11/2011

Merci bcp de ton aide, c'est effectivement l'erreur (je vais prendres quelques jours de congés;-)
J'espère ensuite que la suite de l'imlémentation de ta classe se passera sans nouvelle erreur de ma part.
Cdt

28/11/2011

Bonjour Romualb,
Encore un peut d'aide svp,
En complément de la question de Sylvain, je souhaite avoir sur chaque ligne un icone "voir la fiche" (à terme, il y en aura d'autre comme éditer la fiche ou supprimer la fiche). Il faut donc afficher un icone et créer un lien avec l'id. A ce jour, je procède de la manière suivante:

28/11/2011

Bonjour Romualb

Désole mais en complément de ma dernière question, meme en utilisant la réponse que tu as fait à Sylvain ne marche pas. Pourtant, j'ai essayé plusieurs syntaxe (j'ai meme affiché l'ID pour vérifier le retour de cette valeur)
// S'affiche bien dans le tableau
$obj_liste->addColonne("id","Identifiant");

// Les 3 cas suivant affiche des cellules vides
// $obj_liste->addColonne("id","lien","");
// $obj_liste->addColonne("id","lien","");
// $obj_liste->addColonne("id","lien","");

$obj_liste->noTri();

Merci encore de ton aide et disponibilité.
J'ai décidé d'utliser ta classe pour notre dev mais je dois impérativement être capable de faire un lien vers une "fiche détail" lorque l'on clique sur la ligne (tant pis si l'on ne peut pas afficher un icone à la place de l'id en toute lettre)

Cdt

29/11/2011

Bonsoir Romualb,

Après plusieurs heures, cela fonctionne enfin avec un lien id sur un icone:
$obj_liste->addColonne("id","id",$code = " ");

Désolé de t'avoir envoyé plusieurs requetes.
Mis à part ce blog, peut on échanger par email? Je vais avoir plusieurs class relativement complexe à développer pour ma société... j'aimerais connaitre ton statut? Peux tu par exemple (ou as tu le temps) développer avec facturation?

Merci encore pour cette superbe classe

A bientôt

29/11/2011

@yvo : content que tu ais trouvé une solution et désolé de répondre un peu tard aux questions. Tu peux me contacter directement sur l'adresse contact du site.

29/11/2011

Bonjour Romualb,
Je termine l'implémentation d'affichage de tableau pour mon application, cela normalement devrait être ma dernière question ;-)
J'ai une colonne « statut utilisateur » qui indique si l'utilisateur est actif ou inactif, c'est un champ BOOLEAN (0 ou 1) récupéré par le SQL. Plutôt que d'afficher 0 ou 1, j'affiche une icone spécifique. J'ai utilisé ta méthode $obj_liste->addContenuFonction qui fonctionne très bien. Seulement, j'ai aussi l'affichage de la valeur du SQL (0 ou 1) avec l'icone dans la cellule (ce qui n'est pas » graphiquement top»).
Je peux créer une nouvelle colonne, mais alors est-il possible de « rendre invisible» la colonne qui contient la donnée brute (le boolean) ?
En complément, tu a annoncé dans ton blog une future version avec la possibilité d'exporter les données. Est-ce que la mise en ligne de cet update est toujours dans le pipe ?
Merci encore de ta disponibilité et aide
Yvo

Si besoin, le code:
// fonction d'affiage du contenu de la colonne statut
function get_icone($m_actif)
{

if ($m_actif == 1) {
$code = "";

}else {
$code = "";
}
return($code);
}

...
...
...

$obj_liste->addColonne("m_actif","Statut");
$obj_liste->addContenuFonction("m_actif","get_icone([m_actif]);");

01/12/2011

@yvo : bonjour,
il faut ajouter un argument à la fonction addColonne :
$obj_liste->addColonne("m_actif","Statut","");
(pour une fois la réponse est rapide... )

Pour l'import, c'est fait. Par contre la version que je propose en téléchargement n'est pas à jour. Je peux t'envoyer la nouvelle si tu veux. Envoie moi un mail directement sur l'adresse contact.

01/12/2011

 

Ajouter un commentaire

nom / pseudo :
e-mail :

(Votre e-mail ne sera ni exploité, ni divulgué.)

site (facultatif)
 
romualb.com est sur Facebook
<Février 2012 
LunMarMerJeuVenSamDim
  01 02 03 04 05
06 07 08 09 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29