Documentation

Formulaire d

Créez des formulaires d'adresse professionnels avec des selects en cascade pays, région et ville

Apprenez à créer un formulaire d'adresse complet avec des listes déroulantes pays → région → ville en utilisant les endpoints select de CountryDataAPI.

Aperçu

Ce guide vous montre comment créer des inputs select en cascade pour :

  • Sélection du pays - Charger tous les pays disponibles
  • Sélection de la région/province - Filtré par le pays sélectionné
  • Sélection de la ville - Filtré par la région sélectionnée

Les endpoints select sont optimisés pour les formulaires, ne retournant que les champs id et name pour une taille de payload minimale et des performances maximales.

Prérequis

  • Une clé API CountryDataAPI (Obtenez-en une ici)
  • Connaissance de base de JavaScript et HTML
  • Navigateur moderne avec support de l'API fetch

Étape 1 : Charger les Pays

D'abord, chargez tous les pays au chargement de votre page. Les pays changent rarement, vous pouvez donc mettre ces données en cache dans localStorage pour de meilleures performances.

const API_KEY = 'votre-cle-api';
const BASE_URL = 'https://api.countrydataapi.com/v1';

async function loadCountries() {
  try {
    const response = await fetch(
      `${BASE_URL}/select/countries?apikey=${API_KEY}&lang=fr`
    );
    const { success, data, error } = await response.json();

    if (!success) {
      console.error('Erreur API:', error);
      return;
    }

    const countrySelect = document.getElementById('country');
    data.forEach(country => {
      const option = new Option(country.name, country.id);
      countrySelect.add(option);
    });
  } catch (err) {
    console.error('Erreur Réseau:', err);
  }
}

// Appeler au chargement de la page
document.addEventListener('DOMContentLoaded', loadCountries);

Astuce : Mettez la liste des pays en cache dans localStorage pour éviter les appels API répétés. Les pays ne changent pas fréquemment !

Étape 2 : Charger les Régions Quand le Pays Change

Quand un utilisateur sélectionne un pays, chargez les régions/provinces correspondantes et réinitialisez la liste déroulante des villes.

document.getElementById('country').addEventListener('change', async (e) => {
  const countryId = e.target.value;
  const stateSelect = document.getElementById('state');
  const citySelect = document.getElementById('city');

  // Réinitialiser les listes déroulantes région et ville
  stateSelect.innerHTML = '<option value="">Sélectionnez une région...</option>';
  citySelect.innerHTML = '<option value="">Sélectionnez une ville...</option>';
  stateSelect.disabled = true;
  citySelect.disabled = true;

  if (!countryId) return;

  try {
    const response = await fetch(
      `${BASE_URL}/select/states?apikey=${API_KEY}&country=${countryId}&lang=fr`
    );
    const { success, data, error } = await response.json();

    if (!success) {
      console.error('Erreur API:', error);
      return;
    }

    data.forEach(state => {
      stateSelect.add(new Option(state.name, state.id));
    });

    stateSelect.disabled = false;
  } catch (err) {
    console.error('Erreur Réseau:', err);
  }
});

Étape 3 : Charger les Villes Quand la Région Change

Enfin, chargez les villes quand une région est sélectionnée.

document.getElementById('state').addEventListener('change', async (e) => {
  const stateId = e.target.value;
  const citySelect = document.getElementById('city');

  // Réinitialiser la liste déroulante ville
  citySelect.innerHTML = '<option value="">Sélectionnez une ville...</option>';
  citySelect.disabled = true;

  if (!stateId) return;

  try {
    const response = await fetch(
      `${BASE_URL}/select/cities?apikey=${API_KEY}&state=${stateId}&lang=fr`
    );
    const { success, data, error } = await response.json();

    if (!success) {
      console.error('Erreur API:', error);
      return;
    }

    data.forEach(city => {
      citySelect.add(new Option(city.name, city.id));
    });

    citySelect.disabled = false;
  } catch (err) {
    console.error('Erreur Réseau:', err);
  }
});

Exemple HTML Complet

<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Formulaire d'Adresse - CountryDataAPI</title>
  <style>
    body {
      font-family: system-ui, -apple-system, sans-serif;
      max-width: 600px;
      margin: 50px auto;
      padding: 20px;
    }
    .form-group {
      margin-bottom: 20px;
    }
    label {
      display: block;
      margin-bottom: 8px;
      font-weight: 600;
      color: #333;
    }
    select {
      width: 100%;
      padding: 10px;
      border: 2px solid #e2e8f0;
      border-radius: 6px;
      font-size: 16px;
      background-color: white;
      cursor: pointer;
    }
    select:disabled {
      background-color: #f7fafc;
      cursor: not-allowed;
      opacity: 0.6;
    }
    select:focus {
      outline: none;
      border-color: #3b82f6;
    }
    button {
      background-color: #3b82f6;
      color: white;
      padding: 12px 24px;
      border: none;
      border-radius: 6px;
      font-size: 16px;
      font-weight: 600;
      cursor: pointer;
      width: 100%;
    }
    button:disabled {
      background-color: #cbd5e0;
      cursor: not-allowed;
    }
  </style>
