Chapitre 5.3 : Intégration de JavaScript dans les vues Laravel
Temps d'étude : 50 minutes
1. Deux approches de JavaScript sur le web
Jusqu'à présent, nous avons travaillé avec le Server-Side Rendering (SSR) — le serveur (Laravel) générait le HTML prêt (via Blade) et l'envoyait au navigateur. C'est excellent pour le SEO et un premier chargement rapide.
Maintenant, nous allons ajouter des Client-Side Interactions — le navigateur, une fois la page chargée, exécutera du code JavaScript pour :
- Envoyer des requêtes à notre API sans recharger la page.
- Mettre à jour dynamiquement des parties de la page (par exemple, ajouter une nouvelle planète à la liste).
- Afficher des notifications et des fenêtres modales.
💡 Analogie spatiale :
Imaginez que le SSR est l'obtention d'une carte complète d'un système stellaire, imprimée au centre de contrôle (serveur). Vous voyez tous les objets au moment de l'impression.
Le Client-Side JS est votre tablette personnelle (navigateur) qui se connecte en temps réel aux satellites (API) et met à jour la position des objets sur votre carte, sans demander une nouvelle carte papier au centre de contrôle.
2. Où stocker et comment inclure le code JS
Comme nous l'avons déjà établi, tous les actifs publics (CSS, JS, images) doivent se trouver dans le dossier public
.
Structure correcte :
- Fichiers source : Tout votre code JS principal doit se trouver dans
public/js/
. Par exemple,public/js/planets.js
. - Inclusion dans Blade : Utilisez l'aideur
asset()
pour générer l'URL correcte.
Exemple d'inclusion dans le gabarit layouts/app.blade.php
:
<!DOCTYPE html>
<html>
<head>
{{-- ... --}}
</head>
<body>
{{-- ... header et main ... --}}
<footer>
<p>© {{ date('Y') }} Space Command.</p>
</footer>
{{-- Il est préférable d'inclure les scripts à la fin du corps pour accélérer le rendu de la page --}}
<script src="{{ asset('js/planets.js') }}"></script>
@stack('scripts') {{-- Nous créons un "slot" pour les scripts d'une page spécifique --}}
</body>
</html>
@stack('scripts')
est une directive Blade puissante. Elle permet aux vues enfants de "pousser" leur propre code JS à cet endroit. C'est utile lorsqu'une page nécessite un script unique et qu'une autre non.
3. Exemple : Bouton "Supprimer" avec confirmation
Ajoutons un bouton "Supprimer" pour chaque planète sur la page de liste des planètes (planets/index.blade.php
), qui fonctionnera via JavaScript et l'API Fetch.
Étape 1 : Ajout du bouton dans resources/views/planets/index.blade.php
Modifiez la carte de la planète en ajoutant un bouton avec des attributs data :
{{-- ... à l'intérieur de la boucle @forelse ... --}}
<div class="planet-card" id="planet-card-{{ $planet->id }}">
<h3>{{ $planet->name }}</h3>
<p>Système solaire : {{ $planet->solar_system }}</p>
<p>Diamètre : {{ number_format($planet->size_km, 0, '.', ' ') }} km</p>
<a href="/planets/{{ $planet->id }}">En savoir plus →</a>
<button class="delete-btn" data-id="{{ $planet->id }}" data-url="/api/planets/{{ $planet->id }}">
Désaffecter
</button>
</div>
<!-- ... Avant la balise de fermeture body ... -->
<script src="{{ asset('js/planets.js') }}" defer></script>
id="planet-card-{{ $planet->id }}"
— ID unique pour toute la carte, afin que nous puissions la supprimer du DOM.data-id
etdata-url
— un moyen pratique de transmettre des données de PHP (Blade) à JavaScript.
Étape 2 : Écriture de la logique JavaScript
Créez le fichier public/js/planets.js
et ajoutez-y le code suivant :
document.addEventListener('DOMContentLoaded', () => {
// Trouver tous les boutons "Supprimer"
const deleteButtons = document.querySelectorAll('.delete-btn');
deleteButtons.forEach(button => {
button.addEventListener('click', async (event) => {
const planetId = event.target.dataset.id;
const apiUrl = event.target.dataset.url;
if (!confirm(`Êtes-vous sûr de vouloir désaffecter la planète avec l'ID ${planetId} ? Cette action est irréversible.`)) {
return; // L'utilisateur a cliqué sur "Annuler"
}
try {
// Envoyer une requête DELETE à notre API
const response = await fetch(apiUrl, {
method: 'DELETE',
headers: {
'Accept': 'application/json',
// Plus tard, nous ajouterons le jeton CSRF ici
}
});
if (response.status === 204) { // 204 No Content - suppression réussie
// Supprimer la carte de la planète de la page
const cardToRemove = document.getElementById(`planet-card-${planetId}`);
if (cardToRemove) {
cardToRemove.remove();
}
alert('La planète a été désaffectée avec succès.');
} else {
// Si l'API a renvoyé une erreur
const errorData = await response.json();
alert(`Erreur : ${errorData.message || 'Impossible de supprimer la planète.'}`);
}
} catch (error) {
console.error('Erreur lors de l\'envoi de la requête :', error);
alert('Une erreur réseau est survenue. Veuillez réessayer.');
}
});
});
});
Maintenant, si vous rafraîchissez la page /planets
, vous verrez les boutons "Désaffecter", et en cliquant dessus, notre code JavaScript se déclenchera !
4. Transmission de données de Blade vers JavaScript
Parfois, il est nécessaire de transmettre à JS non pas une simple chaîne de caractères, mais un tableau ou un objet entier.
Méthode incorrecte (vulnérable) :
Méthode correcte (via JSON) :
Utilisez la directive @json
. Elle convertit en toute sécurité un tableau/objet PHP en un objet JSON valide.
Exemple dans planets/index.blade.php
:
@extends('layouts.app')
{{-- ... --}}
@section('content')
{{-- ... --}}
@endsection
@push('scripts') {{-- Nous "poussons" notre script dans le slot @stack('scripts') du gabarit --}}
<script>
// Laravel convertit en toute sécurité la collection $planets en un tableau JSON
const planetsData = @json($planets);
// Maintenant, nous pouvons travailler avec ce tableau en JS
console.log('Données sur les planètes transmises depuis Blade :', planetsData);
alert(`${planetsData.length} planètes chargées !`);
</script>
@endpush
@push('scripts')
place le contenu à l'intérieur de@stack('scripts')
danslayouts/app.blade.php
. Cela permet d'ajouter des scripts uniquement aux pages où ils sont réellement nécessaires.
Quiz de consolidation
🚀 Conclusion du chapitre :
Vous avez appris à donner vie aux pages Blade statiques en ajoutant de la logique côté client. Compétences clés :
- Organisation et inclusion correctes des fichiers JS dans un projet Laravel.
- Utilisation des attributs
data-*
pour transmettre des données de HTML à JS. - Interaction dynamique avec l'API via Fetch sans rechargement de page.
- Transmission sécurisée des variables PHP à JavaScript à l'aide de la directive
@json
. - Organisation des scripts avec
@push
et@stack
. Vos "panneaux de contrôle" sont devenus interactifs. Cependant, nos requêtes de modification (POST, PUT, DELETE) sont désormais vulnérables. Dans le chapitre suivant, nous ajouterons un mécanisme de protection crucial : les jetons CSRF.