![]() |
|
Snippets |
|
Here we go !
The sort in admin generator is for a single field only, but in some complex list, it can be usefull to sort by multiple criterias. This is the main goal of this snippet. Those functions therefore override the ones of your auto-generated class. (1) And to display what are the ongoing sort criterias, you have to modify your '_list_th_tabular.php' file.
// /** * Add a sort criteria */ protected function processSort () { $sort = $this->getRequestParameter('sort'); $type = $this->getRequestParameter('type'); // Register sort if ($sort) { $this->getUser()->setAttribute($sort, $type, 'sf_admin/produits/sort'); } } /** * Add the sort criterias to the query */ protected function addSortCriteria(&$c) { $multisort = $this->getUser()->getAttributeHolder()->getAll('sf_admin/produits/sort'); if ($multisort) { foreach($multisort as $sort_column => $sort_type) { $sort_column = Propel::getDB($c->getDbName())->quoteIdentifier($sort_column); if ($sort_type == 'asc') { $c->addAscendingOrderByColumn($sort_column); } elseif ($sort_type == 'desc') { $c->addDescendingOrderByColumn($sort_column); } } } else { // Default sort $sort_column = Propel::getDB($c->getDbName())->quoteIdentifier('libelle'); $c->addAscendingOrderByColumn($sort_column); } } /** * Specific function for multi-sort */ protected function processFilters () { if ($this->getRequest()->hasParameter('filter')) { $filters = $this->getRequestParameter('filters'); // Multi-sort initialisation if (!is_array($filters)) { $this->getUser()->getAttributeHolder()->removeNamespace('sf_admin/produits/sort'); } $this->getUser()->getAttributeHolder()->removeNamespace('sf_admin/produits/filters'); $this->getUser()->getAttributeHolder()->add($filters, 'sf_admin/produits/filters'); } }
(for each sortable field)
<?php $multisort = $sf_user->getAttributeHolder()->getAll('sf_admin/produits/sort'); ?> <th id="sf_admin_list_th_libelle"> <?php if (isset($multisort['libelle'])) { echo link_to('Libellé', 'Produits/list?sort=libelle&type='. ($multisort['libelle'] == 'asc' ? 'desc' : 'asc')); echo ' ('. $multisort['libelle'] . ')'; } else { echo link_to('Libellé', 'Produits/list?sort=libelle&type=asc'); } ?> </th>
'Produits' is the module name, 'libelle' is the field to sort.
The 'reset button' of filters also initialize the multi-sort. The sort is made from the first field clicked to the last. That means, if you want a different primary sort you will have to use the reset filter button before.
PS: Obviously, this modification can be easly integrated in your backoffice theme, note that the default sort criteria set in the 'generator.yml' is used in the addSortCriteria function (from line // default sort)
COil :)
Comments on this snippet
_list_th_tabular.php is in cache, every time when propel-init-admin, it is rebuilt. How to deal with this?
William you are not supposed to use the propel-init-admin several times, only once is enough. After you need to parameter the config/generator.yml file for your module. This is a normal behaviour, the cached files are always regenerated, you must copy the wanted file from the cache to your module (keeping the file struture, in /template in this case) in order to be able to customize the file.
Thanks Loïc for your example
I think I noticed a type at addSortCriteria (the '&' should be removed before the argument).
Also in the table-header I added two variables, to make reproduction easier:
Maybe I later on even change the generator, but I need some more time for that, which I don't have right now.
Another addition to your post: I've added the option to disable the sorting on a column by clicking on the header for a third time.
this way you get asc->desc->none->asc->desc->none->etc.... Which I think is nicer than only being able to use the reset button from the filter. One thing I haven't figured out though is, if it would be nicer to keep the disabled sorting of the column in memory or not. That means first you have selected to sort on ColumnA (asc) then on columnB (asc) then on ColumnA again (desc). If you would now again press ColumnA (none) ColumnB will now be the first column to sort on if you again press ColumnA.
the code for the table-header is now:
the code for addSortCriteria is now:
An even nicer solution can be to keep the switching between asc->desc->asc->desc... and add an option/link in the header to remove the sorting of this column (by adding an X or something)
like E.G.
and maybe even the 'X' can get replaced by his location in the multisort-array...
Nice to see this works again ;)
I've created an even further improved version which you can find in tract at: http://trac.symfony-project.com/trac/ticket/2092
You now only have to define the option multisort: true in your generator.yml file under list.
Good job :)