! Nouvelle version pour Laravel 5.2 !
On m'a souvent posé la question concernant la création d'un formulaire modal avec Bootstrap et également son interaction avec Laravel. Je vais donc dans cet article développer cet aspect en partant d'une installation toute fraiche de Laravel et en la modifiant un peu pour permettre l'enregistrement des utilisateurs à partir d'un formulaire modal.
Donc commencez par installer un Laravel 5.2 tout neuf par votre méthode préférée (l'installateur, composer...). Créez aussi une base de données pour que ça fonctionne. N'oubliez pas de changer le nom du fichier d'environnement (.env.example => .env) en mentionnant correctement les références de la base.
Vous devez vous retrouver avec le contrôleur pour l'authentification :
Comme Laravel 5.2 ne comporte pas les vues, routes et autres pour l'authentification il faut les générer avec la commande :
php artisan make:auth
Vous devez alors avoir ces vues :
Le contrôleur
Voici le code du contrôleur Authcontroller modifié :
<?php namespace App\Http\Controllers\Auth; use App\User; use Validator; use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\ThrottlesLogins; use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers; use Illuminate\Http\Request; class AuthController extends Controller { /* |-------------------------------------------------------------------------- | Registration & Login Controller |-------------------------------------------------------------------------- | | This controller handles the registration of new users, as well as the | authentication of existing users. By default, this controller uses | a simple trait to add these behaviors. Why don't you explore it? | */ use AuthenticatesAndRegistersUsers, ThrottlesLogins; /** * Where to redirect users after login / registration. * * @var string */ protected $redirectTo = '/'; /** * Create a new authentication controller instance. * * @return void */ public function __construct() { $this->middleware($this->guestMiddleware(), ['except' => 'logout']); } /** * Get a validator for an incoming registration request. * * @param array $data * @return \Illuminate\Contracts\Validation\Validator */ protected function validator(array $data) { return Validator::make($data, [ 'name' => 'required|max:255', 'email' => 'required|email|max:255|unique:users', 'password' => 'required|min:6|confirmed', ]); } /** * Create a new user instance after a valid registration. * * @param array $data * @return User */ protected function create(array $data) { return User::create([ 'name' => $data['name'], 'email' => $data['email'], 'password' => bcrypt($data['password']), ]); } /** * Handle a registration request for the application. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function register(Request $request) { $validator = $this->validator($request->all()); if ($validator->fails()) { $this->throwValidationException( $request, $validator ); } $this->create($request->all()); return response()->json(); } }
J'ai surchargé la méthode postRegister du trait pour changer le code en enlevant la connexion automatique et en renvoyant une réponse JSON. La validation tient compte du fait que la requête peut être en Ajax, donc en cas d'erreur de saisie on aura automatiquement un retour correct. Si tout va bien on crée l'utilisateur et on renvoie une réponse JSON vierge.
La vue app.blade.php
Voici le code complet de cette vue :<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Laravel</title> <!-- Fonts --> <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.4.0/css/font-awesome.min.css" rel='stylesheet' type='text/css'> <link href="https://fonts.googleapis.com/css?family=Lato:100,300,400,700" rel='stylesheet' type='text/css'> <!-- Styles --> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"> {{-- <link href="{{ elixir('css/app.css') }}" rel="stylesheet"> --}} <style> body { font-family: 'Lato'; } .fa-btn { margin-right: 6px; } </style> </head> <body id="app-layout"> <nav class="navbar navbar-default navbar-static-top"> <div class="container"> <div class="navbar-header"> <!-- Collapsed Hamburger --> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#app-navbar-collapse"> <span class="sr-only">Toggle Navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <!-- Branding Image --> <a class="navbar-brand" href="{{ url('/') }}"> Laravel </a> </div> <div class="collapse navbar-collapse" id="app-navbar-collapse"> <!-- Left Side Of Navbar --> <ul class="nav navbar-nav"> <li><a href="{{ url('/home') }}">Home</a></li> </ul> <!-- Right Side Of Navbar --> <ul class="nav navbar-nav navbar-right"> <!-- Authentication Links --> @if (Auth::guest()) <li><a href="{{ url('/login') }}">Login</a></li> <li><a href="#" id="register">Register</a></li> @else <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"> {{ Auth::user()->name }} <span class="caret"></span> </a> <ul class="dropdown-menu" role="menu"> <li><a href="{{ url('/logout') }}"><i class="fa fa-btn fa-sign-out"></i>Logout</a></li> </ul> </li> @endif </ul> </div> </div> </nav> <div class="container"> <div class="alert alert-success alert-dismissible hidden"> You are now registered, you can login. </div> </div> @yield('content') <!-- Modal --> <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <h4 class="modal-title" id="myModalLabel">Register</h4> </div> <div class="modal-body"> <form id="formRegister" class="form-horizontal" role="form" method="POST" action="{{ url('register') }}"> <input type="hidden" name="_token" value="{{ csrf_token() }}"> <div class="form-group"> <label class="col-md-4 control-label">Name</label> <div class="col-md-6"> <input type="text" class="form-control" name="name"> <small class="help-block"></small> </div> </div> <div class="form-group"> <label class="col-md-4 control-label">E-Mail Address</label> <div class="col-md-6"> <input type="email" class="form-control" name="email"> <small class="help-block"></small> </div> </div> <div class="form-group"> <label class="col-md-4 control-label">Password</label> <div class="col-md-6"> <input type="password" class="form-control" name="password"> <small class="help-block"></small> </div> </div> <div class="form-group"> <label class="col-md-4 control-label">Confirm Password</label> <div class="col-md-6"> <input type="password" class="form-control" name="password_confirmation"> </div> </div> <div class="form-group"> <div class="col-md-6 col-md-offset-4"> <button type="submit" class="btn btn-primary"> Register </button> </div> </div> </form> </div> </div> </div> </div> <!-- JavaScripts --> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> <script> $(function(){ $('#register').click(function() { $('#myModal').modal(); }); $(document).on('submit', '#formRegister', function(e) { e.preventDefault(); $('input+small').text(''); $('input').parent().removeClass('has-error'); $.ajax({ method: $(this).attr('method'), url: $(this).attr('action'), data: $(this).serialize(), dataType: "json" }) .done(function(data) { $('.alert-success').removeClass('hidden'); $('#myModal').modal('hide'); }) .fail(function(data) { $.each(data.responseJSON, function (key, value) { var input = '#formRegister input[name=' + key + ']'; $(input + '+small').text(value); $(input).parent().addClass('has-error'); }); }); }); }) </script> {{-- <script src="{{ elixir('js/app.js') }}"></script> --}} </body> </html>Nous allons analyser un peu tout ça...
Le formulaire
La première chose à prévoir est le formulaire d'enregistrement :
<!-- Modal --> <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <h4 class="modal-title" id="myModalLabel">Register</h4> </div> <div class="modal-body"> <form id="formRegister" class="form-horizontal" role="form" method="POST" action="{{ url('/auth/register') }}"> <input type="hidden" name="_token" value="{{ csrf_token() }}"> <div class="form-group"> <label class="col-md-4 control-label">Name</label> <div class="col-md-6"> <input type="text" class="form-control" name="name"> <small class="help-block"></small> </div> </div> <div class="form-group"> <label class="col-md-4 control-label">E-Mail Address</label> <div class="col-md-6"> <input type="email" class="form-control" name="email"> <small class="help-block"></small> </div> </div> <div class="form-group"> <label class="col-md-4 control-label">Password</label> <div class="col-md-6"> <input type="password" class="form-control" name="password"> <small class="help-block"></small> </div> </div> <div class="form-group"> <label class="col-md-4 control-label">Confirm Password</label> <div class="col-md-6"> <input type="password" class="form-control" name="password_confirmation"> </div> </div> <div class="form-group"> <div class="col-md-6 col-md-offset-4"> <button type="submit" class="btn btn-primary"> Register </button> </div> </div> </form> </div> </div> </div> </div>
A ce niveau il n'y a rien de bien particulier, c'est le code classique d'une page modale de Bootstrap.
Le Javascript
Voici le Javascript que j'ai prévu :@section('scripts') <script> $(function(){ $('#register').click(function() { $('#myModal').modal(); }); $(document).on('submit', '#formRegister', function(e) { e.preventDefault(); $('input+small').text(''); $('input').parent().removeClass('has-error'); $.ajax({ method: $(this).attr('method'), url: $(this).attr('action'), data: $(this).serialize(), dataType: "json" }) .done(function(data) { $('.alert-success').removeClass('hidden'); $('#myModal').modal('hide'); }) .fail(function(data) { $.each(data.responseJSON, function (key, value) { var input = '#formRegister input[name=' + key + ']'; $(input + '+small').text(value); $(input).parent().addClass('has-error'); }); }); }); }) </script> @endsection
La première chose est l'ouverture de la feuille modale lorsqu'on clique l'option Register de la barre de menu :
$('#register').click(function() { $('#myModal').modal(); });On a alors la présentation du formulaire modal :
On doit s'intéresser ensuite à la soumission :
$(document).on('submit', '#formRegister', function(e) { e.preventDefault(); $('input+small').text(''); $('input').parent().removeClass('has-error'); $.ajax({ method: $(this).attr('method'), url: $(this).attr('action'), data: $(this).serialize(), dataType: "json" }) .done(function(data) { // Action en cas de réussite }) .fail(function(data) { // Action en cas d'échec }); });
On commence par effacer les références éventuelles des erreurs précédentes et on lance la requête en Ajax.
En cas d'erreur dans la saisie on a :.fail(function(data) { $.each(data.responseJSON, function (key, value) { var input = '#formRegister input[name=' + key + ']'; $(input + '+small').text(value); $(input).parent().addClass('has-error'); }); });
On passe en revue toutes les erreurs et on les rend visibles sur le formulaire. On reçoit ce genre de JSON de la part du contrôleur :
{"name":["The name field is required."],"password":["The password field is required."]}Et donc cet aspect : Si la validation est correcte c'est ce code qui est activé :
.done(function(data) { $('.alert-success').removeClass('hidden'); $('#myModal').modal('hide'); })On rend visible la barre d'information pour l'utilisateur :
On pourrait adopter une autre stratégie en connectant directement l'utilisateur, là j'ai préféré l'obliger à entrer ses informations.
Pour terminer on cache la feuille modale et c'est terminé !
Par bestmomo
Nombre de commentaires : 9