From 1bcaf05da4038e23b1dabb2545392904e95b76d5 Mon Sep 17 00:00:00 2001 From: ouidade Date: Thu, 22 May 2025 13:50:45 +0200 Subject: [PATCH] views resources --- web/themes/custom/eql/dist/assets/bundle.js | 2 +- .../custom/eql/dist/assets/css/bundle.css | 6 + web/themes/custom/eql/eql.theme | 52 +- web/themes/custom/eql/scripts/main.js | 487 ++++++------------ .../custom/eql/scss/pages/ressources.scss | 11 + .../views-view-unformatted.html.twig | 4 +- .../custom/eql/templates/views-view.html.twig | 11 +- 7 files changed, 227 insertions(+), 346 deletions(-) diff --git a/web/themes/custom/eql/dist/assets/bundle.js b/web/themes/custom/eql/dist/assets/bundle.js index 63bcd3b..893bc41 100644 --- a/web/themes/custom/eql/dist/assets/bundle.js +++ b/web/themes/custom/eql/dist/assets/bundle.js @@ -36,7 +36,7 @@ eval("/**\n * @file\n * External links js file.\n */\n\n (function ($, Drupal, d \*************************/ /***/ (function() { -eval("\nconsole.log('salut');\n// menu burger open\n\nvar burger = document.getElementById(\"block-burger\");\nvar burgertitle = document.getElementById(\"block-burger-menu\");\n\n\nburgertitle.addEventListener(\"click\", toggleMenu);\n\nfunction toggleMenu(event) {\n // console.log(event);\n burger.classList.toggle('opened');\n}\n\n//////////////////////////\n// faq reponse open \n\nvar answers = document.getElementsByClassName(\"field--name-field-reponse\");\nvar fichiers = document.getElementsByClassName(\"field--name-field-fichiers\");\nvar questions = document.getElementsByClassName(\"field--name-field-question\");\n\nfor (let i = 0; i < questions.length; i++) {\n const question = questions[i]\n question.addEventListener(\"click\", toggleFaq);\n}\nfunction toggleFaq(event) {\n // console.log(event, this);\n // fermé tout\n for (let i = 0; i < answers.length; i++) {\n answers[i].classList.remove('opened'); \n }\n // la réponse correspndante a la question clické\n // | this c'est l'élément sur le quel on a clické\n // | |le parent |la réponse dans le parent\n let answer = this.parentNode.querySelector('.field--name-field-reponse');\n // console.log(answer); \n answer.classList.add('opened');\n\n}\n///// répète fonction pour les fichiers, les liens et ressources\n//// il faudrait créer un tableau d'objet ?\n\nvar fichiers = document.getElementsByClassName(\"field--name-field-fichiers\");\nvar questions = document.getElementsByClassName(\"field--name-field-question\");\n\nfor (let i = 0; i < questions.length; i++) {\n const question = questions[i]\n question.addEventListener(\"click\", toggleFaqFichiers);\n}\nfunction toggleFaqFichiers(event) {\n // console.log(event, this);\nfor (let i = 0; i < fichiers.length; i++) {\n fichiers[i].classList.remove('opened'); \n}\nlet fichier = this.parentNode.querySelector('.field--name-field-fichiers');\n\nfichier.classList.add('opened');\n}\n\n\n////////////////////////\nvar liens = document.getElementsByClassName(\"field--name-field-liens\");\nvar questions = document.getElementsByClassName(\"field--name-field-question\");\n\nfor (let i = 0; i < questions.length; i++) {\n const question = questions[i]\n question.addEventListener(\"click\", toggleFaqLiens);\n}\nfunction toggleFaqLiens(event) {\n // console.log(event, this);\nfor (let i = 0; i < liens.length; i++) {\n liens[i].classList.remove('opened'); \n}\nlet lien = this.parentNode.querySelector('.field--name-field-liens');\n \nlien.classList.add('opened');\n}\n\n//////////////////////\nvar ressources = document.getElementsByClassName(\"field--name-field-ress\");\nvar questions = document.getElementsByClassName(\"field--name-field-question\");\n\nfor (let i = 0; i < questions.length; i++) {\n const question = questions[i]\n question.addEventListener(\"click\", toggleFaqRessources);\n}\nfunction toggleFaqRessources(event) {\n // console.log(event, this);\nfor (let i = 0; i < resources.length; i++) {\n ressources[i].classList.remove('opened'); \n}\nlet ressource = this.parentNode.querySelector('.field--name-field-ress');\n\nressource.classList.add('opened');\n}\n\n///////////////////////////////\n////////////////////////////////\n// fleche qui tourne faq\n\n// var questions = document.getElementsByClassName(\"field--name-field-question\");\n// var paragraph = document.querySelector('.field--name-field-question p::after');\n// console.log(paragraph)\n// var styles = window.getComputedStyle(element,':after')\n// console.log(styles)\n// var content = styles['content']\n// console.log(content)\n\n\n// for (let i = 0; i < questions.length; i++) {\n// const question = questions[i]\n// question.addEventListener(\"click\", rotateFleche);\n// }\n// function rotateFleche(event) {\n// console.log(event, this);\n// // for (let i = 0; i < answers.length; i++) {\n// // answers[i].classList.remove('opened'); \n// // }\n// }\n\n//////////////////////////////////////////\n// block collection reste bleu quand actif\n \njQuery(function($) {\n var path = window.location.href; // because the 'href' property of the DOM element is the absolute path\n console.log(path);\n $(\".view-id-collections .view-content .views-row a\").each(function() {\n if (this.href === path) {\n $(this).parent().closest('.views-row').addClass('active');\n }\n });\n });\n\n// /////////////////\n//// ancre dans texte au click parragraphe correspondant arrive en dessous du header \n\n\n(function($, window) {\n var adjustAnchor = function() {\n var $anchor = $('.block-entity-fieldnodefield-textes'),\n fixedElementHeight = 350;\n if ($anchor.length > 0) {\n $('html, body').stop().animate({scrollTop: $anchor.offset().top - fixedElementHeight }, 0);\n }\n };\n\n $(window).on('hashchange', function() {\n adjustAnchor();\n });\n\n})(jQuery, window);\n\n\n// ///////////////////////////////\n\n\n// slideshow home // marche pas. attention ai rajouter des class dans template views.view.html.twig et views-view-actus-blocks-pages--block-1.html.twig\n\n(function($, window) {\n console.log('hello')\n $(document).ready(function(){\n $('.path-frontpage .view-actus-blocks-pages .view-content .view-type-slide .views-row-wrapper').slick({\n slidesToShow: 1,\n // slidesToScroll: 1,\n dots: true,\n arrows: true,\n centerMode: true,\n // centerPadding: '100px',\n responsive: [\n {\n breakpoint: 810,\n settings: {\n slidesToShow: 1,\n adaptiveHeight: true,\n arrows: false,\n draggable: true,\n centerMode: true,\n }\n }]\n });\n console.log('salut slick home');\n\n\n $('.page-node-type-actualite .block-entity-fieldnodefield-images .field--type-image').slick({\n dots: true,\n arrows: true,\n adaptiveHeight: true,\n responsive: [\n {\n breakpoint: 800,\n settings: {\n adaptiveHeight: true\n }\n }]\n });\n console.log('salut slick actus');\n\n\n $('.page-node-type-projet .block-entity-fieldnodefield-photo .field--type-image').slick({\n slidesToShow: 1,\n dots: true,\n arrows: false,\n draggable: true,\n adaptiveHeight: true,\n responsive: [\n {\n breakpoint: 800,\n settings: {\n adaptiveHeight: true\n }\n }]\n });\n console.log('salut slick projets');\n\n $('.path-ressources .view:not(.view-partenaires) .view-content .view-type-slide .views-row-wrapper').slick({\n slidesToShow: 3,\n dots: false,\n arrows: true,\n infinite: false,\n centerMode: false,\n responsive: [\n {\n breakpoint: 810,\n settings: {\n slidesToShow: 3,\n arrows: false,\n draggable: true,\n centerMode: true,\n }\n }]\n });\n console.log('salut slick ressource');\n\n });\n\n\n// //////// start ajoute class à views-row-wrapper et view-type-slide dans /ressources ////////\n$(document).ready(function () {\n if (hasActiveFilters()) return;\n $(\".views-row-wrapper\").each(function () {\n let h3 = $(this).prev(\"h3\");\n let link = h3.find(\"a\");\n if (link.length) {\n let text = link.text().trim();\n let className = text\n .toLowerCase()\n .normalize(\"NFD\").replace(/[\\u0300-\\u036f]/g, \"\") // enlever les accents\n .replace(/[^a-z0-9]+/g, '-') // remplacer tout ce qui n'est pas a-z0-9 par -\n .replace(/(^-|-$)/g, ''); // enlever tirets début/fin\n\n $(this).addClass('type-' + className);\n // Ajouter la même classe sur le

\n h3.addClass('type-' + className);\n h3.closest('.view-type-slide').addClass('type-' + className); // ajouter aussi au bloc parent\n }\n });\n\n\n $(\".wrapper-ressource\").each(function(){\n let media = $(this).find(\".field--name-field-type-de-media\");\n\n // console.log(media);\n \n let mediaText = media.text().trim();\n let className = mediaText\n .toLowerCase()\n .normalize(\"NFD\").replace(/[\\u0300-\\u036f]/g, \"\") // enlever les accents\n .replace(/[^a-z0-9]+/g, '-') // remplacer tout ce qui n'est pas a-z0-9 par -\n .replace(/(^-|-$)/g, ''); // enlever tirets début/fin\n // console.log(mediaText);\n $(this).addClass('type-media-' + className);\n });\n\n// ////// cache les slide non voulue en fonction de la class /////////\n// const allowedTypes = [\n// \"type-publication-issue-du-programme-eqld\",\n// \"type-paroles-de-laureats\",\n// \"type-les-projets-en-images\",\n// \"type-presse\"\n// ];\n\n// $(\".view-type-slide\").each(function () {\n// let $block = $(this);\n// let keep = allowedTypes.some(type => $block.hasClass(type));\n \n\n// if (!keep) {\n// $block.hide(); // ou fadeOut() si tu veux un effet\n// }\n// });\n// });\n// $(\".view-type-slide\").each(function () {\n// let $block = $(this);\n// let matched = allowedTypes.filter(type => $block.hasClass(type));\n// console.log(\"Matched:\", matched);\n\n// let keep = matched.length > 0;\n// if (!keep) {\n// $block.hide();\n// }\n});\n\n\nfunction hasActiveFilters() {\n const params = new URLSearchParams(window.location.search);\n for (const [key, value] of params) {\n if (key !== 'page' && value !== 'All' && value !== '') {\n return true;\n }\n }\n return false;\n}\n// /////// end class à views-row-wrapper ///////\n\n\n/////////////// start ouverture liens externes vers nouvel onglet //////////////////\ndocument.querySelectorAll('a[href^=\"http\"]').forEach(link => {\n if (!link.href.includes(location.hostname)) {\n link.setAttribute('target', '_blank');\n link.setAttribute('rel', 'noopener noreferrer');\n }\n});\n\n/////////////// end ouverture liens externes vers nouvel onglet //////////////////\n\n\n/// start /// dans pages /projets après click sur appliquer filtres, scroll down la page au niveau des filtres //////\ndocument.addEventListener(\"DOMContentLoaded\", function () {\n const form = document.querySelector(\".views-exposed-form\");\n\n // console.log(form);\n\n if (form) {\n form.setAttribute(\"action\", form.action.split(\"#\")[0] + \"#filtres\");\n }\n if (window.location.hash === \"#filtres\") {\n const target = document.getElementById(\"filtres\");\n if (target) {\n // target.scrollIntoView({ behavior: \"smooth\", block: \"start\" });\n const offset = 300;\n const top = target.getBoundingClientRect().top + window.pageYOffset - offset;\n\n window.scrollTo({\n top: top,\n behavior: \"smooth\"\n });\n }\n }\n/// end //// dans pages /projets après click sur appliquer filtres, scroll down la page au niveau des filtres //////\n\n\n\n\n //// start ne pas afficher type de ressource 2 fois dans /ressources //////\n document.querySelectorAll(\".view-type-slide\").forEach(view => {\n const h3Content = view.querySelector(\"h3 > a\")?.textContent.trim();\n\n view.querySelectorAll(\".field--name-field-type-de-ressource\").forEach(field => {\n const fieldText = field.textContent.trim();\n\n if (fieldText === h3Content) {\n field.style.display = \"none\";\n }\n });\n });\n\n //// end ne pas afficher type de ressource 2 fois dans /ressources //////\n\n});\n\n})(jQuery, window);\n\n\n\n//# sourceURL=webpack://dev.eql.fr/./scripts/main.js?"); +eval("jQuery(function ($) {\n console.log('salut');\n\n // MENU BURGER\n const burger = document.getElementById(\"block-burger\");\n const burgertitle = document.getElementById(\"block-burger-menu\");\n if (burger && burgertitle) {\n burgertitle.addEventListener(\"click\", function () {\n burger.classList.toggle('opened');\n });\n }\n\n // FAQ — réponses\n const answers = document.getElementsByClassName(\"field--name-field-reponse\");\n const fichiers = document.getElementsByClassName(\"field--name-field-fichiers\");\n const liens = document.getElementsByClassName(\"field--name-field-liens\");\n const ressources = document.getElementsByClassName(\"field--name-field-ress\");\n const questions = document.getElementsByClassName(\"field--name-field-question\");\n\n for (let i = 0; i < questions.length; i++) {\n const q = questions[i];\n q.addEventListener(\"click\", function () {\n // Réponses\n Array.from(answers).forEach(a => a.classList.remove(\"opened\"));\n const r = this.parentNode.querySelector(\".field--name-field-reponse\");\n if (r) r.classList.add(\"opened\");\n\n // Fichiers\n Array.from(fichiers).forEach(f => f.classList.remove(\"opened\"));\n const f = this.parentNode.querySelector(\".field--name-field-fichiers\");\n if (f) f.classList.add(\"opened\");\n\n // Liens\n Array.from(liens).forEach(l => l.classList.remove(\"opened\"));\n const l = this.parentNode.querySelector(\".field--name-field-liens\");\n if (l) l.classList.add(\"opened\");\n\n // Ressources\n Array.from(ressources).forEach(r => r.classList.remove(\"opened\"));\n const res = this.parentNode.querySelector(\".field--name-field-ress\");\n if (res) res.classList.add(\"opened\");\n });\n }\n\n // SLIDESHOW INIT\n $('.path-frontpage .view-actus-blocks-pages .view-content .view-type-slide .views-row-wrapper').slick({\n slidesToShow: 1,\n dots: true,\n arrows: true,\n centerMode: true,\n responsive: [{\n breakpoint: 810,\n settings: {\n slidesToShow: 1,\n adaptiveHeight: true,\n arrows: false,\n draggable: true,\n centerMode: true,\n }\n }]\n });\n\n $('.page-node-type-actualite .block-entity-fieldnodefield-images .field--type-image').slick({\n dots: true,\n arrows: true,\n adaptiveHeight: true,\n responsive: [{\n breakpoint: 800,\n settings: { adaptiveHeight: true }\n }]\n });\n\n $('.page-node-type-projet .block-entity-fieldnodefield-photo .field--type-image').slick({\n slidesToShow: 1,\n dots: true,\n arrows: false,\n draggable: true,\n adaptiveHeight: true,\n responsive: [{\n breakpoint: 800,\n settings: { adaptiveHeight: true }\n }]\n });\n\n // Classes media → .wrapper-ressource\n $(\".wrapper-ressource\").each(function () {\n const media = $(this).find(\".field--name-field-type-de-media\").text().trim();\n const className = media\n .toLowerCase()\n .normalize(\"NFD\").replace(/[\\u0300-\\u036f]/g, \"\")\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/(^-|-$)/g, '');\n $(this).addClass('type-media-' + className);\n });\n\n // SLIDES RECONSTRUCTION LORS DU CHARGEMENT COMPLET\n $(window).on('load', function () {\n const $viewContent = $('.path-ressources .view-content').first();\n if ($viewContent.length === 0) return;\n $viewContent.addClass('view-ressources-hidden');\n\n const allowedTypes = [\n 'type-publication-issue-du-programme-eqld',\n 'type-paroles-de-laureats',\n 'type-les-projets-en-images',\n 'type-presse'\n ];\n\n // const $viewContent = $('.view-content');\n const allRows = $('.path-ressources .view-base-de-donnees .views-row').detach();\n function toLabel(str) {\n return str.replace('type-', '').replace(/-/g, ' ').replace(/\\b\\w/g, l => l.toUpperCase());\n } \n allowedTypes.forEach(type => {\n const label = toLabel(type); \n const $slide = $(`\n
\n

${label}

\n
\n
\n `);\n $viewContent.append($slide);\n });\n\n allRows.each(function () {\n const $row = $(this);\n const classList = $row.attr('class').split(/\\s+/);\n classList.forEach(cls => {\n if (allowedTypes.includes(cls)) {\n $(`.view-type-slide.${cls} .views-row-wrapper`).append($row.clone(true, true));\n }\n });\n });\n\n $('.path-ressources .view:not(.view-partenaires) .view-content .view-type-slide .views-row-wrapper').slick({\n slidesToShow: 3,\n dots: false,\n arrows: true,\n infinite: false,\n centerMode: false,\n responsive: [{\n breakpoint: 810,\n settings: {\n slidesToShow: 3,\n arrows: false,\n draggable: true,\n centerMode: true,\n }\n }]\n });\n // Supprimer les .view-type-slide originales générées par Drupal (vides ou non autorisées)\n $('.path-ressources .view-base-de-donnees .view-type-slide').each(function () {\n const classes = $(this).attr('class').split(/\\s+/);\n const isCustom = classes.some(cls => allowedTypes.includes(cls));\n if (!isCustom) {\n $(this).remove();\n }\n });\n \n $viewContent.removeClass('view-ressources-hidden');\n\n });\n\n // Ouvrir les liens externes dans un nouvel onglet\n document.querySelectorAll('a[href^=\"http\"]').forEach(link => {\n if (!link.href.includes(location.hostname)) {\n link.setAttribute('target', '_blank');\n link.setAttribute('rel', 'noopener noreferrer');\n }\n });\n\n // Scroll automatique au filtre\n const form = document.querySelector(\".views-exposed-form\");\n if (form) form.setAttribute(\"action\", form.action.split(\"#\")[0] + \"#filtres\");\n\n if (window.location.hash === \"#filtres\") {\n const target = document.getElementById(\"filtres\");\n if (target) {\n const offset = 300;\n const top = target.getBoundingClientRect().top + window.pageYOffset - offset;\n window.scrollTo({ top: top, behavior: \"smooth\" });\n }\n }\n\n // MASQUER TYPE DE RESSOURCE DOUBLON\n $(\".view-type-slide\").each(function () {\n const h3Content = $(this).find(\"h3\").text().trim();\n $(this).find(\".field--name-field-type-de-ressource\").each(function () {\n if ($(this).text().trim() === h3Content) {\n $(this).hide();\n }\n });\n });\n});\n\n\n//# sourceURL=webpack://dev.eql.fr/./scripts/main.js?"); /***/ }) diff --git a/web/themes/custom/eql/dist/assets/css/bundle.css b/web/themes/custom/eql/dist/assets/css/bundle.css index 9923ba9..00059bb 100644 --- a/web/themes/custom/eql/dist/assets/css/bundle.css +++ b/web/themes/custom/eql/dist/assets/css/bundle.css @@ -5406,7 +5406,13 @@ svg.ext { padding-bottom: 1rem; } } +.path-ressources .layout-content .region-content #block-contenudelapageprincipale .layout--onecol .layout__region--content .block-region-content .block-views-blockbase-de-donnees-block-1 .view-base-de-donnees .view-ressources-hidden { + visibility: hidden; + height: 0; + overflow: hidden; +} .path-ressources .layout-content .region-content #block-contenudelapageprincipale .layout--onecol .layout__region--content .block-region-content .block-views-blockbase-de-donnees-block-1 .view-base-de-donnees .view-content { + transition: opacity 0.3s ease; display: flex; flex-direction: row; flex-wrap: wrap; diff --git a/web/themes/custom/eql/eql.theme b/web/themes/custom/eql/eql.theme index 50aeb8f..8bda916 100644 --- a/web/themes/custom/eql/eql.theme +++ b/web/themes/custom/eql/eql.theme @@ -8,6 +8,8 @@ // use Drupal\Core\Link; // use Drupal\Core\Url; use Drupal\Component\Utility\Html; +use Drupal\Component\Transliteration\TransliterationInterface; + function eql_preprocess_html(&$variables) { $node = \Drupal::routeMatch()->getParameter('node'); @@ -29,14 +31,21 @@ function eql_preprocess_node(&$variables){ $type_protagoniste = $node->get('field_type_de_protagoniste')->getString(); $variables['attributes']['class'][] = 'type-de-protagoniste-' . $type_protagoniste; } - // Vérifie si le champ field_type_de_ressource existe et ajoute une classe basée sur sa valeur - if ($node->hasField('field_type_de_ressource') && !$node->get('field_type_de_ressource')->isEmpty()) { - // Récupère la valeur de field_type_de_ressource - $type_de_ressource_entity = $node->get('field_type_de_ressource')->entity; - if ($type_de_ressource_entity) { - $type_de_ressource_name = $type_de_ressource_entity->getName(); - // Ajoute la classe CSS basée sur la valeur du type de ressource - $variables['attributes']['class'][] = 'type-de-ressource-' . Html::cleanCssIdentifier($type_de_ressource_name); + + // if ($node->hasField('field_type_de_ressource') && !$node->get('field_type_de_ressource')->isEmpty()) { + // // Récupère la valeur de field_type_de_ressource + // $type_de_ressource_entity = $node->get('field_type_de_ressource')->entity; + // if ($type_de_ressource_entity) { + // $type_de_ressource_name = $type_de_ressource_entity->getName(); + // // Ajoute la classe CSS basée sur la valeur du type de ressource + // $variables['attributes']['class'][] = 'type-de-ressource-' . Html::cleanCssIdentifier($type_de_ressource_name); + // } + // } + if ($node->getType() === 'ressource' && $node->hasField('field_type_de_ressource') && !$node->get('field_type_de_ressource')->isEmpty()) { + foreach ($node->get('field_type_de_ressource')->referencedEntities() as $term) { + $label = $term->label(); // ex: "Presse" + $class = 'type-' . Html::cleanCssIdentifier(strtolower($label)); + $variables['attributes']['class'][] = $class; } } } @@ -94,3 +103,30 @@ function eql_preprocess_layout__threecol_25_50_25(&$variables) { } + +function eql_preprocess_views_view_unformatted(&$variables) { + // On utilise le service de translittération de Drupal + $transliterator = \Drupal::service('transliteration'); + + foreach ($variables['rows'] as &$row) { + if (isset($row['content']['#node'])) { + $node = $row['content']['#node']; + + if ($node->hasField('field_type_de_ressource') && !$node->get('field_type_de_ressource')->isEmpty()) { + foreach ($node->get('field_type_de_ressource')->referencedEntities() as $term) { + $label = $term->label(); + + // Supprimer les accents + $label_ascii = $transliterator->transliterate($label); + + // Nettoyer pour que ce soit une classe CSS valide + $class = 'type-' . Html::cleanCssIdentifier(strtolower($label_ascii)); + + $row['attributes']->addClass($class); + } + } + } + } +} + + diff --git a/web/themes/custom/eql/scripts/main.js b/web/themes/custom/eql/scripts/main.js index 342a47e..8ce6b53 100644 --- a/web/themes/custom/eql/scripts/main.js +++ b/web/themes/custom/eql/scripts/main.js @@ -1,373 +1,194 @@ +jQuery(function ($) { + console.log('salut'); -console.log('salut'); -// menu burger open - -var burger = document.getElementById("block-burger"); -var burgertitle = document.getElementById("block-burger-menu"); - - -burgertitle.addEventListener("click", toggleMenu); - -function toggleMenu(event) { - // console.log(event); - burger.classList.toggle('opened'); -} - -////////////////////////// -// faq reponse open - -var answers = document.getElementsByClassName("field--name-field-reponse"); -var fichiers = document.getElementsByClassName("field--name-field-fichiers"); -var questions = document.getElementsByClassName("field--name-field-question"); - -for (let i = 0; i < questions.length; i++) { - const question = questions[i] - question.addEventListener("click", toggleFaq); -} -function toggleFaq(event) { - // console.log(event, this); - // fermé tout - for (let i = 0; i < answers.length; i++) { - answers[i].classList.remove('opened'); + // MENU BURGER + const burger = document.getElementById("block-burger"); + const burgertitle = document.getElementById("block-burger-menu"); + if (burger && burgertitle) { + burgertitle.addEventListener("click", function () { + burger.classList.toggle('opened'); + }); } - // la réponse correspndante a la question clické - // | this c'est l'élément sur le quel on a clické - // | |le parent |la réponse dans le parent - let answer = this.parentNode.querySelector('.field--name-field-reponse'); - // console.log(answer); - answer.classList.add('opened'); -} -///// répète fonction pour les fichiers, les liens et ressources -//// il faudrait créer un tableau d'objet ? + // FAQ — réponses + const answers = document.getElementsByClassName("field--name-field-reponse"); + const fichiers = document.getElementsByClassName("field--name-field-fichiers"); + const liens = document.getElementsByClassName("field--name-field-liens"); + const ressources = document.getElementsByClassName("field--name-field-ress"); + const questions = document.getElementsByClassName("field--name-field-question"); -var fichiers = document.getElementsByClassName("field--name-field-fichiers"); -var questions = document.getElementsByClassName("field--name-field-question"); + for (let i = 0; i < questions.length; i++) { + const q = questions[i]; + q.addEventListener("click", function () { + // Réponses + Array.from(answers).forEach(a => a.classList.remove("opened")); + const r = this.parentNode.querySelector(".field--name-field-reponse"); + if (r) r.classList.add("opened"); -for (let i = 0; i < questions.length; i++) { - const question = questions[i] - question.addEventListener("click", toggleFaqFichiers); -} -function toggleFaqFichiers(event) { - // console.log(event, this); -for (let i = 0; i < fichiers.length; i++) { - fichiers[i].classList.remove('opened'); -} -let fichier = this.parentNode.querySelector('.field--name-field-fichiers'); + // Fichiers + Array.from(fichiers).forEach(f => f.classList.remove("opened")); + const f = this.parentNode.querySelector(".field--name-field-fichiers"); + if (f) f.classList.add("opened"); -fichier.classList.add('opened'); -} + // Liens + Array.from(liens).forEach(l => l.classList.remove("opened")); + const l = this.parentNode.querySelector(".field--name-field-liens"); + if (l) l.classList.add("opened"); + // Ressources + Array.from(ressources).forEach(r => r.classList.remove("opened")); + const res = this.parentNode.querySelector(".field--name-field-ress"); + if (res) res.classList.add("opened"); + }); + } -//////////////////////// -var liens = document.getElementsByClassName("field--name-field-liens"); -var questions = document.getElementsByClassName("field--name-field-question"); - -for (let i = 0; i < questions.length; i++) { - const question = questions[i] - question.addEventListener("click", toggleFaqLiens); -} -function toggleFaqLiens(event) { - // console.log(event, this); -for (let i = 0; i < liens.length; i++) { - liens[i].classList.remove('opened'); -} -let lien = this.parentNode.querySelector('.field--name-field-liens'); - -lien.classList.add('opened'); -} - -////////////////////// -var ressources = document.getElementsByClassName("field--name-field-ress"); -var questions = document.getElementsByClassName("field--name-field-question"); - -for (let i = 0; i < questions.length; i++) { - const question = questions[i] - question.addEventListener("click", toggleFaqRessources); -} -function toggleFaqRessources(event) { - // console.log(event, this); -for (let i = 0; i < resources.length; i++) { - ressources[i].classList.remove('opened'); -} -let ressource = this.parentNode.querySelector('.field--name-field-ress'); - -ressource.classList.add('opened'); -} - -/////////////////////////////// -//////////////////////////////// -// fleche qui tourne faq - -// var questions = document.getElementsByClassName("field--name-field-question"); -// var paragraph = document.querySelector('.field--name-field-question p::after'); -// console.log(paragraph) -// var styles = window.getComputedStyle(element,':after') -// console.log(styles) -// var content = styles['content'] -// console.log(content) - - -// for (let i = 0; i < questions.length; i++) { -// const question = questions[i] -// question.addEventListener("click", rotateFleche); -// } -// function rotateFleche(event) { -// console.log(event, this); -// // for (let i = 0; i < answers.length; i++) { -// // answers[i].classList.remove('opened'); -// // } -// } - -////////////////////////////////////////// -// block collection reste bleu quand actif - -jQuery(function($) { - var path = window.location.href; // because the 'href' property of the DOM element is the absolute path - console.log(path); - $(".view-id-collections .view-content .views-row a").each(function() { - if (this.href === path) { - $(this).parent().closest('.views-row').addClass('active'); - } - }); - }); - -// ///////////////// -//// ancre dans texte au click parragraphe correspondant arrive en dessous du header - - -(function($, window) { - var adjustAnchor = function() { - var $anchor = $('.block-entity-fieldnodefield-textes'), - fixedElementHeight = 350; - if ($anchor.length > 0) { - $('html, body').stop().animate({scrollTop: $anchor.offset().top - fixedElementHeight }, 0); - } - }; - - $(window).on('hashchange', function() { - adjustAnchor(); - }); - -})(jQuery, window); - - -// /////////////////////////////// - - -// slideshow home // marche pas. attention ai rajouter des class dans template views.view.html.twig et views-view-actus-blocks-pages--block-1.html.twig - -(function($, window) { - console.log('hello') - $(document).ready(function(){ - $('.path-frontpage .view-actus-blocks-pages .view-content .view-type-slide .views-row-wrapper').slick({ + // SLIDESHOW INIT + $('.path-frontpage .view-actus-blocks-pages .view-content .view-type-slide .views-row-wrapper').slick({ + slidesToShow: 1, + dots: true, + arrows: true, + centerMode: true, + responsive: [{ + breakpoint: 810, + settings: { slidesToShow: 1, - // slidesToScroll: 1, - dots: true, - arrows: true, - centerMode: true, - // centerPadding: '100px', - responsive: [ - { - breakpoint: 810, - settings: { - slidesToShow: 1, - adaptiveHeight: true, - arrows: false, - draggable: true, - centerMode: true, - } - }] - }); - console.log('salut slick home'); - - - $('.page-node-type-actualite .block-entity-fieldnodefield-images .field--type-image').slick({ - dots: true, - arrows: true, adaptiveHeight: true, - responsive: [ - { - breakpoint: 800, - settings: { - adaptiveHeight: true - } - }] - }); - console.log('salut slick actus'); - - - $('.page-node-type-projet .block-entity-fieldnodefield-photo .field--type-image').slick({ - slidesToShow: 1, - dots: true, arrows: false, draggable: true, - adaptiveHeight: true, - responsive: [ - { - breakpoint: 800, - settings: { - adaptiveHeight: true - } - }] - }); - console.log('salut slick projets'); - - $('.path-ressources .view:not(.view-partenaires) .view-content .view-type-slide .views-row-wrapper').slick({ - slidesToShow: 3, - dots: false, - arrows: true, - infinite: false, - centerMode: false, - responsive: [ - { - breakpoint: 810, - settings: { - slidesToShow: 3, - arrows: false, - draggable: true, - centerMode: true, - } - }] - }); - console.log('salut slick ressource'); - + centerMode: true, + } + }] }); - -// //////// start ajoute class à views-row-wrapper et view-type-slide dans /ressources //////// -$(document).ready(function () { - if (hasActiveFilters()) return; - $(".views-row-wrapper").each(function () { - let h3 = $(this).prev("h3"); - let link = h3.find("a"); - if (link.length) { - let text = link.text().trim(); - let className = text - .toLowerCase() - .normalize("NFD").replace(/[\u0300-\u036f]/g, "") // enlever les accents - .replace(/[^a-z0-9]+/g, '-') // remplacer tout ce qui n'est pas a-z0-9 par - - .replace(/(^-|-$)/g, ''); // enlever tirets début/fin - - $(this).addClass('type-' + className); - // Ajouter la même classe sur le

- h3.addClass('type-' + className); - h3.closest('.view-type-slide').addClass('type-' + className); // ajouter aussi au bloc parent - } + $('.page-node-type-actualite .block-entity-fieldnodefield-images .field--type-image').slick({ + dots: true, + arrows: true, + adaptiveHeight: true, + responsive: [{ + breakpoint: 800, + settings: { adaptiveHeight: true } + }] }); + $('.page-node-type-projet .block-entity-fieldnodefield-photo .field--type-image').slick({ + slidesToShow: 1, + dots: true, + arrows: false, + draggable: true, + adaptiveHeight: true, + responsive: [{ + breakpoint: 800, + settings: { adaptiveHeight: true } + }] + }); - $(".wrapper-ressource").each(function(){ - let media = $(this).find(".field--name-field-type-de-media"); - - // console.log(media); - - let mediaText = media.text().trim(); - let className = mediaText - .toLowerCase() - .normalize("NFD").replace(/[\u0300-\u036f]/g, "") // enlever les accents - .replace(/[^a-z0-9]+/g, '-') // remplacer tout ce qui n'est pas a-z0-9 par - - .replace(/(^-|-$)/g, ''); // enlever tirets début/fin - // console.log(mediaText); + // Classes media → .wrapper-ressource + $(".wrapper-ressource").each(function () { + const media = $(this).find(".field--name-field-type-de-media").text().trim(); + const className = media + .toLowerCase() + .normalize("NFD").replace(/[\u0300-\u036f]/g, "") + .replace(/[^a-z0-9]+/g, '-') + .replace(/(^-|-$)/g, ''); $(this).addClass('type-media-' + className); }); -// ////// cache les slide non voulue en fonction de la class ///////// -// const allowedTypes = [ -// "type-publication-issue-du-programme-eqld", -// "type-paroles-de-laureats", -// "type-les-projets-en-images", -// "type-presse" -// ]; + // SLIDES RECONSTRUCTION LORS DU CHARGEMENT COMPLET + $(window).on('load', function () { + const $viewContent = $('.path-ressources .view-content').first(); + if ($viewContent.length === 0) return; + $viewContent.addClass('view-ressources-hidden'); -// $(".view-type-slide").each(function () { -// let $block = $(this); -// let keep = allowedTypes.some(type => $block.hasClass(type)); + const allowedTypes = [ + 'type-publication-issue-du-programme-eqld', + 'type-paroles-de-laureats', + 'type-les-projets-en-images', + 'type-presse' + ]; + + // const $viewContent = $('.view-content'); + const allRows = $('.path-ressources .view-base-de-donnees .views-row').detach(); + function toLabel(str) { + return str.replace('type-', '').replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase()); + } + allowedTypes.forEach(type => { + const label = toLabel(type); + const $slide = $(` +
+

${label}

+
+
+ `); + $viewContent.append($slide); + }); + + allRows.each(function () { + const $row = $(this); + const classList = $row.attr('class').split(/\s+/); + classList.forEach(cls => { + if (allowedTypes.includes(cls)) { + $(`.view-type-slide.${cls} .views-row-wrapper`).append($row.clone(true, true)); + } + }); + }); + + $('.path-ressources .view:not(.view-partenaires) .view-content .view-type-slide .views-row-wrapper').slick({ + slidesToShow: 3, + dots: false, + arrows: true, + infinite: false, + centerMode: false, + responsive: [{ + breakpoint: 810, + settings: { + slidesToShow: 3, + arrows: false, + draggable: true, + centerMode: true, + } + }] + }); + // Supprimer les .view-type-slide originales générées par Drupal (vides ou non autorisées) + $('.path-ressources .view-base-de-donnees .view-type-slide').each(function () { + const classes = $(this).attr('class').split(/\s+/); + const isCustom = classes.some(cls => allowedTypes.includes(cls)); + if (!isCustom) { + $(this).remove(); + } + }); + $viewContent.removeClass('view-ressources-hidden'); -// if (!keep) { -// $block.hide(); // ou fadeOut() si tu veux un effet -// } -// }); -// }); -// $(".view-type-slide").each(function () { -// let $block = $(this); -// let matched = allowedTypes.filter(type => $block.hasClass(type)); -// console.log("Matched:", matched); + }); -// let keep = matched.length > 0; -// if (!keep) { -// $block.hide(); -// } -}); - - -function hasActiveFilters() { - const params = new URLSearchParams(window.location.search); - for (const [key, value] of params) { - if (key !== 'page' && value !== 'All' && value !== '') { - return true; + // Ouvrir les liens externes dans un nouvel onglet + document.querySelectorAll('a[href^="http"]').forEach(link => { + if (!link.href.includes(location.hostname)) { + link.setAttribute('target', '_blank'); + link.setAttribute('rel', 'noopener noreferrer'); } - } - return false; -} -// /////// end class à views-row-wrapper /////// + }); - -/////////////// start ouverture liens externes vers nouvel onglet ////////////////// -document.querySelectorAll('a[href^="http"]').forEach(link => { - if (!link.href.includes(location.hostname)) { - link.setAttribute('target', '_blank'); - link.setAttribute('rel', 'noopener noreferrer'); - } -}); - -/////////////// end ouverture liens externes vers nouvel onglet ////////////////// - - -/// start /// dans pages /projets après click sur appliquer filtres, scroll down la page au niveau des filtres ////// -document.addEventListener("DOMContentLoaded", function () { + // Scroll automatique au filtre const form = document.querySelector(".views-exposed-form"); + if (form) form.setAttribute("action", form.action.split("#")[0] + "#filtres"); - // console.log(form); - - if (form) { - form.setAttribute("action", form.action.split("#")[0] + "#filtres"); - } if (window.location.hash === "#filtres") { const target = document.getElementById("filtres"); if (target) { - // target.scrollIntoView({ behavior: "smooth", block: "start" }); const offset = 300; const top = target.getBoundingClientRect().top + window.pageYOffset - offset; - - window.scrollTo({ - top: top, - behavior: "smooth" - }); + window.scrollTo({ top: top, behavior: "smooth" }); } } -/// end //// dans pages /projets après click sur appliquer filtres, scroll down la page au niveau des filtres ////// - - - - //// start ne pas afficher type de ressource 2 fois dans /ressources ////// - document.querySelectorAll(".view-type-slide").forEach(view => { - const h3Content = view.querySelector("h3 > a")?.textContent.trim(); - - view.querySelectorAll(".field--name-field-type-de-ressource").forEach(field => { - const fieldText = field.textContent.trim(); - - if (fieldText === h3Content) { - field.style.display = "none"; + // MASQUER TYPE DE RESSOURCE DOUBLON + $(".view-type-slide").each(function () { + const h3Content = $(this).find("h3").text().trim(); + $(this).find(".field--name-field-type-de-ressource").each(function () { + if ($(this).text().trim() === h3Content) { + $(this).hide(); } }); }); - - //// end ne pas afficher type de ressource 2 fois dans /ressources ////// - }); - -})(jQuery, window); - diff --git a/web/themes/custom/eql/scss/pages/ressources.scss b/web/themes/custom/eql/scss/pages/ressources.scss index 01f8edb..381d7f5 100644 --- a/web/themes/custom/eql/scss/pages/ressources.scss +++ b/web/themes/custom/eql/scss/pages/ressources.scss @@ -151,7 +151,18 @@ } } + .view-ressources-hidden { + visibility: hidden; + height: 0; + overflow: hidden; + } + + + + .view-content{ + + transition: opacity 0.3s ease; display: flex; flex-direction: row; flex-wrap: wrap; diff --git a/web/themes/custom/eql/templates/views-view-unformatted.html.twig b/web/themes/custom/eql/templates/views-view-unformatted.html.twig index 81dbfe3..d7e2935 100644 --- a/web/themes/custom/eql/templates/views-view-unformatted.html.twig +++ b/web/themes/custom/eql/templates/views-view-unformatted.html.twig @@ -21,6 +21,8 @@ default_row_class ? 'views-row-wrapper', ] %} + +
{% if title %} @@ -44,4 +46,4 @@ {% endfor %}
- \ No newline at end of file + diff --git a/web/themes/custom/eql/templates/views-view.html.twig b/web/themes/custom/eql/templates/views-view.html.twig index 3e99338..8b276ae 100644 --- a/web/themes/custom/eql/templates/views-view.html.twig +++ b/web/themes/custom/eql/templates/views-view.html.twig @@ -40,6 +40,7 @@ dom_id ? 'js-view-dom-id-' ~ dom_id, ] %} + {{ title_prefix }} {% if title %} @@ -62,13 +63,17 @@ {% endif %} - {% if rows %} +{% if rows %} + {% set content_classes = ['view-content'] %} + {% if view.id == 'base_de_donnees' %} + {% set content_classes = content_classes|merge(['view-ressources-hidden']) %} + {% endif %} -
+ {{ rows }} -
+ {% elseif empty %}
{{ empty }}