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

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

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

لاستخدام ميزة "الإكمال التلقائي للأماكن" (الإصدار التجريبي)، عليك تفعيل Places API في مشروعك على 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);

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

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

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

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

إذا لم تقدِّم أي حدود أو مساحة عرض للخريطة، ستحاول واجهة برمجة التطبيقات رصد موقع المستخدم الجغرافي من عنوان IP الخاص به، وستؤثّر في النتائج لتظهر في ذلك الموقع الجغرافي. حدِّد حدودًا كلما أمكن. بخلاف ذلك، قد يتلقّى مستخدمون مختلفون توقّعات مختلفة. بالإضافة إلى ذلك، لتحسين التوقعات بشكل عام، من المهم توفير مساحة عرض معقولة، مثل المساحة التي تحدّدها من خلال التمرير أو magnification على الخريطة، أو مساحة عرض يحدّدها المطوّر استنادًا إلى الموقع الجغرافي للجهاز والنطاق. عندما لا يتوفّر نطاق جغرافي، يُعدّ 5 كيلومتر قيمة تلقائية مناسبة لميزة "الإكمال التلقائي للأماكن". لا تضبط إطار عرض بنصف قطر صفري (نقطة واحدة) أو إطار عرض لا يتجاوز عرضه بضعة أمتار (أقل من 100 متر) أو إطار عرض يمتد على مستوى الكرة الأرضية.

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

لحصر البحث عن الأماكن ببلد واحد أو أكثر، استخدِم السمة 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-placeselect إلى 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;
});

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

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

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

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

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

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 أو بدون إطار عمل على الإطلاق.