mise a jours des pages du slider
This commit is contained in:
@@ -0,0 +1,74 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Ajouter un slide</title>
|
||||||
|
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background: #f4f6f9;
|
||||||
|
padding: 40px;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
max-width: 600px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<h2 class="text-center mb-4">Ajouter une image au slider</h2>
|
||||||
|
|
||||||
|
<!-- Erreur : image manquante -->
|
||||||
|
<div id="errorEmpty" class="alert alert-danger d-none">
|
||||||
|
Merci de sélectionner une image.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Erreur : format invalide -->
|
||||||
|
<div id="errorFormat" class="alert alert-danger d-none">
|
||||||
|
Format d'image invalide. Formats acceptés : JPG, PNG, WEBP.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Succès -->
|
||||||
|
<div id="successMsg" class="alert alert-success d-none">
|
||||||
|
Slide ajouté avec succès !
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form id="addSlideForm">
|
||||||
|
|
||||||
|
<!-- Image -->
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label fw-bold">Image du slide (obligatoire)</label>
|
||||||
|
<input type="file" id="slideImage" class="form-control" accept="image/*">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ALT -->
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label fw-bold">Texte ALT (obligatoire)</label>
|
||||||
|
<input type="text" id="slideAlt" class="form-control" placeholder="Description de l’image">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Titre -->
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label fw-bold">Titre (optionnel)</label>
|
||||||
|
<input type="text" id="slideTitle" class="form-control">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Boutons -->
|
||||||
|
<div class="d-flex gap-3 mt-4">
|
||||||
|
<a href="../../../slider/liste_slider/liste_slider.html" class="btn btn-secondary w-50">Annuler</a>
|
||||||
|
<button type="submit" class="btn btn-primary w-50">Ajouter</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="ajouter_slider.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
const form = document.getElementById('addSlideForm');
|
||||||
|
const imgField = document.getElementById('slideImage');
|
||||||
|
const altField = document.getElementById('slideAlt');
|
||||||
|
const titleField = document.getElementById('slideTitle');
|
||||||
|
|
||||||
|
const errorEmpty = document.getElementById('errorEmpty');
|
||||||
|
const errorFormat = document.getElementById('errorFormat');
|
||||||
|
const successMsg = document.getElementById('successMsg');
|
||||||
|
|
||||||
|
// Création du tableau simulant la BDD
|
||||||
|
let slides = [];
|
||||||
|
|
||||||
|
form.addEventListener('submit', function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
// Reset messages
|
||||||
|
errorEmpty.classList.add('d-none');
|
||||||
|
errorFormat.classList.add('d-none');
|
||||||
|
successMsg.classList.add('d-none');
|
||||||
|
|
||||||
|
const image = imgField.files[0];
|
||||||
|
const alt = altField.value.trim();
|
||||||
|
|
||||||
|
// Image obligatoire
|
||||||
|
if (!image) {
|
||||||
|
errorEmpty.textContent = "Merci de sélectionner une image.";
|
||||||
|
errorEmpty.classList.remove('d-none');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ALT obligatoire
|
||||||
|
if (alt === "") {
|
||||||
|
errorEmpty.textContent = "Le texte ALT est obligatoire.";
|
||||||
|
errorEmpty.classList.remove('d-none');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vérification format
|
||||||
|
const validFormats = ["image/jpeg", "image/png", "image/webp"];
|
||||||
|
if (!validFormats.includes(image.type)) {
|
||||||
|
errorFormat.classList.remove('d-none');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enregistrement simulé
|
||||||
|
slides.push({
|
||||||
|
id: Date.now(),
|
||||||
|
image: image.name,
|
||||||
|
alt: alt,
|
||||||
|
title: titleField.value.trim(),
|
||||||
|
order: slides.length + 1
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("Nouveau slide ajouté :", slides);
|
||||||
|
|
||||||
|
// Succès
|
||||||
|
successMsg.classList.remove('d-none');
|
||||||
|
|
||||||
|
// Redirection
|
||||||
|
setTimeout(() => {
|
||||||
|
window.location.href = "../../../slider/liste_slider/liste_slider.html";
|
||||||
|
}, 1500);
|
||||||
|
});
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Liste des slides</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background: #f4f6f9;
|
||||||
|
padding: 40px;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
max-width: 900px;
|
||||||
|
}
|
||||||
|
.miniature {
|
||||||
|
width: 90px;
|
||||||
|
height: 60px;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
.action-buttons button,
|
||||||
|
.action-buttons a {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<h2 class="text-center mb-4">Slider – Liste des images</h2>
|
||||||
|
|
||||||
|
<!-- Message succès (suppression / ordre) -->
|
||||||
|
<div id="successMsg" class="alert alert-success d-none"></div>
|
||||||
|
|
||||||
|
<!-- Bouton ajouter -->
|
||||||
|
<div class="d-flex justify-content-end mb-4">
|
||||||
|
<a href="../../slider/liste_slider/ajouter_slider/ajouter_slider.html" class="btn btn-primary">Ajouter une image au slider</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="table table-striped table-hover align-middle">
|
||||||
|
<thead class="table-dark">
|
||||||
|
<tr>
|
||||||
|
<th>Image</th>
|
||||||
|
<th>Texte ALT</th>
|
||||||
|
<th>Titre</th>
|
||||||
|
<th>Ordre</th>
|
||||||
|
<th class="text-center">Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody id="sliderTableBody">
|
||||||
|
<!-- rempli en JS -->
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="liste_slider.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
// Simulation BDD slider
|
||||||
|
let slides = [
|
||||||
|
{ id: 1, image: "slide1.webp", alt: "Chien toiletté", title: "Promo du mois", order: 1 },
|
||||||
|
{ id: 2, image: "slide2.webp", alt: "Avant / Après", title: "", order: 2 },
|
||||||
|
{ id: 3, image: "slide3.webp", alt: "Coupe ciseaux", title: "Nouveauté", order: 3 }
|
||||||
|
];
|
||||||
|
|
||||||
|
const tableBody = document.getElementById("sliderTableBody");
|
||||||
|
const successMsg = document.getElementById("successMsg");
|
||||||
|
|
||||||
|
function afficherSlides() {
|
||||||
|
|
||||||
|
// trier par ordre
|
||||||
|
slides.sort((a, b) => a.order - b.order);
|
||||||
|
|
||||||
|
tableBody.innerHTML = "";
|
||||||
|
|
||||||
|
slides.forEach((slide, index) => {
|
||||||
|
const row = `
|
||||||
|
<tr>
|
||||||
|
<td><img src="#" alt="${slide.alt}" class="miniature"></td>
|
||||||
|
|
||||||
|
<td>${slide.alt}</td>
|
||||||
|
<td>${slide.title || "-"}</td>
|
||||||
|
<td>${slide.order}</td>
|
||||||
|
|
||||||
|
<td class="text-center action-buttons">
|
||||||
|
<button class="btn btn-secondary btn-sm" onclick="monter(${index})">↑</button>
|
||||||
|
<button class="btn btn-secondary btn-sm" onclick="descendre(${index})">↓</button>
|
||||||
|
|
||||||
|
<a href="../../slider/liste_slider/modifier_slider/modifier_slider.html?id=${slide.id}"
|
||||||
|
class="btn btn-warning btn-sm">Modifier</a>
|
||||||
|
|
||||||
|
|
||||||
|
<button class="btn btn-danger btn-sm" onclick="supprimerSlide(${index})">Supprimer</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
`;
|
||||||
|
tableBody.innerHTML += row;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
afficherSlides();
|
||||||
|
|
||||||
|
// Suppression
|
||||||
|
function supprimerSlide(index) {
|
||||||
|
if (confirm("Voulez-vous vraiment supprimer cette image du slider ?")) {
|
||||||
|
slides.splice(index, 1);
|
||||||
|
|
||||||
|
// Réordonner après suppression
|
||||||
|
slides.forEach((s, i) => s.order = i + 1);
|
||||||
|
|
||||||
|
afficherSlides();
|
||||||
|
|
||||||
|
successMsg.textContent = "Image du slider supprimée avec succès.";
|
||||||
|
successMsg.classList.remove("d-none");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Monter
|
||||||
|
function monter(index) {
|
||||||
|
if (index === 0) return; // déjà en haut
|
||||||
|
|
||||||
|
[slides[index - 1], slides[index]] = [slides[index], slides[index - 1]];
|
||||||
|
|
||||||
|
// recalcul ordre
|
||||||
|
slides.forEach((s, i) => s.order = i + 1);
|
||||||
|
|
||||||
|
afficherSlides();
|
||||||
|
|
||||||
|
successMsg.textContent = "Ordre mis à jour.";
|
||||||
|
successMsg.classList.remove("d-none");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Descendre
|
||||||
|
function descendre(index) {
|
||||||
|
if (index === slides.length - 1) return; // déjà en bas
|
||||||
|
|
||||||
|
[slides[index], slides[index + 1]] = [slides[index + 1], slides[index]];
|
||||||
|
|
||||||
|
slides.forEach((s, i) => s.order = i + 1);
|
||||||
|
|
||||||
|
afficherSlides();
|
||||||
|
|
||||||
|
successMsg.textContent = "Ordre mis à jour.";
|
||||||
|
successMsg.classList.remove("d-none");
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Modifier un slide</title>
|
||||||
|
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background: #f4f6f9;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
max-width: 600px;
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
.miniature {
|
||||||
|
width: 150px;
|
||||||
|
height: 90px;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<h2 class="text-center mb-5">Modifier une image du slider</h2>
|
||||||
|
|
||||||
|
<!-- Messages -->
|
||||||
|
<div id="errorMsg" class="alert alert-danger d-none"></div>
|
||||||
|
<div id="successMsg" class="alert alert-success d-none">Slide modifié avec succès !</div>
|
||||||
|
|
||||||
|
<form id="editSlideForm">
|
||||||
|
|
||||||
|
<!-- Image actuelle -->
|
||||||
|
<div class="mb-5">
|
||||||
|
<label class="form-label fw-bold">Image actuelle :</label><br>
|
||||||
|
<img id="currentImage" src="#" alt="Image actuelle" class="miniature">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Remplacer l’image -->
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label fw-bold">Nouvelle image (optionnel) :</label>
|
||||||
|
<input type="file" id="newImage" class="form-control" accept="image/*">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Texte ALT -->
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label fw-bold">Texte alternatif (obligatoire)</label>
|
||||||
|
<input type="text" id="slideAlt" class="form-control">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Titre -->
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label fw-bold">Titre du slide (optionnel)</label>
|
||||||
|
<input type="text" id="slideTitle" class="form-control">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Boutons -->
|
||||||
|
<div class="d-flex gap-3 mt-4">
|
||||||
|
<a href="../liste_slider/liste_slider.html" class="btn btn-secondary w-50">Annuler</a>
|
||||||
|
<button type="submit" class="btn btn-primary w-50">Enregistrer</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="modifier_slider.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
// Simuler la BDD slider
|
||||||
|
let slides = [
|
||||||
|
{ id: 1, image: "slide1.webp", alt: "Chien toiletté", title: "Promo du mois", order: 1 },
|
||||||
|
{ id: 2, image: "slide2.webp", alt: "Avant / Après", title: "", order: 2 },
|
||||||
|
{ id: 3, image: "slide3.webp", alt: "Coupe ciseaux", title: "Nouveauté", order: 3 }
|
||||||
|
];
|
||||||
|
|
||||||
|
// --- Sélections elements HTML ---
|
||||||
|
const form = document.getElementById("editSlideForm");
|
||||||
|
const currentImage = document.getElementById("currentImage");
|
||||||
|
const newImage = document.getElementById("newImage");
|
||||||
|
const altField = document.getElementById("slideAlt");
|
||||||
|
const titleField = document.getElementById("slideTitle");
|
||||||
|
|
||||||
|
const errorMsg = document.getElementById("errorMsg");
|
||||||
|
const successMsg = document.getElementById("successMsg");
|
||||||
|
|
||||||
|
// --- Récupérer l’ID dans l’URL ---
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const slideId = parseInt(urlParams.get("id"));
|
||||||
|
|
||||||
|
// Trouver le slide correspondant
|
||||||
|
let slide = slides.find(s => s.id === slideId);
|
||||||
|
|
||||||
|
if (!slide) {
|
||||||
|
errorMsg.classList.remove("d-none");
|
||||||
|
errorMsg.textContent = "Slide introuvable.";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pré-remplir les champs
|
||||||
|
currentImage.src = "#";
|
||||||
|
altField.value = slide.alt;
|
||||||
|
titleField.value = slide.title;
|
||||||
|
|
||||||
|
|
||||||
|
// --- Validation + modification ---
|
||||||
|
form.addEventListener("submit", function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
errorMsg.classList.add("d-none");
|
||||||
|
successMsg.classList.add("d-none");
|
||||||
|
|
||||||
|
// Vérifier ALT obligatoire
|
||||||
|
if (altField.value.trim() === "") {
|
||||||
|
errorMsg.textContent = "Le texte ALT est obligatoire.";
|
||||||
|
errorMsg.classList.remove("d-none");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vérifier la nouvelle image si elle existe
|
||||||
|
if (newImage.files.length > 0) {
|
||||||
|
const file = newImage.files[0];
|
||||||
|
const validFormats = ["image/jpeg", "image/png", "image/webp"];
|
||||||
|
|
||||||
|
if (!validFormats.includes(file.type)) {
|
||||||
|
errorMsg.textContent = "Format d'image invalide. JPG, PNG et WEBP acceptés.";
|
||||||
|
errorMsg.classList.remove("d-none");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simuler remplacement de l’image
|
||||||
|
slide.image = file.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mettre à jour les données
|
||||||
|
slide.alt = altField.value.trim();
|
||||||
|
slide.title = titleField.value.trim();
|
||||||
|
|
||||||
|
successMsg.classList.remove("d-none");
|
||||||
|
|
||||||
|
console.log("Slide modifié :", slide);
|
||||||
|
|
||||||
|
// Redirection après succès
|
||||||
|
setTimeout(() => {
|
||||||
|
window.location.href = "../liste_slider/liste_slider.html";
|
||||||
|
}, 1500);
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user