lunes, 8 de noviembre de 2010

Sorting Lists in Symfony

On my previous post Using Pagination with Symfony and Doctrine I discussed how to implement pagination based what the admin generator created.

With sorting I did pretty much the same, looked around the cache to see what the generator did.

Creating the sortable_header Partial


Create a file named /myproject/apps/myapplication/templates/_sortable_header.php and copy the following code on it. Then save it.

<?php if ($fieldname == $sort[0]): ?>
<?php echo link_to(__($fieldlabel, array(), 'messages'), $routename,
array('query_string' => 'sort='. $fieldname .'&sort_type=' .
($sort[1] == 'asc' ? 'desc' : 'asc'))) ?>
<?php echo image_tag('/images/' .
$sort[1] . '.png', array('alt' => __($sort[1], array(), 'sf_admin'),
'title' => __($sort[1], array(), 'sf_admin'))) ?>
<?php else: ?>
<?php echo link_to(__($fieldlabel, array(), 'messages'), $routename,
array('query_string' => 'sort='. $fieldname .'&sort_type=asc')) ?>
<?php endif; ?>


This template receives 3 variables:
$fieldname: The name of the field as defined in the Object class.
$fieldlabel: The text you want to display in the header. It implements i18n so if your translate your site it will work.
$routename: Name of the route to generate the link.

You'll need to have the asc.png and desc.png on your /myproject/web/images directory in order to get the arrows.

Editing indexSuccess.php


Open your /myproject/apps/myapplication/modules/mymodule/templates/indexSuccess.php
Your column headers should look something like this:

<thead>
<tr>
<th>Id</th>
<th>Request date</th>
<th>Location</th>
<th>Description</th>
<th>Repair type</th>
<th>Repair status</th>
<th>Real state</th>
<th>Updated at</th>
<th>Updated by</th>
</tr>
</thead>

Choose which headers you want to be sortable. Your code should look something like this:
  <thead>
<tr>
<th>
<?php include_partial('global/sortable_header', array('fieldname'
=> 'id',
'fieldlabel' => 'Id' ,'routename' => '@repairrequest', 'sort'
=> $sort)) ?>
</th>
<th>
<?php include_partial('global/sortable_header', array('fieldname'
=> 'requestDate',
'fieldlabel' => 'Request Date' ,'routename' => '@repairrequest', 'sort' => $sort)) ?>
</th>
<th>
<?php include_partial('global/sortable_header', array('fieldname'
=> 'location',
'fieldlabel' => 'Location' ,'routename' => '@repairrequest', 'sort'
=> $sort)) ?>
</th>
<th>Description</th>
<th>
<?php include_partial('global/sortable_header', array('fieldname' => 'repair_type_id',
'fieldlabel' => 'Repair Type' ,'routename' => '@repairrequest', 'sort'
=> $sort)) ?>
</th>
<th>
<?php include_partial('global/sortable_header', array('fieldname'
=> 'repair_status_id',
'fieldlabel' => 'Repair Status' ,'routename' => '@repairrequest', 'sort' => $sort)) ?>
</th>
<th>
<?php include_partial('global/sortable_header', array('fieldname'
=> 'real_state_id',
'fieldlabel' => 'Real State' ,'routename' => '@repairrequest', 'sort'
=> $sort)) ?>
</th>
<th>Updated at</th>
<th>Updated by</th>
</tr>
</thead>


But there is a problem with this logic. For columns that are foreign keys it will only sort by the id. For example RepairRequest has a one to many relation with RepairType, so i can sort by foreign keys only, thats why I uses as $fieldname repair_request_id. What we actually want is to sort by the name of the RepairType.
I think I can fix this with a custom query on the action. I'll post the fix when I find it.
For now enjoy!!

4 comentarios:

  1. Hola tengo un problema con el tutorial, y no se que es realmente lo que ocurre, el navegador me retorna lo siguiente, ayuda porfa.
    Undefined variable: sort in /Users/Mono/Sites/imprenta/apps/frontend/modules/cliente/templates/indexSuccess.php on line 10 Fatal error: Call to undefined function __() in /Users/Mono/Sites/imprenta/apps/frontend/templates/_sort_header.php on line 9

    ResponderEliminar
  2. Darth: Este error es porque no tienes habilitado el modulo i18n en la aplicacion.

    ResponderEliminar
  3. habilite el modulo i18n, el error de la variable sort desaparecio, pero el segundo error sigue estando.
    __() in Users/Mono/Sites/imprenta/apps/frontend/templates/_sort_header.php on line 9
    no entiendo bien la verdad solo llevo unos pocos de días con symfony

    ResponderEliminar
  4. por cierto no existe linea 9 en _sort_header.php

    ResponderEliminar