مكان التطبيق المصغّر للإكمال التلقائي (معاينة)

أداة الإكمال التلقائي للمكان تنشئ حقل إدخال نصي، وتوفر تنبؤات في قائمة اختيارات واجهة المستخدم، وتعرض مكان التفاصيل ردًا على اختيار المستخدم. استخدِم تطبيق Place Autocomplete Widget لتضمين واجهة مستخدم كاملة ومكتفية ذاتيًا للإكمال التلقائي على صفحة الويب.

المتطلبات الأساسية

لاستخدام ميزة "الإكمال التلقائي للأماكن" (معاينة)، يجب تفعيل "واجهة برمجة تطبيقات الأماكن" على Google Cloud وحدد القناة التجريبية (v: "beta") في برنامج الإقلاع. عرض البدء لمعرفة التفاصيل

الميزات الجديدة

تم تحسين ميزة "الإكمال التلقائي للأماكن" (الإصدار التجريبي) بالطرق التالية:

  • تتيح واجهة مستخدم التطبيق المصغّر للإكمال التلقائي الترجمة والشرح على مستوى منطقة معيّنة (بما في ذلك اللغات التي تُكتب من اليمين إلى اليسار)، وذلك لأجل عنصر النائب لإدخال النص وشعار قائمة الاقتراحات واقتراحات الأماكن.
  • إمكانية وصول محسّنة، بما في ذلك دعم برامج قراءة الشاشة والتفاعل باستخدام لوحة المفاتيح
  • تعرض أداة الإكمال التلقائي فئة المكان الجديدة لتبسيط التعامل مع العنصر الذي تم إرجاعه.
  • دعم أفضل للأجهزة الجوّالة والشاشات الصغيرة.
  • أداء أفضل ومظهر رسومي محسّن

إضافة تطبيق مصغّر للإكمال التلقائي

يمكنك إضافة تطبيق مصغّر لإكمال تلقائي إلى صفحة ويب أو خريطة Google. تنشئ أداة الإكمال التلقائي حقل إدخال نص، وتوفر تنبؤات في قائمة اختيارات واجهة المستخدم، وتعرض تفاصيل المكان في الرد على نقرة أحد المستخدمين من خلال مستمع gmp-placeselect. يعرض لك هذا القسم وكيفية إضافة أداة للإكمال التلقائي إلى صفحة ويب أو خريطة Google.

إضافة تطبيق مصغّر لميزة "الإكمال التلقائي" إلى صفحة ويب

لإضافة التطبيق المصغّر "الإكمال التلقائي" إلى صفحة ويب، أنشئ عنصر google.maps.places.PlaceAutocompleteElement جديدًا وألصقه في الصفحة كما هو موضّح في المثال التالي:

TypeScript

// Request needed libraries.
//@ts-ignore
await google.maps.importLibrary("places") as google.maps.PlacesLibrary;
// Create the input HTML element, and append it.
//@ts-ignore
const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement();
//@ts-ignore
document.body.appendChild(placeAutocomplete);

JavaScript

// Request needed libraries.
//@ts-ignore
await google.maps.importLibrary("places");

// Create the input HTML element, and append it.
//@ts-ignore
const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement();

//@ts-ignore
document.body.appendChild(placeAutocomplete);

الاطّلاع على مثال الرمز البرمجي الكامل

إضافة أداة إكمال تلقائي إلى خريطة

لإضافة أداة "الإكمال التلقائي" إلى خريطة، أنشئ مثيلًا جديدًا من google.maps.places.PlaceAutocompleteElement، وأضِف PlaceAutocompleteElement إلى div، ثمّ ادفعه إلى الخريطة كعنصر تحكّم مخصّص ، كما هو موضّح في المثال التالي:

TypeScript

//@ts-ignore
const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement();
//@ts-ignore
placeAutocomplete.id = 'place-autocomplete-input';