</head>
<body>
  <h1>Formulaire d'Adresse</h1>

  <form id="address-form">
    <div class="form-group">
      <label for="country">Pays *</label>
      <select id="country" name="country" required>
        <option value="">Sélectionnez un pays...</option>
      </select>
    </div>

    <div class="form-group">
      <label for="state">Région *</label>
      <select id="state" name="state" required disabled>
        <option value="">Sélectionnez une région...</option>
      </select>
    </div>

    <div class="form-group">
      <label for="city">Ville *</label>
      <select id="city" name="city" required disabled>
        <option value="">Sélectionnez une ville...</option>
      </select>
    </div>

    <div class="form-group">
      <label for="street">Adresse *</label>
      <input type="text" id="street" name="street" required
             style="width: 100%; padding: 10px; border: 2px solid #e2e8f0; border-radius: 6px;">
    </div>

    <button type="submit">Envoyer l'Adresse</button>
  </form>

  <script src="address-form.js"></script>
</body>
</html>

Soumission du Formulaire

Gérez la soumission du formulaire pour obtenir les valeurs sélectionnées :

document.getElementById('address-form').addEventListener('submit', (e) => {
  e.preventDefault();

  const formData = new FormData(e.target);
  const address = {
    country: formData.get('country'),
    state: formData.get('state'),
    city: formData.get('city'),
    street: formData.get('street')
  };

  console.log('Adresse soumise:', address);

  // Envoyez à votre backend ou traitez selon vos besoins
  // fetch('/api/save-address', {
  //   method: 'POST',
  //   headers: { 'Content-Type': 'application/json' },
  //   body: JSON.stringify(address)
  // });
});

Utilisation des Tokens

Cette implémentation est très efficace en termes d'utilisation de tokens :

  • 1 token pour charger les pays (une fois par chargement de page, peut être mis en cache)
  • 1 token par recherche de régions (quand l'utilisateur sélectionne un pays)
  • 1 token par recherche de villes (quand l'utilisateur sélectionne une région)

Exemple : Un utilisateur remplissant le formulaire complètement utilise seulement 3 tokens au total.

Conseils d'Optimisation

1. Mettre en Cache les Données des Pays

Les pays ne changent pas souvent. Mettez-les en cache dans localStorage :

async function loadCountries() {
  const cached = localStorage.getItem('countries');

  if (cached) {
    const data = JSON.parse(cached);
    populateCountrySelect(data);
    return;
  }

  const response = await fetch(
    `${BASE_URL}/select/countries?apikey=${API_KEY}&lang=fr`
  );
  const { success, data } = await response.json();

  if (success) {
    localStorage.setItem('countries', JSON.stringify(data));
    populateCountrySelect(data);
  }
}

function populateCountrySelect(countries) {
  const select = document.getElementById('country');
  countries.forEach(country => {
    select.add(new Option(country.name, country.id));
  });
}

2. Ajouter des États de Chargement

Affichez un retour visuel pendant le chargement des données :

async function loadStates(countryId) {
  const stateSelect = document.getElementById('state');
  stateSelect.innerHTML = '<option>Chargement...</option>';
  stateSelect.disabled = true;

  // ... récupérer les régions

  stateSelect.disabled = false;
}

3. Debounce sur l'Entrée de Recherche

Si vous ajoutez une liste déroulante avec recherche, utilisez le debounce sur l'entrée :

let debounceTimer;
searchInput.addEventListener('input', (e) => {
  clearTimeout(debounceTimer);
  debounceTimer = setTimeout(() => {
    filterOptions(e.target.value);
  }, 300);
});

4. Gérer les Erreurs avec Élégance

Fournissez toujours des messages d'erreur conviviaux :

try {
  // Appel API
} catch (err) {
  const select = document.getElementById('state');
  select.innerHTML = '<option>Erreur de chargement des régions. Veuillez réessayer.</option>';
}

Support Multi-langues

L'API supporte plusieurs langues. Changez le paramètre lang :

// Espagnol
`${BASE_URL}/select/countries?apikey=${API_KEY}&lang=es`

// Portugais
`${BASE_URL}/select/countries?apikey=${API_KEY}&lang=pt`

// Français
`${BASE_URL}/select/countries?apikey=${API_KEY}&lang=fr`

// Allemand
`${BASE_URL}/select/countries?apikey=${API_KEY}&lang=de`

// Italien
`${BASE_URL}/select/countries?apikey=${API_KEY}&lang=it`

Prochaines Étapes

Besoin d'Aide ?

Si vous avez des questions ou avez besoin d'assistance :


Astuce Pro : Pour les applications en production, envisagez d'implémenter un composant dropdown personnalisé avec fonctionnalité de recherche pour gérer les pays avec de nombreuses régions/villes. Des bibliothèques comme Select2, Choices.js ou un autocomplete personnalisé peuvent améliorer significativement l'expérience utilisateur.