1jQuery(function ($) { 2 3 const $table = $('#ccr-arretes-table'); 4 if (!$table.length) return; 5 6 const ajaxUrl = $table.data('ajax-url'); 7 const nonce = $table.data('nonce'); 8 let domDTSort = "<''<''i><'col-sm-12'f>>"; 9 domDTSort += "<''<''tr>>"; 10 domDTSort += "<''<''l><''p>>"; 11 12 13 const table = $table.DataTable({ 14 15 "dom": domDTSort, 16 "responsive": true, 17 "paging": true, 18 "search": true, 19 "processing": true, 20 "serverSide": true, 21 ajax: { 22 url: ajaxUrl, 23 type: 'POST', 24 data: function (d) { 25 const typeSMS = document.getElementById('select_type').__sms; 26 const anneeSMS = document.getElementById('year_type').__sms; 27 const departement_select = document.getElementById('departement_select').__sms; 28 const commune_select = document.getElementById('commune_select').__sms; 29 d.action = 'get_arretes'; 30 d._ajax_nonce = nonce; 31 d.codePeril = typeSMS ? typeSMS.getValue() : []; 32 d.codeNOR = $('#search_code_nor').val(); 33 d.dateArrete = anneeSMS ? anneeSMS.getValue() : []; 34 d.nomCommune = commune_select ? commune_select.getValue() : []; 35 d.departement = departement_select ? departement_select.getValue(): [] 36 } 37 }, 38 columns: [ 39 { 40 data: null, 41 render: renderPictos, 42 orderable: false 43 }, 44 {data: 'nomPeril', className: 'text-center'}, 45 {data: 'dateArrete'}, 46 {data: 'dateParutionJO'}, 47 {data: 'codeNOR'}, 48 { 49 "data": null, 50 "orderable": false, 51 52 "render": function (data, type, row) { 53 return `<div class="liste-arrete-telechargement"><a href="#" class="export-csv data_table_btn" data-id="${row.codeArrete}">Télécharger</a> 54 <a href="/detail-arrete/?codeArrete=${row.codeArrete}" class="show-arrete"><img style="padding-left: 25px; padding-right: 7px" src="/wp-content/themes/neve-child/icon/visibility.svg"><span class="show-arrete-txt"> Détails</span></a></div>`; 55 } 56 } 57 ], 58 "language": { 59 "decimal": "", 60 "emptyTable": "Aucune donnée disponible dans le tableau", 61 "info": "Affichage _START_ à _END_ sur _TOTAL_", 62 "infoEmpty": "Affichage 0 à 0 sur 0 élément", 63 "infoFiltered": "", 64 "infoPostFix": "", 65 "thousands": ",", 66 "lengthMenu": "Afficher _MENU_", 67 "loadingRecords": "Chargement...", 68 "processing": "Traitement...", 69 // "search": "Rechercher Code NOR:", 70 "zeroRecords": "Aucun élément correspondant trouvé", 71 "paginate": { 72 "first": "Premier", 73 "last": "Dernier", 74 "next": "Suivant", 75 "previous": "Précédent" 76 }, 77 "aria": { 78 "sortAscending": ": activer pour trier la colonne par ordre croissant", 79 "sortDescending": ": activer pour trier la colonne par ordre décroissant" 80 } 81 } 82 }); 83 84 $('#ccr-reset-filter').on('click', function () { 85 $('#search_code_nor').val(""); 86 const typeSMS = document.getElementById('select_type').__sms; 87 const anneeSMS = document.getElementById('year_type').__sms; 88 const departement_select = document.getElementById('departement_select').__sms; 89 const commune_select = document.getElementById('commune_select').__sms; 90 91 typeSMS.setValue([]); 92 typeSMS.setData(typeSMS.data); 93 94 anneeSMS.setValue([]); 95 anneeSMS.setData(anneeSMS.data); 96 97 departement_select.setValue([]); 98 departement_select.setData(departement_select.data); 99 100 commune_select.setValue([]); 101 commune_select.setData(commune_select.data); 102 103 table.ajax.reload(); 104 }); 105 106 function renderPictos(row) { 107 const map = { 108 "00": "", 109 "10": "_Inondations_jaune.png", 110 "15": "_Inondations_jaune.png", 111 "20": "_Mouvement-de-terrain_jaune.png", 112 '30': '_Avalanches_jaune.png', 113 "40": "_Seisme_jaune.png", 114 '45': '_Vents-cycloniques_jaune.png', 115 '49': "", 116 "50": "_Vents-cycloniques_jaune.png", 117 '54': '_Erosion_jaune.png', 118 "55": "_Secheresse_jaune.png", 119 '59': '_Volcan_jaune.png', 120 '60': '_Tsunami_jaune.png', 121 '61': '_Submersion_jaune.png', 122 '65': '_Tsunami_jaune.png', 123 '70': '', 124 '80': '_Orages_jaune.png', 125 '90': '_Grele_jaune.png', 126 }; 127 128 let html = ''; 129 html += `<div class="div-img-type">`; 130 let codePeril = (row.codePeril || '').split(', '); 131 countPeril = codePeril.map(item => item.trim()); 132 var classImg = countPeril.length === 1 ? '' : 'img-max'; 133 const addedIcons = new Set(); 134 (row.codePeril || '').split(', ').forEach(code => { 135 // if (map[code]) { 136 // html += `<img class="ccr-icon `+classImg+`" src="${CCR_ARRETES.icons}${map[code]}">`; 137 // } 138 const iconFile = map[code]; 139 if (iconFile && !addedIcons.has(iconFile)) { 140 addedIcons.add(iconFile); 141 html += `<img class="ccr-icon ` + classImg + `" src="${CCR_ARRETES.icons}${iconFile}">`; 142 } 143 }); 144 html += ` </div>`; 145 146 return html; 147 } 148 149 150 // Gestion des filtres pour la recherche 151 $('#select_type').on('change', function (e) { 152 table.column(0).search(e.originalEvent.detail).draw(); 153 }); 154 //Filtre par code nor 155 $('#search_code_nor').on('input', function () { 156 table.column(7).search(this.value).draw(); 157 }); 158 // 159 $("#year_type").on("change", function (e) { 160 table.column(3).search(e.originalEvent.detail).draw(); 161 }); 162 // 163 $("#departement_select").on("change", function (e) { 164 var codeDep = e.originalEvent.detail; 165 // var val = codeDep.trim(); 166 // var len = val.length; 167 168 if (codeDep !== 'undefined') { 169 table.column(5).search('^' + codeDep, true, false).draw(); 170 } else { 171 table.column(5).search('').draw(); 172 } 173 174 loadCommunesFromDepartements(codeDep); 175 }); 176 177 $('#commune_select').on('change', function (e) { 178 var data = e.originalEvent.detail; 179 table.column(6).search(data).draw(); 180 // loadDepartementFromCommune(data); 181 }); 182 183 // Télécharger le CSV pour un arrêté spécifique 184 $("#ccr-arretes-table").on("click", ".export-csv", function (e) { 185 e.preventDefault(); 186 var codeArrete = $(this).data("id");
187 window.location.href = ajaxUrl + "?action=export_csv&codeArrete=" + codeArrete; 188 }); 189 190 191 192 193 // --- 1) Initialisation du multiselect pour les départements --- 194 // $('#departement_select').multiselect({ 195 // includeSelectAllOption: false, 196 // enableFiltering: true, 197 // enableCaseInsensitiveFiltering: true, 198 // nSelectedText: 'département(s) sélectionné(s)', 199 // allSelectedText: 'Tous les départements', 200 // nonSelectedText: 'Départements', 201 // buttonWidth: '100%', 202 // filterPlaceholder: 'Rechercher...', 203 // }); 204 205 // $('#commune_select').multiselect({ 206 // includeSelectAllOption: false, 207 // enableFiltering: true, 208 // enableCaseInsensitiveFiltering: true, 209 // nSelectedText: 'Commune(s) sélectionné(s)', 210 // allSelectedText: 'Toutes les communes', 211 // nonSelectedText: 'Communes', 212 // buttonWidth: '100%', 213 // filterPlaceholder: 'Rechercher...', 214 // }); 215 216 let searchTimer = null; 217 218 $(document).on('input', '.multiselect-search', function () { 219 // Vérifie qu'on est bien sur le multiselect commune 220 if (!$(this).closest('.multiselect-container').prev().attr('id') === 'commune_select') { 221 return; 222 } 223 let keyword = $(this).val(); 224 // console.log(keyword.length); 225 if (keyword.length >= 3) { 226 clearTimeout(searchTimer); 227 searchTimer = setTimeout(function () { 228 // chargerCommunes(keyword, 100); 229 }, 400); 230 } 231 232 233 }); 234 235 236 // Default Commune 237 loadInitialCommunes(); 238 239 // function loadDepartement() { 240 // let $select = $('#commune_select'); 241 // // ð 1. Sauvegarder les valeurs déjà sélectionnées 242 // let selectedValues = $select.val() || []; 243 // let selectedTexts = {}; 244 // // Sauvegarder aussi les libellés 245 // $select.find('option:selected').each(function () { 246 // selectedTexts[$(this).val()] = $(this).text(); 247 // }); 248 // } 249 250 async function loadInitialCommunes() { 251 const smsCommunes = document.getElementById('commune_select').__sms; 252 const url = "https://geo.api.gouv.fr/communes?fields=nom,code&format=json&limit=100"; 253 const res = await fetch(url); 254 const communes = await res.json(); 255 256 const data = communes.map(c => ({ 257 value: c.code, 258 label: c.nom 259 })); 260 261 smsCommunes.setData(data); 262 } 263 264 searchCommuneViaInput(); 265 async function searchCommuneViaInput () { 266 const commune = document.getElementById('Commune_search'); 267 commune.addEventListener('input', function (e){ 268 const term = e.target.value; 269 if (term.length >= 2) { 270 searchCommuneTerm(term); 271 }else if (term.length === 0) { 272 loadInitialCommunes(); 273 } 274 }); 275 276 } 277 278 async function searchCommuneTerm(term){ 279 const el = document.getElementById('commune_select'); 280 if (!el || !el.__sms) { 281 console.warn('[loadCommunesFromDepartements] SimpleMultiSelect non initialisé sur #commune_select'); 282 return; 283 } 284 const sms = el.__sms; 285 286 const previouslySelectedValues = sms.getValue(); 287 const previouslySelectedMap = new Map( 288 Array.from(sms.selected.values()).map(o => [String(o.value), o.label]) 289 ); 290 el.classList.add('ms-loading'); // si tu as un style .ms-loading 291 try { 292 const url = `https://geo.api.gouv.fr/communes?nom=${encodeURIComponent(term)}&fields=code,nom&boost=population&limit=50`; 293 294 const r = await fetch(url); 295 if (!r.ok) throw new Error(`HTTP ${r.status}`); 296 const json = await r.json(); 297 const data = json 298 .filter(c => c && c.code && c.nom) 299 .map(c => ({ value: String(c.code), label: String(c.nom) })); 300 sms.setData(data); 301 302 } catch (err) { 303 console.error('[loadCommunesFromDepartements] Erreur API:', err); 304 } finally { 305 el.classList.remove('ms-loading'); 306 } 307 308 } 309 /** 310 * Met à jour #commune_select (SimpleMultiSelect) à partir d'une liste de codes départements 311 * @param {string[]} departementCodes - ex: ["75","13"] 312 */ 313 async function loadCommunesFromDepartements(departementCodes = []) { 314 // 0) Garde-fous 315 if (!Array.isArray(departementCodes) || departementCodes.length === 0) { 316 return; 317 } 318 319 // 1) Récupérer l'instance SimpleMultiSelect 320 const el = document.getElementById('commune_select'); 321 if (!el || !el.__sms) { 322 console.warn('[loadCommunesFromDepartements] SimpleMultiSelect non initialisé sur #commune_select'); 323 return; 324 } 325 const sms = el.__sms; 326 327 // 2) Sauvegarder la sélection courante (values + labels) 328 const previouslySelectedValues = sms.getValue(); // ex: ["75056","13055"] 329 const previouslySelectedMap = new Map( 330 Array.from(sms.selected.values()).map(o => [String(o.value), o.label]) 331 ); 332 333 // 3) Optionnel : indiquer le chargement (désactiver UI, class CSS, etc.) 334 el.classList.add('ms-loading'); // si tu as un style .ms-loading 335 try { 336 // 4) Appels API parallèles 337 // https://geo.api.gouv.fr/departements/{code}/communes â [{ code, nom, ...}, ...] 338 const urls = departementCodes.map(code => 339 `https://geo.api.gouv.fr/departements/${encodeURIComponent(code)}/communes` 340 ); 341 342 const responses = await Promise.all(urls.map(u => fetch(u))); 343 const jsons = await Promise.all(responses.map(r => { 344 if (!r.ok) throw new Error(`HTTP ${r.status}`); 345 return r.json(); 346 })); 347 348 // 5) Aplatir et dédupliquer (code commune â nom) 349 const optionsMap = new Map(); 350 for (const arr of jsons) { 351 const list = Array.isArray(arr) ? arr : []; 352 for (const c of list) { 353 if (c && c.code && c.nom) { 354 // Priorité au premier rencontré, sinon écrasement indifférent (même nom) 355 if (!optionsMap.has(String(c.code))) { 356 optionsMap.set(String(c.code), String(c.nom)); 357 } 358 } 359 } 360 } 361 362 // 6) Réinjecter les communes déjà sélectionnées si absentes 363 for (const val of previouslySelectedValues) { 364 if (!optionsMap.has(String(val))) { 365 const label = previouslySelectedMap.get(String(val)) || String(val); 366 optionsMap.set(String(val), label); 367 } 368 } 369 370 // 7) Construire le dataset pour SimpleMultiSelect 371 const data = Array.from(optionsMap.entries()) 372 .sort((a, b) => a[1].localeCompare(b[1], 'fr')) // tri par nom de commune 373 .map(([code, nom]) => ({ value: code, label: nom })); 374 375 // 8) Appliquer dataset + re-sélection 376 sms.setData(data); 377 if (previouslySelectedValues.length) { 378 sms.setValue(previouslySelectedValues); 379 } 380 381 } catch (err) { 382 console.error('[loadCommunesFromDepartements] Erreur API:', err); 383 // TODO: afficher un message utilisateur si tu veux 384 } finally { 385 el.classList.remove('ms-loading'); 386 } 387 } 388 /** 389 * Quand un département est choisi, on charge les communes --- 390 */ 391 /** 392 * Met à jour #departement_select (SimpleMultiSelect) selon les codes communes 393 * @param {string[]} communeCodes - ex: ["75056", "13055"] 394 */ 395 async function loadDepartementFromCommune(communeCodes = []) { 396 // 0) Garde-fous 397 if (!Array.isArray(communeCodes) || communeCodes.length === 0) { 398 loadAllDepartements(); 399 return; 400 } 401 402 // 1) Récupérer l'instance SimpleMultiSelect 403 const el = document.getElementById('departement_select'); 404 if (!el || !el.__sms) { 405 console.warn('[loadDepartementFromCommune] SimpleMultiSelect non initialisé sur #departement_select'); 406 return; 407 } 408 const sms = el.__sms; 409 410 // 2) Sauvegarder la sélection en cours (values et labels) 411 const previouslySelectedValues = sms.getValue(); // ex: ["75","69"] 412 const previouslySelectedMap = new Map( 413 Array.from(sms.selected.values()).map(o => [String(o.value), o.label]) 414 ); 415 416 // 3) Appels API (Promise.all) vers geo.api.gouv.fr 417 // Format attendu: GET https://geo.api.gouv.fr/communes/{code}?fields=departement 418 const urls = communeCodes.map(code => 419 `https://geo.api.gouv.fr/communes/${encodeURIComponent(code)}?fields=departement` 420 ); 421 422 let results = []; 423 try { 424 const responses = await Promise.all(urls.map(u => fetch(u))); 425 const jsons = await Promise.all(responses.map(r => { 426 if (!r.ok) throw new Error(`HTTP ${r.status}`); 427 return r.json(); 428 })); 429 results = jsons; // chaque élément contient potentiellement { departement: { code, nom }, ... } 430 } catch (err) { 431 console.error('[loadDepartementFromCommune] Erreur API:', err); 432 // tu peux afficher un toast / message si besoin 433 return; 434 } 435 436 // 4) Construire une map unique code -> nom 437 const optionsMap = new Map(); 438 for (const item of results) { 439 // Certains endpoints peuvent renvoyer un tableau, on gère les deux cas par robustesse 440 const arr = Array.isArray(item) ? item : [item]; 441 for (const c of arr) { 442 const dep = c && c.departement; 443 if (dep && dep.code && dep.nom) { 444 optionsMap.set(String(dep.code), String(dep.nom)); 445 } 446 } 447 } 448 449 // 5) Réinjecter les valeurs déjà sélectionnées si absentes (préserver la sélection manuelle) 450 for (const val of previouslySelectedValues) { 451 if (!optionsMap.has(String(val))) { 452 const label = previouslySelectedMap.get(String(val)) || String(val); 453 optionsMap.set(String(val), label); 454 } 455 } 456 457 // 6) Construire le dataset pour SimpleMultiSelect 458 // [{ value:"75", label:"Paris (75)" }, ...] (tu peux décider lâaffichage label) 459 // Ici on met "Nom (Code)" pour lisibilité 460 const data = Array.from(optionsMap.entries()) 461 .sort((a, b) => a[0].localeCompare(b[0], 'fr')) // tri par code (ou par nom si tu préfères) 462 .map(([code, nom]) => ({ 463 value: code, 464 label: `${nom} (${code})` 465 })); 466 467 // 7) Appliquer dans le SimpleMultiSelect 468 sms.setData(data); 469 if (previouslySelectedValues.length) { 470 // On essaie de re-sélectionner ce qui était déjà c
470oché 471 // (si certaines values ne sont plus dans data, setValue les ignore) 472 sms.setValue(previouslySelectedValues); 473 } 474 } 475 476 async function loadAllDepartements() { 477 const el = document.getElementById('departement_select'); 478 if (!el || !el.__sms) return; 479 const sms = el.__sms; 480 481 el.classList.add('ms-loading'); 482 try { 483 const url = "https://geo.api.gouv.fr/departements?fields=code,nom&format=json"; 484 const r = await fetch(url); 485 const json = await r.json(); 486 487 const data = json 488 .filter(d => d.code && d.nom) 489 .sort((a, b) => a.nom.localeCompare(b.nom, 'fr')) 490 .map(d => ({value: d.code, label: `${d.nom}`})); 491 492 sms.setData(data); 493 // pas de setValue(), on laisse sélection vide 494 } finally { 495 el.classList.remove('ms-loading'); 496 } 497 } 498 499 /** 500 * Détection de changement sur le select Département 501 */ 502 // $('#departement_select').on('change', function () { 503 // const selectedDeps = $(this).val() || []; 504 // 505 // }); 506 507 /** 508 * Détection de changement sur le select Commune 509 */ 510 // $('#commune_select').on('change', function () { 511 // const selectedCom = $(this).val() || []; 512 // loadDepartementFromCommune(selectedCom); 513 // }); 514 515 516 $("#reset_filter").click(function () { 517 $('#search_code_nor').val(''); 518 // $('#select_type, #year_type, #departement_select').multiselect('deselectAll', false); 519 // $('#select_type, #year_type, #departement_select').multiselect('updateButtonText'); 520 // $('#commune_select').val(null).trigger('change'); 521 table.ajax.reload(); 522 }); 523 $(document).on("click", '.paginate_button', function () { 524 const offset = $('#tag_arretes_list').offset().top; 525 const correction = 120; // ajuste ici : 50, 80, 120⦠526 527 $('html, body').animate({ 528 scrollTop: offset - correction 529 }, 600); 530 }); 531 532 /** 533 * NORMALISATION 534 */ 535 function normalize(str) { 536 return str 537 .toLowerCase() 538 .normalize('NFD') 539 .replace(/[\u0300-\u036f]/g, ''); 540 } 541});
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.