Migrer vers la nouvelle fonctionnalité Place Autocomplete

Place Autocomplete est une fonctionnalité de la bibliothèque Places de l'API Maps JavaScript. Vous pouvez utiliser la saisie semi-automatique pour reproduire dans votre application le comportement de frappe anticipée qu'utilise le champ de recherche de Google Maps.

Cette page explique les différences entre les anciennes et les nouvelles fonctionnalités de saisie semi-automatique de lieux. Dans les deux versions, il existe deux façons générales d'intégrer la saisie semi-automatique:

  • Interface programmatique: pour les développeurs qui souhaitent personnaliser et contrôler davantage l'expérience de saisie semi-automatique.
  • Widget Place Autocomplete: barre de recherche pouvant être intégrée à une carte ou à une page Web.

Interface programmatique de saisie semi-automatique

Le tableau suivant présente certaines des principales différences d'utilisation de Place Autocomplete programmatique entre le service Place Autocomplete (ancien) et l'API Autocomplete Data (nouvelle):

PlacesService (ancienne) Place (nouveau)
Documentation de référence du service Place Autocomplete Référence Données de saisie semi-automatique (nouvelles)
AutocompletionRequest AutocompleteRequest
AutocompleteService.getPlacePredictions AutocompleteSuggestion.fetchAutocompleteSuggestions
AutocompletePrediction PlacePrediction
Les méthodes nécessitent l'utilisation d'un rappel pour gérer l'objet de résultats et la réponse PlacesServiceStatus. Utilise des promesses et fonctionne de manière asynchrone.
Les méthodes nécessitent une vérification PlacesServiceStatus. Aucune vérification d'état requise. Vous pouvez utiliser la gestion des erreurs standard.
Les champs de données de lieu sont définis en tant qu'options lors de la création de l'instance Autocomplete. Les champs de données de lieu sont définis ultérieurement lorsque fetchFields() est appelé.
Les prédictions de requêtes sont acceptées (SearchBox uniquement). Les prédictions de requêtes ne sont pas disponibles dans la classe Autocomplete.
Limité à un ensemble fixe de types d'établissements et de champs de données sur les établissements. Accès à une sélection étendue de types d'établissements et de champs de données sur les établissements.

Les éléments suivants sont utilisés à la fois par les anciennes et les nouvelles API Autocomplete:

Comparaison de code (programmation)

Cette section compare le code de saisie semi-automatique pour illustrer les différences entre le service Places et la classe Place, pour les interfaces programmatiques.

Récupérer des prédictions de saisie semi-automatique (ancienne méthode)

L'ancien service Places vous permet de récupérer des prédictions de saisie semi-automatique de manière programmatique, ce qui vous permet de contrôler davantage l'interface utilisateur que la classe Autocomplete. Dans l'exemple suivant, une seule requête est effectuée pour "par", avec une AutocompletionRequest composée de la valeur d'entrée et d'un ensemble de limites pour biaiser la prédiction. L'exemple renvoie une liste d'instances AutocompletePrediction et affiche la description de chacune d'elles. L'exemple de fonction crée également un jeton de session et l'applique à la requête.

function init() {
  const placeInfo = document.getElementById("prediction");
  const service = new google.maps.places.AutocompleteService();
  const placesService = new google.maps.places.PlacesService(placeInfo);
  var sessionToken = new google.maps.places.AutocompleteSessionToken();

  // Define request options.
  let request = {
    input: "par",
    sessionToken: sessionToken,
    bounds: {
      west: -122.44,
      north: 37.8,
      east: -122.39,
      south: 37.78,
    },
  }

  // Display the query string.
  const title = document.getElementById("title");
  title.appendChild(
    document.createTextNode('Place predictions for "' + request.input + '":'),
  );

  // Perform the query and display the results.
  const displaySuggestions = function (predictions, status) {
    // Check the status of the Places Service.
    if (status != google.maps.places.PlacesServiceStatus.OK || !predictions) {
      alert(status);
      return;
    }

    predictions.forEach((prediction) => {
      const li = document.createElement("li");
      li.appendChild(document.createTextNode(prediction.description));
      document.getElementById("results").appendChild(li);
    });

    const placeRequest = {
      placeId: predictions[0].place_id,
      fields: ["name", "formatted_address"],
    };

    placesService.getDetails(placeRequest, (place, status) => {
      if (status == google.maps.places.PlacesServiceStatus.OK && place) {
        placeInfo.textContent = `
          First predicted place: ${place.name} at ${place.formatted_address}`
      }
    });

  };

  // Show the results of the query.
  service.getPlacePredictions(request, displaySuggestions);
}

Récupérer des prédictions de saisie semi-automatique (nouveau)

La nouvelle classe Place vous permet également de récupérer des prédictions de saisie semi-automatique par programmation pour mieux contrôler l'interface utilisateur que la classe PlaceAutocompleteElement. Dans l'exemple suivant, une seule requête est effectuée pour "par", avec une AutocompleteRequest composée de la valeur d'entrée et d'un ensemble de limites pour biaiser la prédiction. L'exemple renvoie une liste d'instances placePrediction et affiche la description de chacune d'elles. L'exemple de fonction crée également un jeton de session et l'applique à la requête.

