177 lines
6.9 KiB
HTML
177 lines
6.9 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html lang="fr">
|
||
|
<head>
|
||
|
<meta charset="UTF-8">
|
||
|
<title>Communes de France</title>
|
||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.3/css/bulma.min.css">
|
||
|
<style>
|
||
|
.container { max-width: 800px; }
|
||
|
.is-loading::after {
|
||
|
content: '';
|
||
|
display: inline-block;
|
||
|
width: 1em;
|
||
|
height: 1em;
|
||
|
border: 2px solid #ccc;
|
||
|
border-top-color: #333;
|
||
|
border-radius: 50%;
|
||
|
animation: spin 1s infinite linear;
|
||
|
margin-left: 10px;
|
||
|
}
|
||
|
@keyframes spin {
|
||
|
to { transform: rotate(360deg); }
|
||
|
}
|
||
|
</style>
|
||
|
</head>
|
||
|
<body>
|
||
|
<div class="container mt-4">
|
||
|
<h1 class="title has-text-centered">Rechercher des communes</h1>
|
||
|
<div class="field">
|
||
|
<label class="label">Région</label>
|
||
|
<div class="control">
|
||
|
<div class="select is-fullwidth">
|
||
|
<select id="regionSelect"></select>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="field">
|
||
|
<label class="label">Département</label>
|
||
|
<div class="control">
|
||
|
<div class="select is-fullwidth">
|
||
|
<select id="departementSelect" disabled></select>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="field">
|
||
|
<label class="label">Rechercher une commune</label>
|
||
|
<div class="control">
|
||
|
<input class="input" type="text" id="searchInput" placeholder="Nom de la commune..." disabled>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="field is-grouped">
|
||
|
<div class="control">
|
||
|
<button id="sortBtn" class="button is-info" disabled>Trier</button>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div id="communesList" class="box mt-4"></div>
|
||
|
</div>
|
||
|
|
||
|
<script>
|
||
|
const regionSelect = document.getElementById('regionSelect');
|
||
|
const departementSelect = document.getElementById('departementSelect');
|
||
|
const searchInput = document.getElementById('searchInput');
|
||
|
const sortBtn = document.getElementById('sortBtn');
|
||
|
const communesList = document.getElementById('communesList');
|
||
|
let allCommunes = [];
|
||
|
let sortOrder = 'asc';
|
||
|
|
||
|
const fetchRegions = async () => {
|
||
|
const url = 'https://geo.api.gouv.fr/regions';
|
||
|
try {
|
||
|
const response = await fetch(url);
|
||
|
const regions = await response.json();
|
||
|
regionSelect.innerHTML = '<option value="">-- Sélectionnez une région --</option>';
|
||
|
regions.forEach(region => {
|
||
|
regionSelect.innerHTML += `<option value="${region.code}">${region.nom}</option>`;
|
||
|
});
|
||
|
} catch (error) {
|
||
|
console.error('Erreur de chargement des régions:', error);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
const fetchDepartements = async (regionCode) => {
|
||
|
departementSelect.disabled = true;
|
||
|
departementSelect.classList.add('is-loading');
|
||
|
const url = `https://geo.api.gouv.fr/regions/${regionCode}/departements`;
|
||
|
try {
|
||
|
const response = await fetch(url);
|
||
|
const departements = await response.json();
|
||
|
departementSelect.innerHTML = '<option value="">-- Sélectionnez un département --</option>';
|
||
|
departements.forEach(dep => {
|
||
|
departementSelect.innerHTML += `<option value="${dep.code}">${dep.nom} (${dep.code})</option>`;
|
||
|
});
|
||
|
} catch (error) {
|
||
|
console.error('Erreur de chargement des départements:', error);
|
||
|
} finally {
|
||
|
departementSelect.disabled = false;
|
||
|
departementSelect.classList.remove('is-loading');
|
||
|
}
|
||
|
};
|
||
|
|
||
|
const fetchCommunes = async (departementCode) => {
|
||
|
searchInput.disabled = true;
|
||
|
sortBtn.disabled = true;
|
||
|
communesList.innerHTML = '<p class="has-text-centered is-loading">Chargement des communes...</p>';
|
||
|
const url = `https://geo.api.gouv.fr/departements/${departementCode}/communes`;
|
||
|
try {
|
||
|
const response = await fetch(url);
|
||
|
allCommunes = await response.json();
|
||
|
renderCommunes(allCommunes);
|
||
|
} catch (error) {
|
||
|
console.error('Erreur de chargement des communes:', error);
|
||
|
communesList.innerHTML = '<p class="has-text-danger has-text-centered">Erreur de chargement des communes.</p>';
|
||
|
} finally {
|
||
|
searchInput.disabled = false;
|
||
|
sortBtn.disabled = false;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
const renderCommunes = (communes) => {
|
||
|
communesList.innerHTML = '';
|
||
|
if (communes.length === 0) {
|
||
|
communesList.innerHTML = '<p class="has-text-centered">Aucune commune trouvée.</p>';
|
||
|
return;
|
||
|
}
|
||
|
const ul = document.createElement('ul');
|
||
|
communes.forEach(commune => {
|
||
|
const li = document.createElement('li');
|
||
|
li.textContent = `${commune.nom} (Code postal: ${commune.codesPostaux[0]})`;
|
||
|
ul.appendChild(li);
|
||
|
});
|
||
|
communesList.appendChild(ul);
|
||
|
};
|
||
|
|
||
|
regionSelect.addEventListener('change', (e) => {
|
||
|
if (e.target.value) {
|
||
|
fetchDepartements(e.target.value);
|
||
|
} else {
|
||
|
departementSelect.innerHTML = '<option value="">-- Sélectionnez un département --</option>';
|
||
|
departementSelect.disabled = true;
|
||
|
searchInput.disabled = true;
|
||
|
sortBtn.disabled = true;
|
||
|
communesList.innerHTML = '';
|
||
|
}
|
||
|
});
|
||
|
|
||
|
departementSelect.addEventListener('change', (e) => {
|
||
|
if (e.target.value) {
|
||
|
fetchCommunes(e.target.value);
|
||
|
} else {
|
||
|
searchInput.disabled = true;
|
||
|
sortBtn.disabled = true;
|
||
|
communesList.innerHTML = '';
|
||
|
}
|
||
|
});
|
||
|
|
||
|
searchInput.addEventListener('input', (e) => {
|
||
|
const searchTerm = e.target.value.toLowerCase();
|
||
|
const filteredCommunes = allCommunes.filter(c => c.nom.toLowerCase().includes(searchTerm));
|
||
|
renderCommunes(filteredCommunes);
|
||
|
});
|
||
|
|
||
|
sortBtn.addEventListener('click', () => {
|
||
|
sortOrder = sortOrder === 'asc' ? 'desc' : 'asc';
|
||
|
allCommunes.sort((a, b) => {
|
||
|
const nameA = a.nom.toLowerCase();
|
||
|
const nameB = b.nom.toLowerCase();
|
||
|
if (nameA < nameB) return sortOrder === 'asc' ? -1 : 1;
|
||
|
if (nameA > nameB) return sortOrder === 'asc' ? 1 : -1;
|
||
|
return 0;
|
||
|
});
|
||
|
renderCommunes(allCommunes);
|
||
|
});
|
||
|
|
||
|
fetchRegions();
|
||
|
</script>
|
||
|
</body>
|
||
|
</html>
|