const card = document.getElementById('place-autocomplete-card') as HTMLElement;
//@ts-ignore
card.appendChild(placeAutocomplete);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(card);

JavaScript

//@ts-ignore
const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement();

//@ts-ignore
placeAutocomplete.id = "place-autocomplete-input";

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

//@ts-ignore
card.appendChild(placeAutocomplete);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(card);

الاطّلاع على مثال الرمز الكامل

تقييد عبارات البحث المقترَحة من خلال ميزة "الإكمال التلقائي"

بشكل تلقائي، تعرض ميزة "الإكمال التلقائي للأماكن" جميع أنواع الأماكن، وتكون متحيّزة للتوقعات القريبة من مكان تواجد المستخدم الموقع، واسترجاع جميع حقول البيانات المتاحة للمكان الذي اختاره المستخدم. يمكنك ضبط خيارات الإكمال التلقائي لميزة "مكان" لعرض توقعات أكثر صلة من خلال تقييد النتائج أو توجيهها.

يؤدي تقييد النتائج إلى تجاهل أداة الإكمال التلقائي لأي نتائج خارج منطقة القيود. من الممارسات الشائعة حصر النتائج بحدود الخريطة. يؤدي التركيز على نتائج معيّنة إلى عرض التطبيق المصغّر للإكمال التلقائي للنتائج ضمن المنطقة المحدّدة، ولكن قد تكون بعض المطابقات خارج هذه المنطقة.

حصر البحث عن الأماكن حسب البلد

لقصر البحث عن الأماكن على بلد واحد أو أكثر تحديدًا، استخدم componentRestrictions لتحديد رموز البلدان كما هو موضح في المقتطف التالي:

const pac = new google.maps.places.PlaceAutocompleteElement({
  componentRestrictions: {country: ['us', 'au']},
});

حصر البحث عن الأماكن بحدود الخريطة

لتقييد البحث عن الأماكن بحدود خريطة معيّنة، استخدِم السمة locationRestrictions لإضافة الحدود، كما هو موضّح في المقتطف التالي:

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

عند تقييد البيانات بحدود الخريطة، احرص على إضافة مستمع لتعديل الحدود عند تغييرها:

map.addListener('bounds_changed', () => {
  autocomplete.locationRestriction = map.getBounds();
});

لإزالة locationRestriction، اضبطها على null.

الانحياز في نتائج البحث عن الأماكن

يؤدي انحياز النتائج إلى منطقة دائرة باستخدام السمة locationBias مرور نصف قطر، كما هو موضح هنا:

const autocomplete = new google.maps.places.PlaceAutocompleteElement({
  locationBias: {radius: 100, center: {lat: 50.064192, lng: -130.605469}},
});

لإزالة "locationBias"، يجب ضبطه على null.

حصر نتائج البحث عن الأماكن بأنواع معيّنة

يمكنك حصر نتائج البحث عن الأماكن بأنواع معيّنة من الأماكن باستخدام السمة types وتحديد نوع واحد أو أكثر، كما هو موضّح هنا:

const autocomplete = new google.maps.places.PlaceAutocompleteElement({
  types: ['establishment'],
});

للحصول على قائمة كاملة بالأنواع المتوافقة، اطّلِع على الجدول 3: الأنواع المتوافقة مع طلبات الإكمال التلقائي للأماكن.

الحصول على تفاصيل المكان

للحصول على تفاصيل المكان المحدّد، يمكنك إضافة مستمع gmp-place-select إلى PlaceAutocompleteElement، كما هو موضح في المثال التالي:

TypeScript

// Add the gmp-placeselect listener, and display the results.
//@ts-ignore
placeAutocomplete.addEventListener('gmp-placeselect', async ({ place }) => {
    await place.fetchFields({ fields: ['displayName', 'formattedAddress', 'location'] });

    selectedPlaceTitle.textContent = 'Selected Place:';
    selectedPlaceInfo.textContent = JSON.stringify(
        place.toJSON(), /* replacer */ null, /* space */ 2);
});

