| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- // Actions du header (souris, boutons)
- (function() {
- document.addEventListener('DOMContentLoaded', function() {
- // Bouton Charger: demander un ID et naviguer vers ?load=ID
- const loadBtn = document.getElementById('loadBtn');
- if (loadBtn) {
- // Rediriger vers la liste des projets
- loadBtn.addEventListener('click', function(e) {
- e.preventDefault();
- window.location.href = '/projects';
- });
- }
- // Initialiser les dropdown Bootstrap si disponible (résout les dropdown qui ne s'ouvrent pas)
- try {
- if (window.bootstrap && window.bootstrap.Dropdown) {
- const toggles = document.querySelectorAll('[data-bs-toggle="dropdown"]');
- toggles.forEach(function(toggle) {
- // Crée une instance si nécessaire
- if (!bootstrap.Dropdown.getInstance(toggle)) {
- new bootstrap.Dropdown(toggle);
- }
- });
- }
- } catch (err) {
- // ne pas casser l'exécution si bootstrap absent
- console.warn('Bootstrap dropdown init failed:', err);
- }
- // Fallback manuel : si le dropdown ne fonctionne pas (ex: conflits), on gère l'ouverture/fermeture
- (function() {
- const toggles = Array.from(document.querySelectorAll('[data-bs-toggle="dropdown"]'));
- if (!toggles.length) return;
- function closeAll() {
- document.querySelectorAll('.dropdown-menu.show').forEach(function(menu) {
- menu.classList.remove('show');
- });
- toggles.forEach(function(t) { t.setAttribute('aria-expanded', 'false'); });
- }
- // Clic sur toggle : bascule l'affichage
- toggles.forEach(function(toggle) {
- toggle.addEventListener('click', function(e) {
- // Si Bootstrap gère déjà l'événement, laisser faire
- try {
- if (window.bootstrap && window.bootstrap.Dropdown && bootstrap.Dropdown.getInstance(toggle)) {
- return; // bootstrap gère
- }
- } catch (_) {}
- e.preventDefault();
- e.stopPropagation();
- const parent = toggle.closest('.dropdown') || toggle.parentElement;
- const menu = parent ? parent.querySelector('.dropdown-menu') : null;
- if (!menu) return;
- const isOpen = menu.classList.contains('show');
- closeAll();
- if (!isOpen) {
- menu.classList.add('show');
- toggle.setAttribute('aria-expanded', 'true');
- // Ajuster la position pour qu'il soit entièrement visible
- adjustDropdownMenu(menu, toggle);
- }
- });
- });
- // Fermer au clic en dehors
- document.addEventListener('click', function() {
- closeAll();
- });
- })();
- // Ajuste la position/hauteur d'un menu dropdown pour qu'il tienne dans la fenêtre
- function adjustDropdownMenu(menu, toggle) {
- if (!menu) return;
- // Reset des styles précédents
- menu.style.maxHeight = '';
- menu.classList.remove('dropdown-menu-end');
- const rect = menu.getBoundingClientRect();
- const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
- const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0);
- // Si déborde à droite -> aligner à droite du toggle (ajouter dropdown-menu-end)
- if (rect.right > vw - 8) {
- menu.classList.add('dropdown-menu-end');
- }
- // Recalculer après changement éventuel
- const rect2 = menu.getBoundingClientRect();
- // Si déborde en bas -> limiter la hauteur et activer scroll
- if (rect2.bottom > vh - 8) {
- const available = vh - 16 - rect2.top; // garder un petit padding
- if (available > 100) {
- menu.style.maxHeight = available + 'px';
- menu.style.overflowY = 'auto';
- }
- }
- }
- // Si Bootstrap est présent, utiliser l'événement show pour ajuster
- if (window.bootstrap && window.bootstrap.Dropdown) {
- document.querySelectorAll('[data-bs-toggle="dropdown"]').forEach(function(toggle) {
- toggle.addEventListener('show.bs.dropdown', function(e) {
- const parent = toggle.closest('.dropdown') || toggle.parentElement;
- const menu = parent ? parent.querySelector('.dropdown-menu') : null;
- if (menu) adjustDropdownMenu(menu, toggle);
- });
- });
- }
- });
- })();
|