async function init() {
  let sessionToken = new google.maps.places.AutocompleteSessionToken();

  // Define request options.
  let request = {
    input: "par",
    sessionToken: sessionToken,
    locationBias: {
      west: -122.44,
      north: 37.8,
      east: -122.39,
      south: 37.78,
    },
  };

  // Display the query string.
  const title = document.getElementById("title");
  title.appendChild(
    document.createTextNode('Place predictions for "' + request.input + '":'),
  );

  // Perform the query and display the results.
  const { suggestions } =
    await google.maps.places.AutocompleteSuggestion.fetchAutocompleteSuggestions(request);

  const resultsElement = document.getElementById("results");

  for (let suggestion of suggestions) {
    const placePrediction = suggestion.placePrediction;
    const listItem = document.createElement("li");

    listItem.appendChild(
      document.createTextNode(placePrediction.text.text),
    );

    resultsElement.appendChild(listItem);
  }

  // Show the first predicted place.
  let place = suggestions[0].placePrediction.toPlace();

  await place.fetchFields({
    fields: ["displayName", "formattedAddress"],
  });

  const placeInfo = document.getElementById("prediction");

  placeInfo.textContent = `
    First predicted place: ${place.displayName} at ${place.formattedAddress}`
}

Widget Place Autocomplete

Le tableau suivant présente certaines des principales différences d'utilisation des widgets de saisie semi-automatique entre le service Places (ancien) et la classe Place (nouvelle):

Service Places (ancien) Lieu (nouveau)
Classe Autocomplete pour les prédictions de lieux. Classe PlaceAutocompleteElement pour les prédictions de lieux.
Classe SearchBox
pour les prédictions de requêtes.
Les prédictions de requêtes ne sont pas disponibles dans la classe Autocomplete.
Seul le texte d'espace réservé de saisie par défaut est localisé. L'espace réservé de saisie de texte, le logo de la liste de prédictions et les prédictions de lieux sont tous compatibles avec la localisation régionale.
Le widget utilise setBounds() ou autocomplete.bindTo() pour limiter (biaiser) la recherche aux limites spécifiées, et strictBounds pour limiter les résultats aux limites spécifiées. Le widget utilise la propriété locationBias pour pondérer les résultats en fonction des limites spécifiées et la propriété locationRestriction pour limiter la recherche aux limites spécifiées.
Les widgets ne peuvent être intégrés qu'à l'aide d'un élément d'entrée HTML standard. Le widget peut être intégré à l'aide d'un élément d'entrée HTML standard ou d'un élément gmp-place-autocomplete.
Lorsque vous utilisez le widget, les utilisateurs peuvent demander des éléments qui ne sont pas valides (par exemple, "bisneyland"). Ce cas doit être géré explicitement. Le widget ne renvoie que les résultats des suggestions fournies et ne peut pas émettre de requêtes pour des valeurs arbitraires. Il n'est donc pas nécessaire de gérer les requêtes potentiellement non valides.
Renvoie l'ancienne instance PlaceResult. Renvoie une instance Place.
Les champs de données de lieu sont définis comme options pour l'objet Autocomplete. Les champs de données de lieu sont définis lorsque l'utilisateur effectue une sélection et que fetchFields() est appelé.
Limité à un ensemble fixe de types d'établissements et de champs de données sur les établissements. Accès à une sélection étendue de types d'établissements et de champs de données sur les établissements.

Comparaison de code (widgets)

Cette section compare le code de saisie semi-automatique pour illustrer les différences entre l'ancien widget Place Autocomplete et le nouvel élément Place Autocomplete.

Widget Place Autocomplete (ancien)

Le service Places propose deux types de widgets de saisie semi-automatique, que vous pouvez ajouter à l'aide des classes Autocomplete et SearchBox. Chaque type de widget peut être ajouté à une carte en tant que commande de carte ou intégré directement à une page Web. L'exemple de code suivant montre l'intégration d'un widget Autocomplete en tant que commande de carte.

  • Le constructeur du widget Autocomplete utilise deux arguments :
    • Un élément HTML input de type text. Il s'agit du champ d'entrée que le service de saisie semi-automatique surveille et auquel il associe ses résultats.
    • Un argument AutocompleteOptions facultatif, dans lequel vous pouvez spécifier d'autres options pour contraindre la requête.
  • Pour définir des limites, l'instance Autocomplete peut être associée explicitement à la carte en appelant autocomplete.bindTo().
  • Spécifiez les champs de données de lieu dans les options de saisie semi-automatique.
