Datatables en Laravel (la forma más sencilla)

Muy buenas, lechugas de nuestro corazón!

Hoy traemos un tema muy chulo.

Resulta que un complemento ideal para cualquier sistema de gestión es el datatable.

Tienes que crear un tabla (normalmente con un foreach para rellenar todos los campos),  incluir un jQuery y configurarlo.

Pero bajo algunos frameworks teníamos métodos para que incluir cualquier datatable fuese algo sencillo y rápido. Solo un par de lineas indicando query a la base de datos para obtener los valores a mostrar e indicar cuales de estos valore se muestran.

Poniendo esto en el controlador y una variable que plasme el contenido en la vista nos valía.

Pero ahora, que nos hemos hecho super fans de Laravel, en concreto de su versión 5, veíamos que los packages que existen para incorporar datatable no son óptimos porque no benefician en nada.

La idea es que al usarlos mejoraras, como mínimo, la velocidad en la inclusión de los mismos. Pero no es así! Incluso algunos te complican la vida a la hora de añadir código HTML dentro de las celdas del datatable, o te hacen estár configurando jQuery para enviar datos por ajax, lo que implica generar código en el archivo routes.php además de en el controlador.
Vamos, un follón enorme!

Visto esto, nosotros nos hemos dispuesto a realizar una forma más sencilla de trabajar con datatables.

Para ello hemos creado por ahora algo muy simple. Simple, simple, simple. Tanto que no se puede usar ni composer. Pero todo llegará 😉

Hemos creado un controlador y dos vistas.

Y con dos líneas de código en método del controlador que quieras, se muestra el datatable. Ah! y una variable en la vista XD

Quien quiera lo puede ver en nuestra página de GitHub.

Esto es así. Hemos creado un controlador para cargar los datos en dos vistas, una que contiene la tabla que se convertirá en datatable, y la otra que contiene el script jQuery que lo convierte.

Esto tiene la ventaja de que es muy fácil de modificar por cualquiera 🙂

Además, hemos preparado la vista para que el primer elemento a mostrar vaya al perfil del item (si fuera un usuario, a su perfil completo (user.edit)). Y este link también es modificable. Por defecto es edit, pero puedes poner el que quieras (show por ejemplo –> user.show).

También reconoce si alguno de los valores es un mail y te lo plasma con un mailto.

Estos son los archivos:

DatatableController

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;

class DatatableController extends Controller
{
    /**
     * Para mostrar datatables.
     *
     * @param   string      $dt_id          [el id de la tabla que se convertira en datatable]
     * @param   Collection  $values         [representa la colección de valores que se han de incorporar a la tabla]
     * @param   array       $array_values   [array que contiene los atributos/columnas a mostrar]
     * @param   string      $link           [dirección a la que saltar en el primer parámetro, por defecto 'edit']
     * @param   boolean     $search         [true = se muestran inputs de busqueda en cada columna (pierde traducción)]
     * @return vista HTML
     */
    public function datatable($dt_id, $values, $array_values, $link = 'edit', $search = false)
    {
        $view = \View::make('datatable.datatable', [
                                                        'values'        => $values,
                                                        'datatable_id'  => $dt_id,
                                                        'array_values'  => $array_values,
                                                        'link'          => $link,
                                                        'search'        => $search
                                                    ]);
        $contents = $view->render();

        return  $contents;
    }

    /**
     * Para mostrar el jQuery que carga los datatables.
     *
     * @param   string      $dt_id          [el id de la tabla que se convertira en datatable]
     * @param   boolean     $search         [true = se muestran inputs de busqueda en cada columna (pierde traducción)]
     * @return vista HTML
     */
    public function script($dt_id, $search = false)
    {
        $view = \View::make('datatable.script', ['datatable_id' => $dt_id, 'search' => $search]);
        $contents = $view->render();

        return  $contents;
    }
}


Luego crearemos una carpeta dentro de la carpeta de las vistas a la que llamaremos datatable. Y dentro de ella pondremos dos archivos a los que llamaremos datatable.blade.phpscript.blade.php.

Éstos contendrán lo siguiente:

datatable.blade.php

<div class="row">
  <div class="col-xs-12">
    <table id="{{ $datatable_id }}" class="table table-striped" cellspacing="0">
        <thead>
            <tr>
          	@for ($i = 0; $i < count($array_values); $i++)
          		<th>{!! $array_values[$i] !!}</th>
          	@endfor
            </tr>
        </thead>
        <tbody>
          @foreach ($values as $value)
          <tr>
          	@for ($i = 0; $i < count($array_values); $i++)
          		@if ($i == 0)
          			<td>
          				<a href="{{ route('usuario.' . $link, $value->id) }}" class="text-success">
          					<strong>{!! $value->getAttribute($array_values[$i]) !!}</strong>
          				</a>
          			</td>
          		@else
          			@if (filter_var($value->getAttribute($array_values[$i]), FILTER_VALIDATE_EMAIL))
          				<td>
            				<a href="mailto:{!! $value->getAttribute($array_values[$i]) !!}" class="text-info">
            					{!! $value->getAttribute($array_values[$i]) !!}
            				</a>
          				</td>
          			@else
          				<td>{!! $value->getAttribute($array_values[$i]) !!}</td>
          			@endif
          		@endif
          	@endfor
          </tr>
          @endforeach
        </tbody>
        <tfoot>
            <tr>
          	@for ($i = 0; $i < count($array_values); $i++)
          		<th>{!! $array_values[$i] !!}</th>
          	@endfor
            </tr>
        </tfoot>
    </table>
  </div>
