jueves, 10 de mayo de 2012

Crear filtros con paginador en Symfony 1.4

Bien recientemente me vi en la necesidad de aplicar filtros a una lista paginada, bien el filtro funciona bien simpre y cuando no cambies de pagina en la lista. para solucionar esto realice algunos ajustes:
//Nota: el siguiente ej. es parte de un sistema de registro de actividades
en el action:
public function executeIndex(sfWebRequest $request)
  {
    $query = Doctrine_Core::getTable('Actividad')
            ->createQuery('a');
    $this->filtro = new ActividadFormFilter();
    if($request->isMethod('post')) {
        $this->filtro->bind($request->getParameter($this->filtro->getName()));
        if ($this->filtro->isValid()){
            $query =  $this->filtro->buildQuery($this->filtro->getValues());
        }
    }
    $this->pager = new sfDoctrinePager('Actividad',sfConfig::get('app_nb_results_per_page'));
    $this->pager->setQuery($query);
    $this->pager->setPage($request->getParameter('page', 1));
    $this->pager->init();
  }
app_nb_results_per_page se define en proy/apps/app/config/app.yml de la siguiente manera
all:
  nb_results_per_page: 50
en el template lo que sigue...
formulario del filtro:


Script:
 
vinculos del paginador:
<?php if ($pager->haveToPaginate()): ?>

<?php endif; ?>
Páginas :<?php echo $pager->getPage() ?> / <?php echo $pager->getLastPage()?>
Total de registros :<?php echo $pager->getNbResults() ?>

y para finalizar ajusto los widgets que necestio:


class ActividadFormFilter extends BaseActividadFormFilter
{
  public function configure()
  {
      
        //lista de widgets que quieres mostrar
      $this->wantedFields = array(
           'usuario_list',
           'fecha_inicio',
           'fecha_fin',
           'estatus_id',
           'centro_id',);
      foreach ($this as $fieldName => $widget){
        if (!in_array($fieldName, $this->wantedFields)){
            //unset a los widgets que no estan en el arreglo
            unset($this->widgetSchema[$fieldName]);
            unset($this->validatorSchema[$fieldName]);
        }
      }
        
      $years = range(date('Y'), 2010 );
      $this->widgetSchema['fecha_inicio'] = new sfWidgetFormFilterDate(array(
                 'from_date' =>new sfWidgetFormI18nDate(array('years' => array_combine($years, $years),
                                            'format' => '%day% %month% %year%',
                                            'culture' => 'es',
                                            'empty_values' => array('day' => '<- Día ->', 'month' => '<- Mes ->', 'year' => '<- Año ->'),
                                     )),
                 'to_date' => new sfWidgetFormI18nDate(array('years' => array_combine($years, $years),
                                            'format' => '%day% %month% %year%',
                                            'culture' => 'es',
                                            'empty_values' => array('day' => '<- Día ->', 'month' => '<- Mes ->', 'year' => '<- Año ->'),
                                     )),
                 'with_empty' => 0,                   // Para que no salga el checkbox
                 'template' => 'desde : %from_date% 
hasta :  %to_date%'
                ));
      $this->widgetSchema['fecha_fin'] = new sfWidgetFormFilterDate(array(
                 'from_date' =>new sfWidgetFormI18nDate(array('years' => array_combine($years, $years),
                                            'format' => '%day% %month% %year%',
                                            'culture' => 'es',
                                            'empty_values' => array('day' => '<- Día ->', 'month' => '<- Mes ->', 'year' => '<- Año ->'),
                                     )),
                 'to_date' => new sfWidgetFormI18nDate(array('years' => array_combine($years, $years),
                                            'format' => '%day% %month% %year%',
                                            'culture' => 'es',
                                            'empty_values' => array('day' => '<- Día ->', 'month' => '<- Mes ->', 'year' => '<- Año ->'),
                                     )),
                 'with_empty' => 1,                   // Para que salga el checkbox
                 'empty_label' =>'Sin Egreso',
                 'template' => 'desde : %from_date% 
hasta :  %to_date%'
                ));
     
     $this->widgetSchema['centro_id'] = new sfWidgetFormDoctrineChoice(array(
            'model'     => 'Centro',
            'add_empty' => '<- Seleccione Centro ->',
            'label' => 'Estado de Procedencia',
        ));
      
      
      $this->widgetSchema['usuario_list'] = new sfWidgetFormDoctrineChoice(
              array('multiple' => true,
                  'expanded' => true,
                  'model'=>  'Usuario',
                  'table_method'=>'getUsuariosByCoordinacion',
                  'key_method'=>'getId',
                  ));
      
      
      $this->widgetSchema->setLabels(array(
        'fecha_inicio'    =>'Fecha de inicio :',
        'fecha_fin' =>'Fecha de culminacion :',
        'tipo_actividad'    =>'Tipo de actividad :',
        'estatus_id'   =>'Estatus :',
        'lugar_actividad' =>'Lugarde la actividad :',
        'centro_id'    =>'Centro :',
        'recurso_humano' =>'Personas externas involucradas :',
        'institucion_list'    =>'Instituciones :',
        'usuario_list'   =>'Participantes :',
        'observacion_analista' =>'Observaciones del analista:',
        'descripcion'   =>'Titulo de la actividad :',
        'observacion' =>'Objetivo y Observaciones de la actividad:',
	));  
  }
}
Resumen: se crea el filtro como normalmente lo harias, al igual que el paginado, luego modificas los vinculos para navegar entre paginas eliminando el href y agregando onClick; agregas el javascript y listo!!
2 ejemplos en 1: filtros y paginador...
nota: al inicio de la clase para los filtros agregue una funcion muy util para hacer unset a los widgets que no necesitamos usar, hace un tiempo la consegui en un post y no he podido conseguirlo nuevamente... asi q ahi se los dejo...

1 comentario:

  1. Gracias por el post, queria preguntarte por que para la validacion de fechas no usaste sfWidgetFormDateRange?

    ResponderEliminar