function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 40.749933, lng: -73.98633 },
    zoom: 13,
    mapTypeControl: false,
  });
  const card = document.getElementById("pac-card");
  const input = document.getElementById("pac-input");
  const options = {
    fields: ["formatted_address", "geometry", "name"],
    strictBounds: false,
  };

  map.controls[google.maps.ControlPosition.TOP_LEFT].push(card);

  const autocomplete = new google.maps.places.Autocomplete(input, options);

  // Bind the map's bounds (viewport) property to the autocomplete object,
  // so that the autocomplete requests use the current map bounds for the
  // bounds option in the request.
  autocomplete.bindTo("bounds", map);

  const infowindow = new google.maps.InfoWindow();
  const infowindowContent = document.getElementById("infowindow-content");

  infowindow.setContent(infowindowContent);

  const marker = new google.maps.Marker({
    map,
    anchorPoint: new google.maps.Point(0, -29),
  });

  autocomplete.addListener("place_changed", () => {
    infowindow.close();
    marker.setVisible(false);

    const place = autocomplete.getPlace();

    if (!place.geometry || !place.geometry.location) {
      // User entered the name of a Place that was not suggested and
      // pressed the Enter key, or the Place Details request failed.
      window.alert("No details available for input: '" + place.name + "'");
      return;
    }

    // If the place has a geometry, then present it on a map.
    if (place.geometry.viewport) {
      map.fitBounds(place.geometry.viewport);
    } else {
      map.setCenter(place.geometry.location);
      map.setZoom(17);
    }

    marker.setPosition(place.geometry.location);
    marker.setVisible(true);
    infowindowContent.children["place-name"].textContent = place.name;
    infowindowContent.children["place-address"].textContent =
      place.formatted_address;
    infowindow.open(map, marker);
  });
}

Widget Place Autocomplete (nouveau)

La classe Place propose PlaceAutocompleteElement, une sous-classe HTMLElement qui fournit un composant d'interface utilisateur pouvant être ajouté à une carte en tant que commande de carte ou intégré directement sur une page Web. L'exemple de code suivant montre l'intégration d'un widget PlaceAutocompleteElement en tant que commande de carte.

Voici les améliorations que nous avons apportées au widget Place Autocomplete:

  • L'interface utilisateur du widget Autocomplete prend en charge la localisation régionale (y compris les langues RTL) pour l'espace réservé de saisie de texte, le logo de la liste de prédictions et les prédictions de lieux.
  • Amélioration de l'accessibilité, y compris la prise en charge des lecteurs d'écran et l'interaction avec le clavier.
  • Le widget Autocomplete renvoie la nouvelle classe Place pour simplifier le traitement de l'objet renvoyé.
  • Meilleure prise en charge des appareils mobiles et petits écrans.
  • Performances et apparence graphique améliorées.

Voici les principales différences d'implémentation:

  • Les prédictions de requêtes ne sont pas disponibles dans la classe Autocomplete.
  • PlaceAutocompleteElement est construit à l'aide de PlaceAutocompleteElementOptions.
  • Les champs de données de lieu sont spécifiés au moment de la sélection (lorsque fetchFields() est appelé).
  • Définissez des limites à l'aide de l'option locationBounds ou locationRestriction.
  • Associez le PlaceAutocompleteElement à un élément de saisie de texte HTML à l'aide de l'attribut id (hérité de HTMLElement).
let map;
let marker;
let infoWindow;

async function initMap() {
  // Request needed libraries.
  const [{ Map }, { AdvancedMarkerElement }] = await Promise.all([
    google.maps.importLibrary("marker"),
    google.maps.importLibrary("places"),
  ]);

  // Initialize the map.
  map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 40.749933, lng: -73.98633 },
    zoom: 13,
    mapId: "4504f8b37365c3d0",
    mapTypeControl: false,
  });

  const placeAutocomplete =
    new google.maps.places.PlaceAutocompleteElement({
      locationRestriction: map.getBounds(),
    });

  placeAutocomplete.id = "place-autocomplete-input";
  const card = document.getElementById("place-autocomplete-card");

  card.appendChild(placeAutocomplete);
  map.controls[google.maps.ControlPosition.TOP_LEFT].push(card);

  // Create the marker and infowindow.
  marker = new google.maps.marker.AdvancedMarkerElement({
    map,
  });
  infoWindow = new google.maps.InfoWindow({});

  // Add the gmp-placeselect listener, and display the results on the map.
  placeAutocomplete.addEventListener("gmp-placeselect", async ({ place }) => {
    await place.fetchFields({
      fields: ["displayName", "formattedAddress", "location"],
    });
    // If the place has a geometry, then present it on a map.
    if (place.viewport) {
      map.fitBounds(place.viewport);
    } else {
      map.setCenter(place.location);
      map.setZoom(17);
    }

    let content =
      '<div id="infowindow-content">' +
      '<span id="place-displayname" class="title">' +
      place.displayName +
      '</span><br />' +
      '<span id="place-address">' +
      place.formattedAddress +
      '</span>' +
      '</div>';

    updateInfoWindow(content, place.location);
    marker.position = place.location;
  });
}

// Helper function to create an info window.
function updateInfoWindow(content, center) {
  infoWindow.setContent(content);
  infoWindow.setPosition(center);
  infoWindow.open({
    map,
    anchor: marker,
    shouldFocus: false,
  });
}