Vamos a crear un sistema de scroll infinito con Laravel 5 y jQuery sin la necesidad de plugins, hace tiempo ya escribí un tutorial para realizar scroll infinito con Laravel 4.
Si no conoces el concepto de scroll infinito es muy sencillo, la idea es por ejemplo mostrar 5 posts. Cada vez que el usuario hace scroll y llega al final de la página, nosotros ejecutamos un evento con jQuery para obtener y mostrar los nuevos posts a partir del último que se ha mostrado utilizando ajax, y así hasta que no queden más.
Para entenderlo mejor, a continuación tienes un ejemplo del resultado final de nuestra aplicación.
Lo primero que debemos hacer es tener datos en nuestra aplicación, así que asegúrate de tener un modelo Post con su respectiva tabla y ejecuta el siguiente seed para poder introducir datos en la base de datos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder { public function run() { $this->call(PostTableSeeder::class); } } class PostTableSeeder extends Seeder { public function run() { DB::table('posts')->insert([ [ 'title' => 'laravel 5.3, un potente framework', 'body' => 'introducción a laravel 5.3' ], [ 'title' => 'codeigniter, esperando su versión 4.0', 'body' => 'tiene muy buena pinta la nueva versión' ], [ 'title' => 'zend framework, otro gran framework', 'body' => 'no soy muy amigo de él, aunque lo conozco' ], [ 'title' => 'symfony, gran framework', 'body' => 'uno de los mejores frameworks php' ], [ 'title' => 'angular 2, un buen framework en typescript', 'body' => 'trabajando de forma ordenada en typescript' ], [ 'title' => 'jQuery, la mejor librería javascript', 'body' => 'que mal lo ibamos a pasar sin él' ], [ 'title' => 'sublime text', 'body' => 'un muy buen editor de código y muy rápido' ], [ 'title' => 'aptana studio', 'body' => 'buen ide, pero demasiado pesado, hace falta tener un i7 para abri un proyecto :(' ], [ 'title' => 'windows 10', 'body' => 'me gusta más que windows 8' ], [ 'title' => 'visual studio code', 'body' => 'lo mejor de lo mejor para programar y encima free' ], [ 'title' => 'mac os', 'body' => 'lo mejor para programar' ], [ 'title' => 'linux', 'body' => 'bueno y rápido' ] ]); } } |
Ahora vamos a definir las dos rutas que necesitaremos para desarrollar nuestro ejemplo, una para mostrar el primer contenido sin utilizar ajax y otra para realizar peticiones xmlHttpRequest y obtener los datos en formato json.
1 2 |
El controlador InfiniteController será muy sencillo, simplemente tendrá dos métodos, 1 para obtener los primeros datos y el otro para poder obtener los siguientes siempre que se trate de una petición ajax.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Http\Requests; use App\Post; class InfiniteController extends Controller { /** * obtenemos los primeros posts y presentamos en la template infinite-scroll */ public function index() { $posts = Post::skip(0)->take(4)->get(); return view('infinite-scroll', compact('posts')); } /** * devolvemos los siguientes posts en formato json si es una petición ajax */ public function scroll(Request $request) { if($request->ajax()) { $lastId = $request->get("lastId"); $posts = Post::where("id", ">", $lastId)->take(2)->get(); if(count($posts) > 0) { return response()->json([ "response" => true, "posts" => $posts ] ); } return response()->json([ "response" => false ] ); } abort(403); } } |
Cómo puedes ver, en la primera petición obtenemos 4 posts desde el primero take(0), y en el evento de scroll iremos obteniendo de 2 en 2 siempre que el id sea mayor que el id que vamos a enviar, que será el del último posts visualizado en el sistema de scroll infinito.
En este momento debemos crear un archivo infinite-scroll.blade.php para mostrar los 4 primeros posts, así que crea ese archivo y añade el siguiente código.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <html> <head> <title>Infinite Scroll Laravel 5</title> <link rel="stylesheet" href="{{ asset('/bower_components/bootstrap/dist/css/bootstrap.css') }}"> <script src="{{ asset('/bower_components/jquery/dist/jquery.js') }}"></script> <script src="{{ asset('/js/functions.js') }}"></script> </head> <body> <div class="container" style="margin-bottom:50px"> <h1 class="center text-muted">Scroll Infinito con jQuery y laravel 5</h1> <!-- aquí cargaremos todos los posts --> <div id="scroll"> @foreach($posts as $post) <div class="panel panel-default"> <div class="panel-heading"> <p>Título: {{ $post->title }}</p> </div> <div class="panel-body"> <p>Id: {{ $post->id }} </p> <p>Contenido: {{ $post->body }}</p> </div> </div> <?php $id = $post->id ?> @endforeach </div> <!-- aquí mostramos el preloader --> <div style="margin: 10px 0px 0px 48%" class="before"></div> <!-- aquí guardamos el último id, hay muchas formas de hacer esto --> <div class="lastId" style="display:none" id="{{ $id }}"></div> </div> </body> </html> |
Si te fijas, en la cabecera de este archivo estamos llamando a un archivo llamado functions.js que está dentro del directorio js, así que vamos a crearlo.
Scroll infinito con Laravel 5 y jQuery
En este archivo es donde debemos escribir toda la lógica con jQuery para que nuestro sistema de scroll infinito con Laravel 5 funcione, así que vamos añadir el siguiente código.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | var morePosts, //controlamos si hay posts scroll = null;//evitamos que el evento scroll se disparé múltiples veces //creamos una función para llamarla en el evento del scroll function loadMore() { var id = $(".lastId").attr("id"), getLastId, html = ""; if (id) { $.ajax({ type: "GET", url: "http://localhost:8000/infinite", data: `lastId=${id}`,//la última id success: function(data) { $(".before").html(""); if(data.response == true) { for(datos in data.posts) { html += '<div class="panel panel-default">'; html += '<div class="panel-heading">'; html += `<p>Título: ${data.posts[datos].title}</p>`; html += '</div>'; html += '<div class="panel-body">'; html += `<p>Id: ${data.posts[datos].id}</p>`; html += `<p>Body: ${data.posts[datos].body}</p>`; html += '</div>'; html += '</div>'; getLastId = data.posts[datos].id; } $("#scroll").append(html); morePosts = true; } else { //ya no hay más posts que mostrar morePosts = false; $("#scroll").append("<div data-alert class='alert alert-info center'>Ya no hay más posts</div>"); } $(".lastId").attr("id",getLastId); }, error: function() { //TODO controlar los errores } }); } } //actuamos en en evento del scroll $(window).on('scroll',function() { //si hay más posts if(morePosts !== false) { $(".before").html("<img src='/imgs/preloader.gif' />"); //si scroll es distinto de null if (scroll) { clearTimeout(scroll); //limpiamos la petición anterior de scroll } //si el scroll ha llegado al final lanzamos la función loadMore() if ($(window).scrollTop() >= $(document).height() - $(window).height() - 10) { scroll = setTimeout(function() { scroll = null; //lanzamos de nuevo el scroll loadMore(); }, 1000); } } }) |
Y eso es todo, de esta forma ya tenemos un sistema de scroll infinito con Laravel 5 montado y funcionando, recuerda que si tienes dudas con el código que hemos escrito tienes a tu disposición 14 cursos en cursosdesarrolloweb.es.