Buscador en tiempo real en Laravel y Javascript
Programar un buscador en tiempo real con el Framework Laravel con la API nativa de Javascript para extraer datos de forma asíncrona, conocida con fetch. Con autocompletado
INDICE
En este tutorial aprenderás a construir un buscador en tiempo real utilizando Laravel y JavaScript, una funcionalidad muy útil para mejorar la experiencia del usuario en aplicaciones web modernas. Un buscador en tiempo real permite que, a medida que el usuario escribe en una caja de texto o input, esa información se envíe automáticamente al servidor para ser procesada.
Laravel se encargará de recibir la solicitud, realizar la consulta correspondiente y devolver una respuesta, ya sea exitosa o indicando que no se encontraron resultados. Por su parte, JavaScript permitirá actualizar la vista dinámicamente para mostrar los datos devueltos sin necesidad de recargar la página.
Al finalizar este tutorial tendrás un buscador ágil, eficiente y totalmente funcional, listo para integrar en tus proyectos.
Pasos para programar un buscador Laravel con autocompletado
Pasos para programar un buscador Laravel con autocompletado
Declarar las rutas necesarias para el buscador incluyendo la ruta para Fetch
- Implementar un método en el controlador que retorne el texto encontrado a una vista
- Implemenación de una vista para mostrar los resultados
- Un poco de Javascript Fetch para procesar en tiempo real la petición.
Parece que fuera complejo desarrollar esta funcionalidad, pero usando Laravel y un poco de Javascript lograremos realizarla con facilidad. Se cree que utilizando Librerías adicionales como Axios.js, Jquery o Vue.js se obtiene mejor perfomance. Pero está aplicación es sencilla y básica por tanto, pienso que no es necesario cargar alguna librería adicional, suficiente con Bootstrap que al usarla ya ralentiza nuestra aplicación web, si no prueben con un test de velocidad de Google Speed.
Ahora, pongamos en contexto esta aplicación, vamos a usar la configuración de la anterior publicación, te recomiendo revisarlo en el siguiente enlace de ¿Cómo programar un scroll infinito? donde ya tenemos instalado y configurado Laravel además del modelo Nombres y sus 1000 registros; entonces aprovecharemos lo que ya esta implementado para continuar con el desarrollo de ésta publicación.
Empecemos a programar el Buscador
Empecemos a programar el Buscador
Abrimos el archivo de rutas que se encuentra en Routes/web.php este archivo ya contiene dos rutas a la cual agregaremos una más, ¿Por qué? pues porque necesitamos crear una ruta que será usada para realizar las peticiones asíncronas.
- JS Fetch: Envía GET a /search?q=texto y recibe JSON con resultados paginados.
- Simple y Rápido: Sin dependencias extra en frontend. Para autocomplete, agrega input event listener.
- Prueba: Crea posts en BD, indexa y accede a la vista.
El Modelo donde buscaremos datos ...1
El Modelo donde buscaremos datos ...1
El archivo Pais.php define el modelo Eloquent que representa a la tabla pais (o paises, dependiendo de tu convención) dentro de la base de datos. Este modelo permite interactuar con los registros de esa tabla utilizando la sintaxis sencilla y expresiva que ofrece Laravel. Veamos cada parte del código:
Pais.php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Pais extends Model
{
use HasFactory;
protected $guarded = [];
public $timestamps = false;
}
namespace App\Models;
Indica que este archivo forma parte del espacio de nombres App\Models, donde Laravel organiza todos los modelos de la aplicación.
use HasFactory;
El trait HasFactory permite utilizar factories para generar datos de prueba o instancias del modelo de manera rápida y automatizada. Esto es útil especialmente en pruebas o ambientes de desarrollo.
class Pais extends Model
Declara la clase Pais, que hereda de la clase base Model. Esto significa que será tratado como un modelo Eloquent y tendrá acceso a todas sus funcionalidades: consultas, relaciones, guardado de registros, etc.
protected $guarded = [];
Define qué atributos NO pueden ser asignados masivamente. Establecerlo como un array vacío ([]) significa que todos los campos de la tabla pueden asignarse de manera masiva, lo cual es útil en operaciones como Pais::create($request->all()).
Nota: Debe usarse con precaución para evitar asignar campos no deseados.
public $timestamps = false;
Indica que el modelo no manejará automáticamente las columnas created_at y updated_at, ya que la tabla asociada no las utiliza. Eloquent, por defecto, espera estos campos, pero al deshabilitar esta función evitamos errores al insertar o actualizar registros.
En resumen, este modelo sirve como puente entre la aplicación y la tabla de países, permitiendo realizar consultas y manipulaciones de datos de forma sencilla sin necesidad de escribir SQL manualmente.
Las Rutas o urls para nuestro buscador web...2
Las Rutas o urls para nuestro buscador web...2
El siguiente fragmento de código define las rutas principales que usará la aplicación para mostrar la vista inicial y manejar el funcionamiento del buscador en tiempo real.
Entonces, en web.php nuestro código debe quedar de la siguiente forma:
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\BuscadorController;
Route::get('/', function () {
return view('welcome');
});
Route::get('buscador',[BuscadorController::class,'index']);
Route::post('buscador',[BuscadorController::class,'buscar']);
Importaciones necesarias
use Illuminate\Support\Facades\Route; use App\Http\Controllers\BuscadorController;
Aquí se importan las clases necesarias para registrar rutas y para acceder al controlador BuscadorController, que será el encargado de manejar la lógica del buscador.
Ruta principal
Route::get('/', function () { return view('welcome'); });
Esta ruta responde a la URL raíz / de la aplicación. Cuando un usuario ingresa al sitio, se le devuelve la vista welcome.blade.php. Es solo la página inicial y no está relacionada directamente con el buscador.
Ruta GET: mostrar el buscador
Route::get('buscador',[BuscadorController::class,'index']);
Esta ruta se accede mediante una petición GET a /buscador.
Su propósito es mostrar la vista donde se encuentra el input del buscador.
La lógica que devuelve esa vista se encuentra en el método index() del BuscadorController.
Ruta POST: procesar la búsqueda
Route::post('buscador',[BuscadorController::class,'buscar']);
Esta ruta recibe una petición POST desde JavaScript cuando el usuario escribe en el input.
El método buscar() del controlador se encargará de:
- Recibir el texto ingresado.
- Consultar la base de datos.
- Retornar los resultados para ser mostrados en la vista.
Es esta ruta la que permite el funcionamiento del buscador en tiempo real.
El Controlador BuscadorController.....3
El Controlador BuscadorController.....3
El controlador BuscadorController es el encargado de manejar la lógica del buscador en tiempo real. Contiene dos métodos principales: uno para mostrar la vista del buscador y otro para procesar las consultas que llegan desde JavaScript.
BuscadorController.php
namespace App\Http\Controllers;
use App\Models\Pais;
use Illuminate\Http\Request;
class BuscadorController extends Controller
{
public function index(){
return view("welcome");
}
public function buscar(Request $request){
$response= [
"success"=>false,
"message"=>"Hubo un error"
];
if($request->ajax()){
$data = Pais::where("nombre","like",$request->texto."%")->take(10)->get();
$response= [
"success"=>true,
"message"=>"Consulta Correcta",
"data"=>$data
];
}
return response()->json($response);
}
}
Importaciones del controlador
use App\Models\Pais; use Illuminate\Http\Request;
-
Pais: el modelo Eloquent que permitirá consultar la tabla de países en la base de datos.
-
Request: clase que permite acceder a los datos enviados en la petición AJAX.
Método index()
public function index(){ return view("welcome"); }
Este método simplemente retorna la vista welcome, donde se encuentra el formulario o input del buscador.
Es la ruta que devuelve la interfaz inicial al usuario.
Método buscar(Request $request)
Este método procesa la solicitud AJAX enviada desde JavaScript cuando el usuario teclea en el buscador.
$response= [ "success"=>false, "message"=>"Hubo un error" ];
Se inicia un arreglo de respuesta con valores por defecto. Esto funciona como una respuesta de respaldo en caso de que algo salga mal.
Validación de petición AJAX
if($request->ajax()){
Se verifica que la petición realmente provenga de una llamada AJAX.
Si es así, se procede a realizar la consulta en la base de datos.
Consulta a la base de datos
$data = Pais::where("nombre","like",$request->texto."%") ->take(10) ->get();
Aquí se realiza la búsqueda:
-
where("nombre", "like", ...): busca registros cuyo nombre comience con el texto digitado.
-
$request->texto: captura el texto enviado desde el input.
-
take(10): limita los resultados a 10 registros, evitando consultas pesadas.
-
get(): obtiene la colección de resultados.
Respuesta en caso de éxito
$response= [ "success"=>true, "message"=>"Consulta Correcta", "data"=>$data ];
Si la consulta es exitosa, se genera una respuesta con:
-
success= true -
message= texto descriptivo -
data= los resultados obtenidos
Retorno en formato JSON
return response()->json($response);
Finalmente, se retorna la respuesta en formato JSON, que será recibida y procesada por el JavaScript del cliente para actualizar la vista en tiempo real.
La Vista y Javascript fetch....4
La Vista y Javascript fetch....4
Este archivo contiene la estructura HTML, el formulario y el código JavaScript necesarios para capturar el texto ingresado por el usuario y enviar la solicitud AJAX al servidor sin recargar la página. Luego, muestra los resultados que recibe desde el controlador.
Welcome.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>Laravel</title>
</head>
<body>
<form action="" method="post">
<input type="search" name="texto" id="buscar">
</form>
<div id="resultado"></div>
<script>
window.addEventListener("load",function(){
buscar.addEventListener("keyup",(e)=>{
fetch(`/buscador`,{
method:'post',
body:JSON.stringify({texto : buscar.value}),
headers:{
"Content-Type":"application/json",
"X-Requested-With": "XMLHttpRequest",
"X-CSRF-Token":document.head.querySelector("[name~=csrf-token][content]").content
}
})
.then(response=>{
return response.json()
})
.then(data=>{
var html = ""
if(data.success){
html += "<ul>"
for (var i in data.data) {
html += "<li>"+data.data[i].nombre+"</li>"
}
html += "</ul>"
}else{
html += "No existen resultados"
}
resultado.innerHTML = html
})
})
})
</script>
</body>
</html>
Estructura básica del documento
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
Laravel genera dinámicamente el atributo lang según la configuración local de la aplicación.
Metadatos importantes
<meta name="csrf-token" content="{{ csrf_token() }}">
Esto agrega un token CSRF, necesario para que Laravel acepte las solicitudes POST provenientes de JavaScript.
Sin este token, la petición sería rechazada por motivos de seguridad.
Campo de búsqueda
<form action="" method="post">
<input type="search" name="texto" id="buscar">
</form>
<div id="resultado"></div>
-
El formulario contiene un
<input>donde el usuario escribe el texto a buscar. -
El
<div id="resultado">será rellenado dinámicamente con los resultados.
Importante: El formulario no se envía realmente, solo se usa el input.
El envío se realiza mediantefetch().
JavaScript: envío y procesamiento del buscador
Este es el corazón del buscador en tiempo real.
window.addEventListener("load",function(){
buscar.addEventListener("keyup",(e)=>{
fetch(`/buscador`,{
method:'post',
body:JSON.stringify({texto : buscar.value}),
headers:{
"Content-Type":"application/json",
"X-Requested-With": "XMLHttpRequest",
"X-CSRF-Token":document.head.querySelector("[name~=csrf-token][content]").content
}
})
.then(response=>{
return response.json()
})
.then(data=>{
var html = ""
if(data.success){
html += "<ul>"
for (var i in data.data) {
html += "<li>"+data.data[i].nombre+"</li>"
}
html += "</ul>"
}else{
html += "No existen resultados"
}
resultado.innerHTML = html
})
})
})
Explicación paso a paso:
✔ Escuchar el evento keyup
Cada vez que el usuario presiona una tecla dentro del input, se ejecuta la búsqueda:
buscar.addEventListener("keyup", (e) => {
✔ Enviar datos al servidor con fetch()
fetch(`/buscador`,{
method:'post',
body:JSON.stringify({texto : buscar.value}),
headers:{
"Content-Type":"application/json",
"X-Requested-With": "XMLHttpRequest",
"X-CSRF-Token":document.head.querySelector("[name~=csrf-token][content]").content
}
})
-
method: 'post' → usa la ruta POST definida en web.php.
-
body: → se envía un JSON con el texto ingresado.
-
headers:
-
Content-Type: indica que se envía JSON. -
X-Requested-With: permite que Laravel detecte que es una petición AJAX. -
X-CSRF-Token: previene ataques CSRF.
-
✔ Recibir y convertir la respuesta JSON
.then(response => response.json())
Laravel devuelve un JSON, que se transforma a un objeto JavaScript.
✔ Procesar los resultados
if(data.success){
html += "<ul>"
for (var i in data.data) {
html += "<li>"+data.data[i].nombre+"</li>"
}
html += "</ul>"
}else{
html += "No existen resultados"
}
}
-
Si
successes true, se recorren los resultados y se construye una lista<ul>. -
Si no, se muestra un mensaje de “No existen resultados”.
✔ Mostrar los resultados en el DOM
resultado.innerHTML = html
Reemplaza el contenido del <div> con los datos generados.
Esta vista completa el ciclo del buscador en tiempo real:
- El usuario escribe texto.
- JavaScript envía el texto al servidor vía AJAX.
- Laravel procesa la búsqueda.
- JavaScript recibe los resultados y actualiza la vista.
Leido 29719 veces | 2 usuarios
Buscador en tiempo real en Laravel y Javascript
Accede al código fuente esencial de nuestra aplicación en formato ZIP ó TXT. Ideal para desarrolladores que desean personalizar o integrar nuestra solución.
- [ Descargas: 1 ]
Examen
Evalua tus conocimientos
CÓDIGO FUENTE: USD 0.00
Conversar con J.Luis
