Symfony: Domptez les filtres de l’admin generator
Un détail qui m’a toujours titillé dans le fabuleux admin generator de symfony, c’est le bloc de filtre. Le concept est bien sûr génial. Sans rien faire, vous avez déjà la possibilité de filtrer vos résultats, un gain de temps énorme, surtout quand on a un client qui sait ce qu’il veut. Mais voilà, même si depuis la 1.2, le layout de l’admin generator par défaut a subit un lifting qui le rend beau de série:
![]()
On rencontre très vite, dans le cas d’un tableau avec beaucoup de colonnes, le fameux « bug » css sur un écran plus petit que mon 20″ (oui parce que chez moi, c’est toujours très beau, chez mes chefs de projets et leur portable, beaucoup moins :D):
![]()
Alors bien sûr, la solution radicale, c’est de réduire le nombre de colonnes, mais souvent le client, il les veut ses colonnes! La 2e solution est de supprimer ce bloc de filtre. On fait ça très simplement dans le generator.yml:
filter: class: false
Cependant, il arrive quand même que le filtrage soit nécessaire mais bien souvent, seulement 2 ou 3 valeurs. J’ai donc décidé de prendre le taureau par les cornes et faire la modification dont je rêve depuis longtemps, passer ce bloc de filtre, au dessus du tableau! Pour ce faire, j’ai modifié 2 fichiers. Tout d’abord, le fichier _filters.php qu’il faudra rajouter dans le dossier templates de vos modules visés:
<div class="sf_admin_filter"> <div class="content_filter"> <?php if ($form->hasGlobalErrors()): ?> <?php echo $form->renderGlobalErrors() ?> <?php endif; ?> <form action="<?php echo url_for('produits_collection', array('action' => 'filter')) ?>" method="post"> <?php foreach ($configuration->getFormFilterFields($form) as $name => $field): ?> <div class="bloc_filter"> <?php if ((isset($form[$name]) && $form[$name]->isHidden()) || (!isset($form[$name]) && $field->isReal())) continue ?> <?php include_partial('produits/filters_field', array( 'name' => $name, 'attributes' => $field->getConfig('attributes', array()), 'label' => $field->getConfig('label'), 'help' => $field->getConfig('help'), 'form' => $form, 'field' => $field, 'class' => 'sf_admin_form_row sf_admin_'.strtolower($field->getType()).' sf_admin_filter_field_'.$name, )) ?> </div> <?php endforeach; ?> <?php echo $form->renderHiddenFields() ?> <?php echo link_to(__('Reset', array(), 'sf_admin'), 'produits_collection', array('action' => 'filter'), array('query_string' => '_reset', 'method' => 'post')) ?> <input type="submit" value="<?php echo __('Filter', array(), 'sf_admin') ?>" /> </form> </div> </div>
Au final, j’ai simplement supprimé le tableau, par défaut et mis chaque widget dans un div. On obtient donc quelque chose qui change pas vraiment la donne pour l’instant:
![]()
Mais en lui appliquant un peu de css:
div#sf_admin_bar { float:none; margin: 0; } #sf_admin_bar .sf_admin_filter form div.bloc_filter { display:inline; padding:0 20px 0 0; } div#sf_admin_container #sf_admin_bar label { display:inline; float:none; padding:0; }
On commence à approcher de ce que l’on souhaite:
![]()
Maintenant, on habille un peu la chose, histoire de gagner en clarté:
#sf_admin_bar .sf_admin_filter { background-color:#FFF; margin:12px 0; } #sf_admin_bar .sf_admin_filter .content_filter { border:1px solid #DDDDDD; padding:5px; }
Un dernier détail, le filtre « référence » avec sa colonne « is_empty » casse un peu notre rendu. Personnellement, je ne me sers pas de cette checkbox, on va donc redéfinir notre filtre pour la supprimer dans lib/filters/MonModuleFilters.class.php:
public function configure() { $this->widgetSchema['reference'] = new sfWidgetFormFilterInput(array( 'template' => '%input%' )); }
Et voilà, une jolie barre de recherche beaucoup plus du goût des clients en général :)
![]()
Alors bien sûr, cette solution ne fonctionne qu’avec un nombre limité de filtre, sinon on aurait un rendu un peu moins visuel, mais je pense que ça reste toujours mieux que 2 blocs qui se chevauchent.
Tags: admin, filter, howto, Symfony, widget
8 Réponses
Laisser un message

