Validar un formulario con Laravel, JavaScript y Bootstrapt 5 sin recargar la página.
Hola developes hoy en esta sección vamos a aprender a validar un formulario con Laravel y JavaScript sin recargar la página. Para maquetar el formulario utilizaremos Bootstrap 5. Y para el envió de datos al backend utilizaremos fetch que espera como respuesta un json.
Autor: rogercode. Full stack developerPrimero debes de tener un proyecto de Laravel. Si no tienes uno aquí te comparto el link donde puedes ver las diferentes formas de obtener un nuevo proyecto ☛ Instalación - Laravel.
Codigo fuente de los archivos utilizados para el proyecto ☟.
A continuación, se muestran los archivos con el código empleado para la validación del formulario.
1 ruta => resources/views/windows.blade.php ☟.
Es la vista principal del proyecto. Para maquetar la interfaz se utiliza las etiquetas html5 y para mejorar la apariencia se utiliza Bootstrap 5.
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
</head>
<body>
<div class="container shadow-lg p-3 mb-5 bg-body rounded">
<h5><span class="shadow mb-5 rounded">Registro de Usuario</span></h5>
<form class="row g-3" autocomplete="off" id="form">
@csrf
<div class="col-md-3">
<label for="nombre" class="form-label">Nombre</label>
<input type="text" class="form-control" id="nombre" name="nombre" placeholder="Ingresa el nombre">
<span class="badge text-danger errors-nombre"></span>
</div>
<div class="col-md-3">
<label for="primer" class="form-label">Primer apellido</label>
<input type="text" class="form-control" id="primer" name="primer" placeholder="Ingresa el primer apellido">
<span class=" badge text-danger errors-primer"></span>
</div>
<div class="col-md-3">
<label for="segundo" class="form-label">Segundo apellido</label>
<input type="text" class="form-control" id="segundo" name="segundo" placeholder="Ingresa el segundo apellido">
<span class="badge text-danger errors-segundo"></span>
</div>
<div class="col-md-3">
<label class="badge text-danger errors-segundo">Correo</label>
<input type="email" class="form-control" id="email" name="email" placeholder="Ingresa un correo">
<span class="badge text-danger errors-email"></span>
</div>
<div class="col-md-6">
<label for="password" class="form-label">Contraseña</label>
<input type="password" class="form-control" id="password" name="password" placeholder="Ingresa el password">
<span class="badge text-danger errors-password"></span>
</div>
<div class="col-md-6">
<label for="confirmarpassword" class="form-label">Confirmar contraseña</label>
<input type="password" class="form-control" id="confirmarpassword" name="confirmarpassword" placeholder="Confirma el password">
<span class="badge text-danger errors-confirmarpassword"></span>
</div>
<div class="col-12">
<label for="direccion" class="form-label">Direccion</label>
<input type="text" class="form-control" id="direccion" name="direccion" placeholder="Ingresa la direccion">
<span class="badge text-danger errors-direccion"></span>
</div>
<div class="col-md-5">
<label for="ciudad" class="form-label">Ciudad</label>
<input type="text" class="form-control" id="ciudad" name="ciudad" placeholder="Ingresa el nombre de la ciudad">
<span class="badge text-danger errors-ciudad"></span>
</div>
<div class="col-md-4">
<label for="rol" class="form-label">Rol</label>
<select id="rol" name="rol" class="form-select">
<option value="">Selecciona un Rol</option>
<option value="Administrador">Administrador</option>
<option value="Usuario">Usuario</option>
</select>
<span class="badge text-danger errors-rol"></span>
</div>
<div class="col-md-3">
<label for="postal" class="form-label">Codigo postal</label>
<input type="text" class="form-control" id="postal" name="postal" placeholder="Ingresa un codigo postal">
<span class="badge text-danger errors-postal"></span>
</div>
<div class="alert alert-success" style="display: none;"></div>
<div class="col-12">
<button type="text" id="btn-enviar" class="btn btn-primary">Aceptar</button>
</div>
</form>
</div>
<script src="{{asset('js/index.js')}}"></script>
</body>
</html>
2 ruta => public/js/index.js ☟.
El archivo index.js contiene el código necesario para enviar los datos del formulario al backend utilizando fetch y FormData.
const btn = document.querySelector("#btn-enviar");
const form = document.querySelector("#form");
btn.addEventListener("click", (e) =>{
e.preventDefault();
const datos = new FormData(form);
fetch('guardar',{
method: 'post',
body:datos
})
.then(response => response.json())
.then(result => {
console.log(result)
if (result.alerta == "danger") {
let nombre = document.querySelector(".errors-nombre");
nombre.textContent = result.nombre[0];
let primer = document.querySelector(".errors-primer");
primer.textContent = result.primer[0];
let segundo = document.querySelector(".errors-segundo");
segundo.textContent = result.segundo[0];
let email = document.querySelector(".errors-email");
email.textContent = result.email[0];
let password = document.querySelector(".errors-password");
password.textContent = result.password[0];
let confpassword= document.querySelector(".errors-confirmarpassword");
confpassword.textContent = result.confirmarpassword[0];
let direccion = document.querySelector(".errors-direccion");
direccion.textContent = result.direccion[0];
let ciudad = document.querySelector(".errors-ciudad");
ciudad.textContent = result.ciudad[0];
let rol = document.querySelector(".errors-rol");
rol.textContent = result.rol[0];
let postal = document.querySelector(".errors-postal");
postal.textContent = result.postal[0];
let badge = document.querySelectorAll(".badge");
badge.forEach(span => {
span.style.display = "block"
span.style.textAlign = "left";
});
setTimeout(() => {
badge.forEach(span => {
span.style.display = "none";
});
}, 3000);
}
if (result.alerta == "success") {
const success = document.querySelector(".alert");
success.textContent = "El formulario se valido correctamente";
success.style.display = "block";
}
})
});
3 ruta => routes/web.php ☟.
En el archivo web.php se define la ruta que permite conectar el frontend con el backend mediante un controlador. Ver más ☛ Los controladores
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ValidateformController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Route::post('/guardar', [ValidateformController::class, 'guardarDatos']);
4 ruta => app/http/controllers/ValidateformController.php ☟.
El controlador contiene una función que recibe como parámetro los datos enviados desde el frontend para validar cada uno de los campos del formulario mediante el método Validator.
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Response;
use Illuminate\Support\Facades\Validator;
class ValidateformController extends Controller
{
public function guardarDatos(Request $request){
$campos = [
"nombre"=>"required",
"primer"=>"required",
"segundo"=>"required",
"email"=>"required|email",
"password"=>"required",
"confirmarpassword"=>"required|same:password",
"direccion"=>"required",
"ciudad"=>"required",
"rol"=>"required",
"postal"=>"required|digits:5",
];
$mensajes =[
"nombre.required"=>"El nombre es requerido",
"primer.required"=>"El primer apellido es requerido",
"segundo.required"=>"El segundo apellido es requerido",
"email.required"=>"El correo electronico es requerido",
'email.email'=>'El formato de su correo electronico es invalido',
"password.required"=>"La contraseña es requerida",
"confirmarpassword.required"=>"Es necesario confirmar la contraseña",
'confirmarpassword.same'=>'La contraseña no coincide',
"direccion.required"=>"La direccion es requerida",
"ciudad.required"=>"El nombre de la ciudad es requerido",
"rol.required"=>"El Rol es requerido",
"postal.required"=>"El codigo postal es requerido",
"postal.digits"=>"El codigo postal debe tener 5 digitos",
];
$validator = Validator::make($request->all(), $campos, $mensajes);
if ($validator->fails()) {
$errors = $validator->errors();
return response()->json([
'nombre'=> $errors->get('nombre'),
'primer'=> $errors->get('primer'),
'segundo'=> $errors->get('segundo'),
'email'=> $errors->get('email'),
'password'=> $errors->get('password'),
'confirmarpassword'=> $errors->get('confirmarpassword'),
'direccion'=> $errors->get('direccion'),
'ciudad'=> $errors->get('ciudad'),
'rol'=> $errors->get('rol'),
'postal'=> $errors->get('postal'),
'alerta' => 'danger'
]);
}
return response()->json([
"alerta"=>"success"
]);
}
}