JavaScript

// Add the gmp-placeselect listener, and display the results.
//@ts-ignore
placeAutocomplete.addEventListener("gmp-placeselect", async ({ place }) => {
  await place.fetchFields({
    fields: ["displayName", "formattedAddress", "location"],
  });
  selectedPlaceTitle.textContent = "Selected Place:";
  selectedPlaceInfo.textContent = JSON.stringify(
    place.toJSON(),
    /* replacer */ null,
    /* space */ 2,
  );
});

الاطّلاع على مثال الرمز الكامل

في المثال السابق، يعرض مستمع الأحداث عنصرًا من فئة Place. يمكنك الاتصال بالرقم place.fetchFields() للحصول على حقول بيانات تفاصيل المكان. اللازمة لطلبك.

يطلب المستمع في المثال التالي معلومات عن المكان ويعرضها على الخريطة.

TypeScript

// Add the gmp-placeselect listener, and display the results on the map.
//@ts-ignore
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;
});

JavaScript

// Add the gmp-placeselect listener, and display the results on the map.
//@ts-ignore
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;
});

الاطّلاع على مثال الرمز الكامل

الحصول على نتائج ترميز جغرافي للمكان المحدّد

للحصول على نتائج ترميز الموقع الجغرافي للمكان المحدّد، استخدِم google.maps.Geocoder للحصول على الموقع، كما هو موضح في المقتطف التالي:

const map = new google.maps.Map(document.getElementById('map'), {
  center: {lat: 50.064192, lng: -130.605469},
  zoom: 3,
});

const marker = new google.maps.Marker({map});
const autocomplete = new google.maps.places.PlaceAutocompleteElement();
const geocoder = new google.maps.Geocoder();

autocomplete.addListener('gmp-placeselect', async ({prediction: place}) => {
  const results = await geocoder.geocode({place.id});
  marker.setPlace({
    placeId: place.id,
    location: results[0].geometry.location,
  });
});

أمثلة على الخرائط

يحتوي هذا القسم على الرمز الكامل لأمثلة الخرائط المعروضة في هذه الصفحة.

عنصر الإكمال التلقائي

يضيف هذا المثال أداة "الإكمال التلقائي" إلى صفحة ويب، ويعرض النتائج لكل مكان تم اختياره.

TypeScript

async function initMap(): Promise<void> {
    // Request needed libraries.
    //@ts-ignore
    await google.maps.importLibrary("places") as google.maps.PlacesLibrary;
    // Create the input HTML element, and append it.
    //@ts-ignore
    const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement();
    //@ts-ignore
    document.body.appendChild(placeAutocomplete);

    // Inject HTML UI.
    const selectedPlaceTitle = document.createElement('p');
    selectedPlaceTitle.textContent = '';
    document.body.appendChild(selectedPlaceTitle);

    const selectedPlaceInfo = document.createElement('pre');
    selectedPlaceInfo.textContent = '';
    document.body.appendChild(selectedPlaceInfo);

    // Add the gmp-placeselect listener, and display the results.
    //@ts-ignore
    placeAutocomplete.addEventListener('gmp-placeselect', async ({ place }) => {
        await place.fetchFields({ fields: ['displayName', 'formattedAddress', 'location'] });

        selectedPlaceTitle.textContent = 'Selected Place:';
        selectedPlaceInfo.textContent = JSON.stringify(
            place.toJSON(), /* replacer */ null, /* space */ 2);
    });
}

initMap();

JavaScript

