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 developer

Primero 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"
            ]);
        }
    }
    
            
          

5 Imagen del formulario para registrar un nuevo usuario con Laravel ☟.

Video tutorial (Programando un buscador en tiempo real.)

Codigo fuente en GitHub