martes, 16 de enero de 2018

Laravel DataTables 2

Como indicaba en el capítulo anterior, el primer proyecto donde quería probar Laravel DataTables no estaba basado en Laravel. Pero sí había un proyecto relacionado, mucho más reciente, que utilizaba la misma base de datos y que sí tenía Laravel. Lo que hace jQuery DataTables en modo server-side no son más que llamadas AJAX. Así que el lado de Laravel es básicamente una API lista para servir.

Después de instalar Laravel DataTables (como cualquier otro paquete mediante Composer), creé un controlador exclusivamente para esto, con la función data. Como explica la demo oficial, puede bastar con retornar DataTables::of(Modelo::all())->make(true).

Desgraciadamente como este era un proyecto antiguo pre-Laravel, el acceso por modelo no me sirve. O al menos no de manera directa y fácil.
Afortunadamente Laravel DataTables puede recolectar datos en base a tres tipos de objetos: Eloquent, Collection y Query Builder.

  • Eloquent sería trabajar con los Modelos, tal cual. Si están bien definidos, con sus relaciones y todo, es lo más laraveliano. Lo ideal en muchos casos.
  • La Colección debe estar completamente formada antes de llamar a DataTables. Es útil si los datos necesitan ser tratados en PHP, o cualquier historia "chunga". Esto implica más trabajo todavía para PHP, y menor flexibilidad a la hora de aplicar filtros.
  • Query Builder... ya sabe usted, suele ser el paso previo en Laravel a get(), all(), o cualquier función que implique ejecutar la consulta / query. Puede ser tanto formada con métodos de modelos, de DB, o escribiendo manualmente el SQL.

Como este proyecto tenía unas relaciones un tanto complicadas, opté por Query Builder. No es lo ideal, pero así pude copiar las consultas que se estaban utilizando previamente y basarme en ellas. Venía a ser: return DataTables::of(DB::table('tabla')->select(['columna1', 'columna2']))->make(true);

Listos por el lado del controlador. ... ¿Que cómo se gestionan las búsquedas, paginación, etc.? La función of se encarga absolutamente de toda la interactividad, en base a parámetros auto-generados que envía el cliente con cada clic. No hay que programar nada para estos casos. Ni siquiera hace falta extender el controlador.

Lo único que falta es la ruta:
Route::name('tabla.data')->get('tabla/data', 'TablaController@data');

Como verá usted, la ruta no tiene nada de especial. El controlador se encarga de todo.

Por supuesto hay diferencias con mi proyecto: lo paso por ruta POST, en lugar de GET (preferencia personal), y el controlador lo extiendo de ApiGuard (sí, un poco de seguridad, ya que es una API entre dos proyectos, y no quiero que pueda acceder cualquiera).

En el HTML del front-end escribo la tabla solo con sus cabeceras, una por columna, y añado el script necesario:
    $(function() {
        $('#list-table').DataTable({
            processing: true,
            serverSide: true,
            columns: [
                { data: 'columna1' },
                { data: 'columna2', orderable: false, searchable: false }
            ],
            ajax: 'http://sitio.net/tabla/data'
            }
        });
    });

Y con eso ya tenemos lo básico. Creo que por ahora no necesita más explicación, aparte de que esas dos primeras propiedades siempre deben ser true (hasta donde yo sé).


A partir del próximo capítulo serán principalmente detalles y casos más específicos. Condiciones para las búsquedas, cómo tratar columnas de otras tablas, acciones para cada fila, filtro individual por columna, etc.

No hay comentarios:

Publicar un comentario