async function initMap() {
  // Request needed libraries.
  //@ts-ignore
  await google.maps.importLibrary("places");

  // Create the input HTML element, and append it.
  //@ts-ignore
  const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement();

  //@ts-ignore
  document.body.appendChild(placeAutocomplete);

  // Inject HTML UI.
  const selectedPlaceTitle = document.createElement("p");

  selectedPlaceTitle.textContent = "";
  document.body.appendChild(selectedPlaceTitle);

  const selectedPlaceInfo = document.createElement("pre");

  selectedPlaceInfo.textContent = "";
  document.body.appendChild(selectedPlaceInfo);
  // Add the gmp-placeselect listener, and display the results.
  //@ts-ignore
  placeAutocomplete.addEventListener("gmp-placeselect", async ({ place }) => {
    await place.fetchFields({
      fields: ["displayName", "formattedAddress", "location"],
    });
    selectedPlaceTitle.textContent = "Selected Place:";
    selectedPlaceInfo.textContent = JSON.stringify(
      place.toJSON(),
      /* replacer */ null,
      /* space */ 2,
    );
  });
}

initMap();

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

p {
  font-family: Roboto, sans-serif;
  font-weight: bold;
}

HTML

<html>
  <head>
    <title>Place Autocomplete element</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <p style="font-family: roboto, sans-serif">Search for a place here:</p>

    <!-- prettier-ignore -->
    <script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})
        ({key: "AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg", v: "beta"});</script>
  </body>
</html>

تجربة عيّنة

الإكمال التلقائي للخريطة

يوضّح لك هذا المثال كيفية إضافة تطبيق مصغّر لإكمال تلقائي إلى خريطة Google.

TypeScript

let map: google.maps.Map;
let marker: google.maps.marker.AdvancedMarkerElement;
let infoWindow: google.maps.InfoWindow;
async function initMap(): Promise<void> {
    // Request needed libraries.
    //@ts-ignore
    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') as HTMLElement, {
        center: { lat: 40.749933, lng: -73.98633 },
        zoom: 13,
        mapId: '4504f8b37365c3d0',
        mapTypeControl: false,
    });
    //@ts-ignore
    const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement();
    //@ts-ignore
    placeAutocomplete.id = 'place-autocomplete-input';

    const card = document.getElementById('place-autocomplete-card') as HTMLElement;
    //@ts-ignore
    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.
    //@ts-ignore
    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,
    });
}

initMap();

JavaScript

let map;
let marker;
let infoWindow;

async function initMap() {
  // Request needed libraries.
  //@ts-ignore
  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,
  });

  //@ts-ignore
  const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement();

  //@ts-ignore
  placeAutocomplete.id = "place-autocomplete-input";

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

  //@ts-ignore
  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.
  //@ts-ignore
  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,
  });
}

initMap();

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#place-autocomplete-card {
  background-color: #fff;
  border-radius: 5px;
  box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
  margin: 10px;
  padding: 5px;
  font-family: Roboto, sans-serif;
  font-size: large;
  font-weight: bold;
}

gmp-place-autocomplete {
  width: 300px;
}

#infowindow-content .title {
  font-weight: bold;
}

#map #infowindow-content {
  display: inline;
}

HTML

<html>
  <head>
    <title>Place Autocomplete map</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div class="place-autocomplete-card" id="place-autocomplete-card">
      <p>Search for a place here:</p>
    </div>
    <div id="map"></div>

    <!-- prettier-ignore -->
    <script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})
        ({key: "AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg", v: "beta"});</script>
  </body>
</html>

تجربة عيّنة

استخدام مكوّن "أداة اختيار الأماكن"

عنصر أداة اختيار الأماكن هو إدخال نصي يتيح للمستخدمين النهائيين البحث عن عنوان أو مكان معيّن باستخدام ميزة "الإكمال التلقائي". وهي جزء من مكتبة المكوّنات الموسّعة، وهي مجموعة من مكوّنات الويب التي تساعد المطوّرين في إنشاء خرائط وميزات مواقع جغرافية أفضل بشكل أسرع.

استخدام أداة ضبط "أداة اختيار الأماكن" لإنشاء رمز قابل للتضمين لمكوّن "منتقي الأماكن" المخصص، ثم تصدير لاستخدامه مع أطر عمل شائعة مثل React وAngular أو عدم استخدامه على الإطلاق.