Un jolie système de notifications avec SweetAlert2
Tutoriel Symfony 6 - Un jolie système de notifications avec SweetAlert2
À propos de ce tutoriel
Je vous montre comment intégrer la librarie SweetAlert2 dans un projet Symfony 6 à travers plusieurs exemples concrets.
Création du projet
Dans un premier temps, il nous faut créer le projet :
symfony console new sweet_alert --webapp
Création du contrôleur HomeController
Nous allons créer notre unique contrôleur : HomeController.php.
C’est ici que nous allons implémenter nos routes afin de tester SweetAlert2.
symfony console make:controller Home
class HomeController extends AbstractController
{
const SAFE_DEPOSIT_BOX_PASSWORD = 'TEST_1234';
#[Route('/', name: 'app_home')]
public function index(): Response
{
return $this->render('home/index.html.twig');
}
#[Route('/safe-deposit-box', name: 'app_safe_deposit_box')]
public function safeDepositBox(Request $request): Response
{
$password = $request->request->get('password');
return $this->json([
'result' => $password === self::SAFE_DEPOSIT_BOX_PASSWORD
]);
}
}
Création de nos vues Twig
{% extends 'base.html.twig' %}
{% block title %}Accueil{% endblock %}
{% block body %}
<div class="container my-5">
<div class="row">
<div class="col-xl-4 mb-5">
{% include 'home/_card.html.twig'
with {
'header': 'Coffre-fort',
'text': 'Le coffre-fort est protégé par un mot de passe',
'buttonClass': 'safeDepositBoxBtn',
'buttonText': 'Accéder au coffre-fort'
} %}
</div>
<div class="col-xl-4 mb-5">
{% include 'home/_card.html.twig'
with {
'header': "S'inscrire",
'text': 'Inscription gratuite',
'buttonClass': 'registerBtn',
'buttonText': "S'inscrire"
} %}
</div>
<div class="col-xl-4">
{% include 'home/_card.html.twig'
with {
'header': "Changer la couleur de l'arrière-plan",
'text': "Changer la couleur de l'arrière-plan",
'buttonClass': 'changeBackgroundColorBtn',
'buttonText': "Changer la couleur"
} %}
</div>
</div>
</div>
{% include 'home/_template.html.twig' %}
{% endblock %}
<div class="card text-center">
<div class="card-header">
{{ header }}
</div>
<div class="card-body">
<p class="card-text">{{ text }}</p>
<a href="#" class="btn btn-primary {{ buttonClass }}">{{ buttonText }}</a>
</div>
</div>
<template id="bg-color-template">
<swal-title>Choisis une couleur</swal-title>
<swal-icon type="question"></swal-icon>
<swal-button type="confirm">Confirmer</swal-button>
<swal-input type="text" placeholder="#fff"></swal-input>
</template>
Le code JavaScript
import '../css/app.scss';
import Swal from 'sweetalert2'
document.addEventListener('DOMContentLoaded', async () => {
new App();
});
class App {
/**
* @type {HTMLElement}
*/
body;
/**
* @type {HTMLButtonElement}
*/
safeDepositBoxBtn;
/**
* @type {HTMLButtonElement}
*/
registerBtn;
/**
* @type {HTMLButtonElement}
*/
changeBackgroundColorBtn;
constructor() {
this.body = document.body;
this.safeDepositBoxBtn = document.querySelector('.safeDepositBoxBtn');
this.registerBtn = document.querySelector('.registerBtn');
this.changeBackgroundColorBtn = document.querySelector('.changeBackgroundColorBtn');
this.safeDepositBoxBtn.addEventListener('click', async () => {
await this.openSafeDepositBox();
});
this.registerBtn.addEventListener('click', async () => {
await this.register();
});
this.changeBackgroundColorBtn.addEventListener('click', async () => {
this.body.style.backgroundColor = await this.changeBackgroundColor()
});
}
async openSafeDepositBox() {
const {value: password} = await Swal.fire({
title: 'Ouverture du coffre-fort',
confirmButtonText: 'Ouvrir',
input: 'password',
inputLabel: 'Mot de passe',
inputPlaceholder: 'Entre le mot de passe du coffre-fort',
inputAttributes: {
minLength: 3,
maxlength: 10,
autocapitalize: 'off',
autocorrect: 'off',
required: true
},
validationMessage: 'Le mot de passe doit contenir entre 3 et 10 caractères !'
});
if (!password) {
return;
}
const formData = new FormData();
formData.append('password', password);
const response = await fetch('/safe-deposit-box', {
body: formData,
method: 'POST'
});
const data = await response.json();
if (data.result) {
await Swal.fire({
title: 'Félicitations',
text: 'Le coffre est ouvert !',
icon: 'success',
confirmButtonColor: 'green'
});
} else {
await Swal.fire({
title: 'Erreur',
text: "Ce n'est pas le bon mot de passe !",
icon: 'error',
confirmButtonColor: 'red'
});
}
}
async register() {
const Toast = Swal.mixin({
toast: true,
position: 'top-end',
showConfirmButton: false,
timer: 3000,
timerProgressBar: true,
didOpen: (toast) => {
toast.addEventListener('mouseenter', Swal.stopTimer)
toast.addEventListener('mouseleave', Swal.resumeTimer)
}
})
await Toast.fire({
icon: 'success',
title: 'Inscription réussie'
})
}
async changeBackgroundColor() {
const {value: color} = await Swal.fire({
template: '#bg-color-template',
inputAttributes: {
minLength: 4,
maxlength: 7,
required: true
},
validationMessage: "Il ne s'agit pas d'une couleur hexadecimal !"
});
return color;
}
}