jolie beau et ajax
This commit is contained in:
parent
7475c3ce49
commit
42ec68178a
11 changed files with 242 additions and 76 deletions
112
views/_partial/apigeo.tpl
Normal file
112
views/_partial/apigeo.tpl
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
<!-- Script d'autocomplétion ville/département — API Géo (gouvernement français) -->
|
||||
<script>
|
||||
(function () {
|
||||
const input = document.getElementById('user_location');
|
||||
const suggestions = document.getElementById('location-suggestions');
|
||||
let debounceTimer = null;
|
||||
|
||||
// Ferme la liste si on clique ailleurs
|
||||
document.addEventListener('click', function (e) {
|
||||
if (!input.contains(e.target) && !suggestions.contains(e.target)) {
|
||||
hideSuggestions();
|
||||
}
|
||||
});
|
||||
|
||||
input.addEventListener('input', function () {
|
||||
const query = this.value.trim();
|
||||
|
||||
clearTimeout(debounceTimer);
|
||||
|
||||
if (query.length < 2) {
|
||||
hideSuggestions();
|
||||
return;
|
||||
}
|
||||
|
||||
// Délai de 300 ms pour éviter trop d'appels API
|
||||
debounceTimer = setTimeout(function () {
|
||||
fetchCities(query);
|
||||
}, 300);
|
||||
});
|
||||
|
||||
// Navigation clavier dans la liste
|
||||
input.addEventListener('keydown', function (e) {
|
||||
const items = suggestions.querySelectorAll('.list-group-item');
|
||||
const active = suggestions.querySelector('.list-group-item.active');
|
||||
let index = Array.from(items).indexOf(active);
|
||||
|
||||
if (e.key === 'ArrowDown') {
|
||||
e.preventDefault();
|
||||
if (index < items.length - 1) setActive(items, index + 1);
|
||||
} else if (e.key === 'ArrowUp') {
|
||||
e.preventDefault();
|
||||
if (index > 0) setActive(items, index - 1);
|
||||
} else if (e.key === 'Enter' && active) {
|
||||
e.preventDefault();
|
||||
selectItem(active.dataset.value);
|
||||
} else if (e.key === 'Escape') {
|
||||
hideSuggestions();
|
||||
}
|
||||
});
|
||||
|
||||
function fetchCities(query) {
|
||||
// On cherche par nom de commune, on récupère aussi le département
|
||||
const url = 'https://geo.api.gouv.fr/communes?nom=' + encodeURIComponent(query)
|
||||
+ '&fields=nom,departement&boost=population&limit=8';
|
||||
|
||||
fetch(url)
|
||||
.then(function (res) { return res.json(); })
|
||||
.then(function (data) { renderSuggestions(data); })
|
||||
.catch(function () { hideSuggestions(); });
|
||||
}
|
||||
|
||||
function renderSuggestions(cities) {
|
||||
suggestions.innerHTML = '';
|
||||
|
||||
if (!cities || cities.length === 0) {
|
||||
hideSuggestions();
|
||||
return;
|
||||
}
|
||||
|
||||
cities.forEach(function (city) {
|
||||
const dept = city.departement
|
||||
? city.departement.nom + ' (' + city.departement.code + ')'
|
||||
: '';
|
||||
const label = city.nom + (dept ? ' — ' + dept : '');
|
||||
// Valeur stockée : "Ville (Département)"
|
||||
const value = city.nom + (city.departement ? ' (' + city.departement.nom + ')' : '');
|
||||
|
||||
const li = document.createElement('li');
|
||||
li.className = 'list-group-item list-group-item-action py-2 px-3';
|
||||
li.style.cursor = 'pointer';
|
||||
li.dataset.value = value;
|
||||
li.textContent = label;
|
||||
|
||||
li.addEventListener('mousedown', function (e) {
|
||||
// mousedown avant blur pour éviter que la liste disparaisse avant le clic
|
||||
e.preventDefault();
|
||||
selectItem(value);
|
||||
});
|
||||
|
||||
suggestions.appendChild(li);
|
||||
});
|
||||
|
||||
suggestions.style.display = 'block';
|
||||
}
|
||||
|
||||
function selectItem(value) {
|
||||
input.value = value;
|
||||
hideSuggestions();
|
||||
}
|
||||
|
||||
function hideSuggestions() {
|
||||
suggestions.style.display = 'none';
|
||||
suggestions.innerHTML = '';
|
||||
}
|
||||
|
||||
function setActive(items, index) {
|
||||
items.forEach(function (item) { item.classList.remove('active'); });
|
||||
items[index].classList.add('active');
|
||||
input.value = items[index].dataset.value;
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
Loading…
Add table
Add a link
Reference in a new issue