1/** 2 * OFQJ Connector Scripts - V33.0 3 * Gère les interactions client, les filtres et la modal. 4 */ 5var ofqj = { 6 loadMore: function(btn) { 7 var grid = document.getElementById('ofqj-grid'); 8 var flux = btn.getAttribute('data-flux'); 9 var limit = btn.getAttribute('data-limit'); 10 btn.disabled = true; 11 btn.innerHTML = '<i class="fas fa-spinner fa-spin"></i>'; 12 13 fetch(ofqjConfig.ajax_url + '?action=ofqj_load_more&offset=' + grid.querySelectorAll('.ofqj-card').length + '&flux=' + flux + '&limit=' + limit) 14 .then(function(r) { return r.text(); }) 15 .then(function(html) { 16 if (html.trim() === 'EMPTY' || html.trim() === '') { 17 btn.parentElement.innerHTML = '<small>Fin des offres</small>'; 18 } else { 19 grid.insertAdjacentHTML('beforeend', html); 20 btn.disabled = false; 21 btn.innerHTML = 'Charger plus'; 22 this.checkUrlParams(); 23 } 24 }.bind(this)); 25 }, 26 27 applyFilters: function() { 28 var search = document.getElementById('ofqj-search').value.toLowerCase(); 29 var location = document.getElementById('ofqj-filter-city').value; 30 document.querySelectorAll('.ofqj-card').forEach(function(card) { 31 var text = card.innerText.toLowerCase(); 32 var cardLoc = card.getAttribute('data-location'); 33 var matchSearch = text.indexOf(search) > -1; 34 var matchLoc = location === "" || cardLoc === location; 35 card.style.display = (matchSearch && matchLoc) ? 'flex' : 'none'; 36 }); 37 }, 38 39 copyLink: function(id) { 40 var url = new URL(window.location.href); 41 url.searchParams.set('ofqj_id', id); 42 navigator.clipboard.writeText(url.toString()).then(function() { 43 var btn = document.querySelector('.ofqj-copy-btn'); 44 if(btn) { 45 btn.innerHTML = '<i class="fas fa-check"></i> Lien copié'; 46 btn.classList.add('success'); 47 setTimeout(function(){ 48 btn.innerHTML = '<i class="fas fa-link"></i> Copier le lien'; 49 btn.classList.remove('success'); 50 }, 2000); 51 } 52 }); 53 }, 54 55 openB64: function(str) { 56 try { 57 var json = decodeURIComponent(atob(str).split('').map(function(c) { 58 return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); 59 }).join('')); 60 this.open(JSON.parse(json)); 61 } catch(e) { console.error("Format Error", e); } 62 }, 63 64 open: function(d) { 65 var modal = document.getElementById('ofqjMod'); 66 var color = ofqjConfig.color; 67 var accent = ofqjConfig.accent; 68 69 var html = '<div class="ofqj-mod-head"><div><h2 style="color:'+color+'">' + d.title + '</h2>'; 70 if(d.theme) html += '<span class="ofqj-theme-tag" style="color:'+accent+'">'+d.theme+'</span>'; 71 html += '</div><button class="ofqj-copy-btn" onclick="ofqj.copyLink(\''+d.id+'\')"><i class="fas fa-link"></i> Copier le lien</button></div>'; 72 73 html += '<div class="ofqj-loc-bar">'; 74 var locs = []; 75 if(d.ville) locs.push('<div><span>Ville</span><strong>'+d.ville+'</strong></div>'); 76 if(d.region) locs.push('<div><span>Région</span><strong>'+d.region+'</strong></div>'); 77 if(d.province) locs.push('<div><span>Province</span><strong>'+d.province+'</strong></div>'); 78 if(d.pays) locs.push('<div><span>Pays</span><strong>'+d.pays+'</strong></div>'); 79 html += locs.join('<div class="ofqj-loc-sep"></div>'); 80 html += '</div>'; 81 82 html += '<div class="ofqj-mod-body-grid"><div class="ofqj-mod-main">'; 83 if (d.context) html += '<div class="ofqj-sec"><h4 style="color:'+color+'"><i class="fas fa-circle-info" style="color:'+accent+'"></i> Contexte de la mission</h4><div class="ofqj-content">' + d.context + '</div></div>'; 84 html += '<div class="ofqj-sec"><h4 style="color:'+color+'"><i class="fas fa-list-check" style="color:'+accent+'"></i> Description des missions</h4><div class="ofqj-content">' + (d.full || d.description) + '</div></div>'; 85 if (d.diploma) html += '<div class="ofqj-sec"><h4 style="color:'+color+'"><i class="fas fa-graduation-cap" style="color:'+accent+'"></i> Profil recherché</h4><div class="ofqj-content">' + d.diploma + '</div></div>'; 86 87 html += '</div><div class="ofqj-mod-side"><div class="ofqj-sticky-info"><h5>RÃCAPITULATIF</h5>'; 88 if(d.reference) html += '<div class="ofqj-info-row"><div class="ofqj-icon-box"><i class="fas fa-hashtag"></i></div><div><span>RÃFÃRENCE</span><strong>'+d.reference+'</strong></div></div>'; 89 html += '<div class="ofqj-info-row"><div class="ofqj-icon-box" style="background:#ecfdf5"><i class="fas fa-calendar-play" style="color:#10b981"></i></div><div><span>DÃBUT</span><strong>'+(d.date_debut || 'Dès que possible')+'</strong></div></div>'; 90 html += '<div class="ofqj-info-row"><div class="ofqj-icon-box" style="background:#fef2f2"><i class="fas fa-calendar-xmark" style="color:'+accent+'"></i></div><div><span>LIMITE</span><strong>'+(d.limit_date || '-')+'</strong></div></div>'; 91 if(d.theme) html += '<div class="ofqj-info-row"><div class="ofqj-icon-box" style="background:#eff6ff"><i class="fas fa-tag" style="color:'+color+'"></i></div><div><span>THÃMATIQUE</span><strong>'+d.theme+'</strong></div></div>'; 92 html += '<div style="margin-top:25px"><a href="' + d.link + '" target="_blank" class="ofqj-btn-prime" style="background:'+accent+'">Postuler sur OFQJ.org</a></div>'; 93 html += '</div></div></div>'; 94 95 document.getElementById('ofqjModBody').innerHTML = html; 96 modal.style.display = 'flex'; 97 document.body.style.overflow = 'hidden'; 98 }, 99 100 close: function() { 101 document.getElementById('ofqjMod').style.display = 'none'; 102 document.body.style.overflow = 'auto'; 103 var url = new URL(window.location.href); 104 url.searchParams.delete('ofqj_id'); 105 window.history.replaceState({}, '', url); 106 }, 107 108 checkUrlParams: function() { 109 var id = new URLSearchParams(window.location.search).get('ofqj_id'); 110 if(id) { 111 var card = document.querySelector('.ofqj-card[data-id="'+id+'"]'); 112 if(card) card.click(); 113 } 114 }, 115
116 initCarousel: function() { 117 var carousels = document.querySelectorAll('.ofqj-carousel-container'); 118 carousels.forEach(function(c) { 119 var track = c.querySelector('.ofqj-carousel-track'); 120 var slides = Array.from(track.children); 121 if(slides.length < 2) return; 122 var index = 0; 123 setInterval(function() { 124 index = (index + 1) % slides.length; 125 track.style.transform = 'translateX(-' + (index * 100) + '%)'; 126 }, 5000); 127 }); 128 } 129}; 130 131document.addEventListener('DOMContentLoaded', function() { 132 ofqj.checkUrlParams(); 133 ofqj.initCarousel(); 134});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.