Pour enlever la checkbox on peut faire ça aussi :
public function configure() { $this->widgetSchema['reference'] = new sfWidgetFormFilterInput(array( 'with_empty' => false )); }Bien vu, et c’est plus dans la logique je pense. Merci : )
N’ayant pas (encore :( )de blog, je me permet de diffuser sur le tien, en plus de la proprieté ‘with_empty’, j’ai cherché un peu plus en profondeur dans le CSS et après moult efforts :P, j’ai enfin réussi à faire ce que je voulais.
En gros, placé le bloc de filtre comme tu le fais (faut avouer que c’est beaucoup plus pratique), SANS toucher au template « _filter.php ».
Voici le code CSS nécessaire, je l’ai appliqué sur 2 pages d’un backend possédant des filtres et ça à pas posé de soucis.
#sf_admin_container #sf_admin_bar { float:none; margin: 0px; } #sf_admin_container #sf_admin_bar .sf_admin_filter table tr { clear: none; border: 1px solid #DDDDDD; padding: 0px; } #sf_admin_container #sf_admin_bar .sf_admin_filter table tr td { height: 50px; vertical-align: middle; border: none; } #sf_admin_container #sf_admin_bar .sf_admin_filter table tbody { clear: none; float: left; } #sf_admin_container #sf_admin_bar .sf_admin_filter table tbody tr { float: left; border-right: none; } #sf_admin_container #sf_admin_bar .sf_admin_filter table tfoot { clear: none; float: right; } #sf_admin_container #sf_admin_bar .sf_admin_filter table tfoot tr { float: right; }Testé pour les input et les selectbox, j’ai pas encore eu l’occasion de le faire pour les checkbox et radiobox par contre.
Seule les multi-selectbox devraient poser problème, la solution serait surement d’augmenter le « height » du td. On peut le mettre à 40px si on enlève les is_empty, ça réduit un peu la ligne, sinon 50px avec ou sans c’est plus propre je trouve.
Rendu chez moi :
http://img23.imageshack.us/img23/5087/cssfitre.png
Voilà :)
Nice!
Aucun souci pour contribuer via commentaire, et d’ailleurs si t’es intéressé pour y contribuer directement, on peut toujours en discuter : )
Cher Tim
Merci pour ton billet il m’est très utile pour personnaliser mon application.
Cependant, j’ai trouvé le _filters.php de base dans monprojet/cache/monprojet/dev/modules/autoMonmodule/templates/ car le tiens ne marche que pour ton module (bon je sais c’est juste deux trois mots à remplacer ^^)
J’ai trouvé ça dans le cache de google : http://209.85.229.132/search?q=cache:IFQpjw5cMLUJ:trac.symfony-project.org/changeset/1485%3Fformat%3Dzip%26new%3D1485+symfony+customize+_filters.php&cd=1&hl=fr&ct=clnk&gl=fr
Cordialement,
Exact, je n’ai pas précisé, mais c’était le truc à faire, le récupérer dans le cache.
J’essaierai d’éditer quand j’aurais le temps.
Merci bien ;)
Pour enlever la checkbox on peut faire ça également :
public function configure()
{
$this->widgetSchema['reference']->setOption(‘with_empty’, false);
}
Le code de sebastien est nickel (pas besoin de toucher au php, donc plus portable) mais il ne fonctionne malheureusement pas avec IE (clear: none). Les infos ne s’affichent pas en ligne.
Quelqu’un sait comment corriger ça ?