header-actions.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // Actions du header (souris, boutons)
  2. (function() {
  3. document.addEventListener('DOMContentLoaded', function() {
  4. // Bouton Charger: demander un ID et naviguer vers ?load=ID
  5. const loadBtn = document.getElementById('loadBtn');
  6. if (loadBtn) {
  7. // Rediriger vers la liste des projets
  8. loadBtn.addEventListener('click', function(e) {
  9. e.preventDefault();
  10. window.location.href = '/projects';
  11. });
  12. }
  13. // Initialiser les dropdown Bootstrap si disponible (résout les dropdown qui ne s'ouvrent pas)
  14. try {
  15. if (window.bootstrap && window.bootstrap.Dropdown) {
  16. const toggles = document.querySelectorAll('[data-bs-toggle="dropdown"]');
  17. toggles.forEach(function(toggle) {
  18. // Crée une instance si nécessaire
  19. if (!bootstrap.Dropdown.getInstance(toggle)) {
  20. new bootstrap.Dropdown(toggle);
  21. }
  22. });
  23. }
  24. } catch (err) {
  25. // ne pas casser l'exécution si bootstrap absent
  26. console.warn('Bootstrap dropdown init failed:', err);
  27. }
  28. // Fallback manuel : si le dropdown ne fonctionne pas (ex: conflits), on gère l'ouverture/fermeture
  29. (function() {
  30. const toggles = Array.from(document.querySelectorAll('[data-bs-toggle="dropdown"]'));
  31. if (!toggles.length) return;
  32. function closeAll() {
  33. document.querySelectorAll('.dropdown-menu.show').forEach(function(menu) {
  34. menu.classList.remove('show');
  35. });
  36. toggles.forEach(function(t) { t.setAttribute('aria-expanded', 'false'); });
  37. }
  38. // Clic sur toggle : bascule l'affichage
  39. toggles.forEach(function(toggle) {
  40. toggle.addEventListener('click', function(e) {
  41. // Si Bootstrap gère déjà l'événement, laisser faire
  42. try {
  43. if (window.bootstrap && window.bootstrap.Dropdown && bootstrap.Dropdown.getInstance(toggle)) {
  44. return; // bootstrap gère
  45. }
  46. } catch (_) {}
  47. e.preventDefault();
  48. e.stopPropagation();
  49. const parent = toggle.closest('.dropdown') || toggle.parentElement;
  50. const menu = parent ? parent.querySelector('.dropdown-menu') : null;
  51. if (!menu) return;
  52. const isOpen = menu.classList.contains('show');
  53. closeAll();
  54. if (!isOpen) {
  55. menu.classList.add('show');
  56. toggle.setAttribute('aria-expanded', 'true');
  57. // Ajuster la position pour qu'il soit entièrement visible
  58. adjustDropdownMenu(menu, toggle);
  59. }
  60. });
  61. });
  62. // Fermer au clic en dehors
  63. document.addEventListener('click', function() {
  64. closeAll();
  65. });
  66. })();
  67. // Ajuste la position/hauteur d'un menu dropdown pour qu'il tienne dans la fenêtre
  68. function adjustDropdownMenu(menu, toggle) {
  69. if (!menu) return;
  70. // Reset des styles précédents
  71. menu.style.maxHeight = '';
  72. menu.classList.remove('dropdown-menu-end');
  73. const rect = menu.getBoundingClientRect();
  74. const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
  75. const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0);
  76. // Si déborde à droite -> aligner à droite du toggle (ajouter dropdown-menu-end)
  77. if (rect.right > vw - 8) {
  78. menu.classList.add('dropdown-menu-end');
  79. }
  80. // Recalculer après changement éventuel
  81. const rect2 = menu.getBoundingClientRect();
  82. // Si déborde en bas -> limiter la hauteur et activer scroll
  83. if (rect2.bottom > vh - 8) {
  84. const available = vh - 16 - rect2.top; // garder un petit padding
  85. if (available > 100) {
  86. menu.style.maxHeight = available + 'px';
  87. menu.style.overflowY = 'auto';
  88. }
  89. }
  90. }
  91. // Si Bootstrap est présent, utiliser l'événement show pour ajuster
  92. if (window.bootstrap && window.bootstrap.Dropdown) {
  93. document.querySelectorAll('[data-bs-toggle="dropdown"]').forEach(function(toggle) {
  94. toggle.addEventListener('show.bs.dropdown', function(e) {
  95. const parent = toggle.closest('.dropdown') || toggle.parentElement;
  96. const menu = parent ? parent.querySelector('.dropdown-menu') : null;
  97. if (menu) adjustDropdownMenu(menu, toggle);
  98. });
  99. });
  100. }
  101. });
  102. })();