templates/fronts/list_chercheurs.html.twig line 1

  1. {% extends 'base_front.html.twig' %}
  2. {% block title %}Nos chercheurs{% endblock %}
  3. {% block body %}
  4. <section id="content">
  5.     <div class="col-mt-30">
  6.         <section id="researchers-section" class="py-5">
  7.     <div class="container">
  8.         <!-- Titre -->
  9.         {% if nomStructure %}
  10.          <h2 class="section-title text-center mb-5">{{nomStructure}}</h2>
  11.         {% else  %}
  12.             <h2 class="section-title text-center mb-5">Nos Chercheurs</h2>
  13.         {% endif  %}
  14.         
  15.         <!-- Filtres améliorés -->
  16.         <div class="filter-container mb-5">
  17.             <form id="filterForm" class="filter-form">
  18.                 <div class="row g-3">
  19.                     <div class="col-md-4">
  20.                         <div class="filter-group">
  21.                             <label for="filterEtablissement" class="filter-label">Établissement</label>
  22.                             <select name="filterEtablissement" id="filterEtablissement" class="form-select">
  23.                                 <option value="">Tous les établissements</option>
  24.                                 {% for etablissement in etablissements %}
  25.                                     <option value="{{ etablissement.id }}">{{ etablissement.nomLong }}</option>
  26.                                 {% endfor %}
  27.                             </select>
  28.                         </div>
  29.                     </div>
  30.                     <div class="col-md-4">
  31.                         <div class="filter-group">
  32.                             <label for="filterStructure" class="filter-label">Structure de recherche</label>
  33.                             <select name="filterStructure" id="filterStructure" class="form-select">
  34.                                 <option value="">Toutes les structures</option>
  35.                                 {% for structure in structures %}
  36.                                     <option value="{{ structure.id }}">{{ structure.nomLong }}</option>
  37.                                 {% endfor %}
  38.                             </select>
  39.                         </div>
  40.                     </div>
  41.                     <div class="col-md-4">
  42.                         <div class="filter-group">
  43.                             <label for="filterNom" class="filter-label">Nom du chercheur</label>
  44.                             <div class="input-with-icon">
  45.                                 <input type="text" id="filterNom" class="form-control" placeholder="Rechercher par nom">
  46.                                 <i class="fas fa-search"></i>
  47.                             </div>
  48.                         </div>
  49.                     </div>
  50.                 </div>
  51.             </form>
  52.         </div>
  53.         <!-- Cartes des chercheurs -->
  54.         <div id="chercheurContainer" class="row g-4">
  55.             {% for chercheur in chercheurs %}
  56.                     <div class="col-lg-4 col-md-6 mb-4 chercheur-card"
  57.                          data-etablissement="{% if chercheur.etablissement is not null %}{{ chercheur.etablissement.id }}{% endif %}"
  58.                          data-structure="{{ chercheur.structure.id }}"
  59.                          data-nom="{{ chercheur.nom }} {{ chercheur.prenom }}">
  60.                         <a href="{{ path('app_chercheurs_details', {'idChercheur': chercheur.id}) }}" class="researcher-link">
  61.                             <div class="researcher-card">
  62.                                 <div class="researcher-image">
  63.                                     {% if chercheur.photo is not null %}
  64.                                     <img src="/upload/chercheurs/{{ chercheur.photo }}" alt="{{ chercheur.nom }}" class="img-fluid"
  65.                                      style="width: 100px; height: 100px;">
  66.                                 {% else %}
  67.                                     <img src="/front/icons/utilisateur.png" alt="{{ chercheur.nom }}" class="img-fluid"
  68.                                      style="width: 100px; height: 100px;">
  69.                                 {% endif %}
  70.                                     <div class="researcher-badge">{{chercheur.etablissement.nomCourt}}</div>
  71.                                 </div>
  72.                                 <div class="researcher-info">
  73.                                     <h3 class="researcher-name">{{ chercheur.nom }} {{ chercheur.prenom }}</h3>
  74.                                     <div class="researcher-meta">
  75.                                         <span class="research-structure">{{ chercheur.structure ? chercheur.structure.nomLong : '' }}</span>
  76.                                         <span class="institution">{{ chercheur.etablissement ? chercheur.etablissement.nomLong : '' }}</span>
  77.                                     </div>
  78.                                     <div class="researcher-cta">
  79.                                         <span>Voir profil <i class="fas fa-arrow-right"></i></span>
  80.                                     </div>
  81.                                 </div>
  82.                             </div>
  83.                             
  84.                         </a>
  85.                     </div>
  86.                 {% endfor %}
  87.             
  88.         </div>
  89.         <!-- Pagination -->
  90.         <div id="paginationControls" class="pagination-container text-center mt-5"></div>
  91.         
  92.         
  93.        <!-- <div  class="pagination-container mt-5">
  94.             <nav aria-label="Page navigation">
  95.                 <ul class="pagination justify-content-center">
  96.                     <li class="page-item disabled">
  97.                         <a class="page-link" href="#" tabindex="-1">
  98.                             <i class="fas fa-chevron-left"></i>
  99.                         </a>
  100.                     </li>
  101.                     <li class="page-item active"><a class="page-link" href="#">1</a></li>
  102.                     <li class="page-item"><a class="page-link" href="#">2</a></li>
  103.                     <li class="page-item"><a class="page-link" href="#">3</a></li>
  104.                     <li class="page-item">
  105.                         <a class="page-link" href="#">
  106.                             <i class="fas fa-chevron-right"></i>
  107.                         </a>
  108.                     </li>
  109.                 </ul>
  110.             </nav>
  111.         </div>-->
  112.     </div>
  113. </section>
  114.        
  115. <script>
  116.     document.addEventListener('DOMContentLoaded', function() {
  117.         const filterForm = document.getElementById('filterForm');
  118.         const chercheurCards = document.querySelectorAll('.chercheur-card');
  119.         const paginationControls = document.getElementById('paginationControls');
  120.         const perPage = 15; // Number of items per page
  121.         let currentPage = 1;
  122.         function filterChercheurs() {
  123.             const filterEtablissement = document.getElementById('filterEtablissement').value.toLowerCase();
  124.             const filterStructure = document.getElementById('filterStructure').value.toLowerCase();
  125.             const filterNom = document.getElementById('filterNom').value.toLowerCase();
  126.             let visibleCards = [];
  127.             chercheurCards.forEach(card => {
  128.                 const etablissement = card.getAttribute('data-etablissement').toLowerCase();
  129.                 const structure = card.getAttribute('data-structure').toLowerCase();
  130.                 const nom = card.getAttribute('data-nom').toLowerCase();
  131.                 let isVisible = true;
  132.                 if (filterEtablissement && etablissement !== filterEtablissement) {
  133.                     isVisible = false;
  134.                 }
  135.                 if (filterStructure && structure !== filterStructure) {
  136.                     isVisible = false;
  137.                 }
  138.                 if (filterNom && !nom.includes(filterNom)) {
  139.                     isVisible = false;
  140.                 }
  141.                 card.style.display = isVisible ? 'block' : 'none';
  142.                 if (isVisible) {
  143.                     visibleCards.push(card);
  144.                 }
  145.             });
  146.             paginate(visibleCards);
  147.         }
  148.         function paginate(items) {
  149.             const totalPages = Math.ceil(items.length / perPage);
  150.             paginationControls.innerHTML = '';
  151.             // Create the container structure
  152.             const container = document.createElement('div');
  153.             container.className = 'pagination-container mt-5';
  154.             const nav = document.createElement('nav');
  155.             nav.setAttribute('aria-label', 'Page navigation');
  156.             const ul = document.createElement('ul');
  157.             ul.className = 'pagination justify-content-center';
  158.             // Previous button
  159.             const prevLi = document.createElement('li');
  160.             prevLi.className = 'page-item disabled';
  161.             const prevLink = document.createElement('a');
  162.             prevLink.className = 'page-link';
  163.             prevLink.href = '#';
  164.             prevLink.setAttribute('tabindex', '-1');
  165.             
  166.             const prevIcon = document.createElement('i');
  167.             prevIcon.className = 'fas fa-chevron-left';
  168.             prevLink.appendChild(prevIcon);
  169.             prevLi.appendChild(prevLink);
  170.             ul.appendChild(prevLi);
  171.             // Add click handler for previous button
  172.             prevLink.addEventListener('click', (e) => {
  173.                 e.preventDefault();
  174.                 if (currentPage > 1) {
  175.                     currentPage--;
  176.                     updatePagination(items, totalPages);
  177.                 }
  178.             });
  179.             for (let i = 1; i <= totalPages; i++) {
  180.                 const li = document.createElement('li');
  181.                 li.className = 'page-item' + (i === currentPage ? ' active' : '');
  182.                 const a = document.createElement('a');
  183.                 a.className = 'page-link';
  184.                 a.href = '#';
  185.                 a.textContent = i;
  186.                 a.addEventListener('click', (e) => {
  187.                     e.preventDefault();
  188.                     currentPage = i;
  189.                     updatePagination(items, totalPages);
  190.                 });
  191.                 li.appendChild(a);
  192.                 ul.appendChild(li);
  193.             }
  194.              // Next button
  195.             const nextLi = document.createElement('li');
  196.             nextLi.className = 'page-item';
  197.             const nextLink = document.createElement('a');
  198.             nextLink.className = 'page-link';
  199.             nextLink.href = '#';
  200.             const nextIcon = document.createElement('i');
  201.             nextIcon.className = 'fas fa-chevron-right';
  202.             nextLink.appendChild(nextIcon);
  203.             nextLi.appendChild(nextLink);
  204.             ul.appendChild(nextLi);
  205.     // Add click handler for next button
  206.             nextLink.addEventListener('click', (e) => {
  207.                 e.preventDefault();
  208.                 if (currentPage < totalPages) {
  209.                     currentPage++;
  210.                     updatePagination(items, totalPages);
  211.                 }
  212.             });
  213.     // Build the DOM structure
  214.             nav.appendChild(ul);
  215.             container.appendChild(nav);
  216.             paginationControls.appendChild(container);
  217.             updatePagination(items, totalPages);
  218.         }
  219.         function updatePagination(items, totalPages) {
  220.             items.forEach((item, index) => {
  221.                 item.style.display = (index >= (currentPage - 1) * perPage && index < currentPage * perPage) ? 'block' : 'none';
  222.             });
  223.             // Update pagination controls state
  224.             const pageItems = document.querySelectorAll('.page-item');
  225.             pageItems.forEach((item, index) => {
  226.         // Skip prev/next buttons (first and last elements)
  227.                 if (index > 0 && index < pageItems.length - 1) {
  228.             const pageNum = index; // Because index 0 is prev button
  229.             item.classList.toggle('active', pageNum === currentPage);
  230.                 }
  231.             });
  232.             // Update prev/next button states
  233.             const prevButton = pageItems[0];
  234.             const nextButton = pageItems[pageItems.length - 1];
  235.             prevButton.classList.toggle('disabled', currentPage === 1);
  236.             nextButton.classList.toggle('disabled', currentPage === totalPages);
  237.          }
  238. /* function paginate(items) {
  239.     const totalPages = Math.ceil(items.length / perPage);
  240.     paginationControls.innerHTML = '';
  241.     const container = document.createElement('div');
  242.     container.className = 'pagination-container mt-5';
  243.     const nav = document.createElement('nav');
  244.     nav.setAttribute('aria-label', 'Page navigation');
  245.     const ul = document.createElement('ul');
  246.     ul.className = 'pagination justify-content-center';
  247.     // Bouton Précédent
  248.     const prevLi = document.createElement('li');
  249.     prevLi.className = 'page-item' + (currentPage === 1 ? ' disabled' : '');
  250.     const prevLink = document.createElement('a');
  251.     prevLink.className = 'page-link';
  252.     prevLink.href = '#';
  253.     prevLink.setAttribute('tabindex', currentPage === 1 ? '-1' : '');
  254.     
  255.     const prevIcon = document.createElement('i');
  256.     prevIcon.className = 'fas fa-chevron-left';
  257.     prevLink.appendChild(prevIcon);
  258.     prevLi.appendChild(prevLink);
  259.     ul.appendChild(prevLi);
  260.     prevLink.addEventListener('click', (e) => {
  261.         e.preventDefault();
  262.         if (currentPage > 1) {
  263.             currentPage--;
  264.             updatePagination(items, totalPages);
  265.         }
  266.     });
  267.     // Toujours afficher la première page
  268.     createPageItem(1, ul);
  269.     // Afficher '...' si nécessaire avant la page courante
  270.     if (currentPage > 3) {
  271.         const ellipsisLi = document.createElement('li');
  272.         ellipsisLi.className = 'page-item disabled';
  273.         const ellipsisLink = document.createElement('a');
  274.         ellipsisLink.className = 'page-link';
  275.         ellipsisLink.href = '#';
  276.         ellipsisLink.textContent = '...';
  277.         ellipsisLi.appendChild(ellipsisLink);
  278.         ul.appendChild(ellipsisLi);
  279.     }
  280.     // Afficher la page précédente et la page courante si elles sont dans l'intervalle
  281.     if (currentPage > 2) {
  282.         createPageItem(currentPage - 1, ul);
  283.     }
  284.     if (currentPage !== 1 && currentPage !== totalPages) {
  285.         createPageItem(currentPage, ul);
  286.     }
  287.     // Afficher '...' si nécessaire après la page courante
  288.     if (currentPage < totalPages - 2) {
  289.         const ellipsisLi = document.createElement('li');
  290.         ellipsisLi.className = 'page-item disabled';
  291.         const ellipsisLink = document.createElement('a');
  292.         ellipsisLink.className = 'page-link';
  293.         ellipsisLink.href = '#';
  294.         ellipsisLink.textContent = '...';
  295.         ellipsisLi.appendChild(ellipsisLink);
  296.         ul.appendChild(ellipsisLi);
  297.     }
  298.     // Toujours afficher la dernière page
  299.     if (totalPages > 1) {
  300.         createPageItem(totalPages, ul);
  301.     }
  302.     // Bouton Suivant
  303.     const nextLi = document.createElement('li');
  304.     nextLi.className = 'page-item' + (currentPage === totalPages ? ' disabled' : '');
  305.     const nextLink = document.createElement('a');
  306.     nextLink.className = 'page-link';
  307.     nextLink.href = '#';
  308.     const nextIcon = document.createElement('i');
  309.     nextIcon.className = 'fas fa-chevron-right';
  310.     nextLink.appendChild(nextIcon);
  311.     nextLi.appendChild(nextLink);
  312.     ul.appendChild(nextLi);
  313.     nextLink.addEventListener('click', (e) => {
  314.         e.preventDefault();
  315.         if (currentPage < totalPages) {
  316.             currentPage++;
  317.             updatePagination(items, totalPages);
  318.         }
  319.     });
  320.     nav.appendChild(ul);
  321.     container.appendChild(nav);
  322.     paginationControls.appendChild(container);
  323.     updatePagination(items, totalPages);
  324. }
  325. function createPageItem(pageNum, ul) {
  326.     const li = document.createElement('li');
  327.     li.className = 'page-item' + (pageNum === currentPage ? ' active' : '');
  328.     const a = document.createElement('a');
  329.     a.className = 'page-link';
  330.     a.href = '#';
  331.     a.textContent = pageNum;
  332.     a.addEventListener('click', (e) => {
  333.         e.preventDefault();
  334.         currentPage = pageNum;
  335.         updatePagination();
  336.     });
  337.     li.appendChild(a);
  338.     ul.appendChild(li);
  339. }
  340. function updatePagination(items, totalPages) {
  341.     items.forEach((item, index) => {
  342.         item.style.display = (index >= (currentPage - 1) * perPage && index < currentPage * perPage) ? 'block' : 'none';
  343.     });
  344.     
  345.     // Reconstruire les contrôles de pagination
  346.     paginate(items);
  347. }*/
  348.         document.getElementById('filterEtablissement').addEventListener('change', () => {
  349.             currentPage = 1;
  350.             filterChercheurs();
  351.         });
  352.         document.getElementById('filterStructure').addEventListener('change', () => {
  353.             currentPage = 1;
  354.             filterChercheurs();
  355.         });
  356.         document.getElementById('filterNom').addEventListener('input', () => {
  357.             currentPage = 1;
  358.             filterChercheurs();
  359.         });
  360.         filterChercheurs(); // Initial filter on page load
  361.     });
  362. </script>
  363. {% endblock %}