</div>

 

script.blade.php

<script type="text/javascript">
      $(function() {
          window.table_id = '#' + '{{ $datatable_id }}';

          window.table = $(table_id).DataTable({
          	@if (!$search)
              language: {
                  url: "https://cdn.datatables.net/plug-ins/1.10.10/i18n/Spanish.json"
              }
              @endif
          });

          @if ($search)
          window.table_h = $(table_id + ' thead th');
          window.table_f = $(table_id + ' tfoot th');
          @endif
      });
  </script>

 

Cómo lo usamos!?

Pues es muy sencillo.

Vamos a poner un ejemplo: Imaginad que tenéis un controlador para los usuarios. En su método index haremos una búsqueda de todos los usuarios y después haremos las dos llamadas correspondientes:

$users = User::all();
        
$datatable = (new DataTableController)->datatable('datatable_prueba', $users, ['name', 'email', 'phone', 'nif'], 'show', false);
$script = (new DataTableController)->script('datatable_prueba', false);

 

Y en la vista, en la zona donde quisiéramos que apareciese el datatable, pondríamos:

@extends('app')

@section('content')
  <div class="col-xs-12 col-sm-10">
    {!! $datatable !!}
  </div>
@endsection

@section('scripts')
    {!! $script !!}
@endsection

 

Bueno, creo que esto es todo.

Esperamos que os sean útili

5 comentarios en “Datatables en Laravel (la forma más sencilla)

    • Cierto, y creo que es fallo nuestro porque lo hemos dado por sentado.

      Fíjate que en el código del script existen unas líneas que crean dos variables globales jquery, window.table_h y window.table_f.

      En la página de las librerias de los datatables muestran la forma de cargar los input de búsqueda, y lo que nosotros hemos hecho es mostrarlos en función de los valores de estas variables.
      Para ello debes añadir este código (en tu vista o en tu layout):

          if (typeof table_h !== 'undefined') {
              // Setup - add a text input to each header cell
              table_h.each( function () {
                  var title = $(this).text();
                  $(this).html( '' );
              } );
          }
      
          if (typeof table_f !== 'undefined') {
              // Setup - add a text input to each header cell
              table_f.each( function () {
                  var title = $(this).text();
                  $(this).html( '' );
              } );
          }
       
          if (typeof table !== 'undefined') {
              // Apply the search
              table.columns().every( function () {
                  var that = this;
           
                  if (typeof table_h !== 'undefined') {
                      $( 'input', this.header() ).on( 'keyup change', function () {
                          if ( that.search() !== this.value ) {
                              that
                                  .search( this.value )
                                  .draw();
                          }
                      });
                  }
           
                  if (typeof table_f !== 'undefined') {
                      $( 'input', this.footer() ).on( 'keyup change', function () {
                          if ( that.search() !== this.value ) {
                              that
                                  .search( this.value )
                                  .draw();
                          }
                      });
                  }
              });
          }
      
          var getSearch = setInterval(function() {
              if (typeof table_id !== 'undefined')
              {
                  $(table_id + ' input sm').keypress(function(e){
                      console.log(this.value);
                      console.log(event.which);
                  });
      
                  clearInterval(getSearch);
              }
          }, 100);
      

      Con esto te deberían de aparecer los buscadores.

      Sobre el tema de la paginación te lo miro y te digo algo.

      Un saludo,

      Fran.

      NOTA: Fíjate que en GITHub ya hemos indicado una actualización en el código para poder poner la plantilla del datatable a tu gusto generando un archivo e indicando en el controlador cual es. Espero que eso también te sea útil.

    • Muy buenas de nuevo,
      Los únicos motivos por los que creo que no te deben de salir los enlaces de la paginación debe de ser porque no debes tener incluidos los script necesarios para ello, como indicábamos en el post.

      Te los dejo aquí:

      
      
      
      

      Si no este el problema, envíanos un correo a info@freshware.es concretando qué tienes en cada archivo de las vistas y de los controladores.

      Un saludo,

      Fran.

  • Me falto agregar este contenido a la vista {!! $script !!} por eso no me aparecían la búsqueda y la paginación. Muchas gracias. LO que estoy tratando de poner una clase al pero no he encontrado la forma.
    Muchas gracias por toda su ayuda.

Deja un comentario