Phần tử cơ bản của tính năng Place Autocomplete

BasicPlaceAutocompleteElement tạo một trường nhập văn bản, cung cấp thông tin dự đoán về địa điểm trong danh sách lựa chọn trên giao diện người dùng và trả về mã địa điểm cho địa điểm đã chọn.

Phần tử Place Autocomplete cơ bản dễ triển khai hơn so với PlaceAutocompleteElement và có những điểm khác biệt sau:

  • Phần tử Basic Place Autocomplete trả về một đối tượng Địa điểm chỉ chứa Mã địa điểm, thay vì một đối tượng PlacePrediction. Bạn có thể sử dụng trực tiếp Mã địa điểm được trả về cùng với một phần tử Places UI Kit Details để lấy thêm Place Details, trong khi đối tượng PlacePrediction trước tiên sẽ yêu cầu chuyển đổi thành Mã địa điểm.
  • Phần tử Basic Place Autocomplete không yêu cầu bạn bật Places API trong Google Cloud Console.
  • Phần tử Tự động hoàn thành địa điểm cơ bản sẽ xoá trường nhập dữ liệu khi người dùng chọn một cụm từ gợi ý về địa điểm.

Điều kiện tiên quyết

Để sử dụng thành phần Tự động hoàn thành địa điểm cơ bản, bạn phải bật Bộ công cụ giao diện người dùng Địa điểm trong dự án Google Cloud của mình. Hãy xem phần Bắt đầu để biết thông tin chi tiết.

Thêm phần tử Place Autocomplete cơ bản

Phần này hướng dẫn bạn cách thêm phần tử Tự động hoàn thành cơ bản vào trang web hoặc bản đồ.

Thêm phần tử Tự động hoàn thành cơ bản vào trang web

Để thêm phần tử BasicAutocomplete vào trang web, hãy tạo một google.maps.places.BasicPlaceAutocompleteElement mới và thêm phần tử đó vào trang như trong ví dụ sau:

// Request needed libraries.
const {BasicPlaceAutocompleteElement} = await google.maps.importLibrary('places');
// Create the input HTML element and append it.
const placeAutocomplete = new BasicPlaceAutocompleteElement();
document.body.appendChild(placeAutocomplete);

Thêm phần tử Tự động hoàn thành cơ bản vào bản đồ

Để thêm phần tử Tự động hoàn thành cơ bản vào bản đồ, hãy thêm BasicPlaceAutocompleteElement vào phần tử gmp-map và đặt vị trí của phần tử đó bằng thuộc tính slot, như trong ví dụ sau:

<gmp-map
    zoom="12"
    center="37.4220656,-122.0840897"
    map-id="DEMO_MAP_ID">
    <gmp-basic-place-autocomplete
        slot="control-inline-start-block-start"></gmp-basic-place-autocomplete>
</gmp-map>

Hạn chế cụm từ gợi ý của tính năng tự động hoàn thành

Theo mặc định, tính năng Place Autocomplete cơ bản sẽ hiển thị tất cả các loại địa điểm, ưu tiên các cụm từ gợi ý gần vị trí của người dùng. Đặt BasicPlaceAutocompleteElementOptions để trình bày các cụm từ gợi ý phù hợp hơn bằng cách hạn chế hoặc thiên vị kết quả.

Việc hạn chế kết quả sẽ khiến phần tử Tự động hoàn thành cơ bản bỏ qua mọi kết quả nằm ngoài khu vực hạn chế. Một phương pháp phổ biến là giới hạn kết quả trong ranh giới bản đồ. Việc thiên vị kết quả khiến phần tử BasicAutocomplete hiển thị kết quả trong khu vực được chỉ định, nhưng một số kết quả phù hợp có thể nằm ngoài khu vực đó.

Nếu bạn không cung cấp bất kỳ ranh giới hoặc khung nhìn bản đồ nào, thì API sẽ cố gắng phát hiện vị trí của người dùng từ địa chỉ IP của họ và sẽ ưu tiên kết quả cho vị trí đó. Đặt giới hạn bất cứ khi nào có thể. Nếu không, những người dùng khác nhau có thể nhận được thông tin dự đoán khác nhau. Ngoài ra, để cải thiện thông tin dự đoán nói chung, bạn cần cung cấp một khung nhìn hợp lý, chẳng hạn như khung nhìn mà bạn đặt bằng cách kéo hoặc thu phóng trên bản đồ, hoặc khung nhìn do nhà phát triển đặt dựa trên vị trí và bán kính của thiết bị. Khi không có bán kính, 5 km được coi là giá trị mặc định hợp lý cho phần tử Place Autocomplete cơ bản. Đừng đặt khung nhìn có bán kính bằng 0 (một điểm duy nhất), khung nhìn chỉ rộng vài mét (dưới 100 m) hoặc khung nhìn trải dài trên toàn cầu.

Hạn chế tìm kiếm địa điểm theo quốc gia

Để giới hạn kết quả tìm kiếm địa điểm ở một hoặc nhiều quốc gia cụ thể, hãy sử dụng thuộc tính includedRegionCodes để chỉ định(các) mã quốc gia như trong đoạn mã sau:

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

Giới hạn phạm vi tìm kiếm địa điểm trong ranh giới trên bản đồ

Để giới hạn phạm vi tìm kiếm địa điểm trong ranh giới của bản đồ, hãy sử dụng thuộc tính locationRestrictions để thêm ranh giới, như trong đoạn mã sau:

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

Khi giới hạn ranh giới trên bản đồ, hãy nhớ thêm trình nghe để cập nhật ranh giới khi chúng thay đổi:

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

Để xoá locationRestriction, hãy đặt giá trị thành null.

Kết quả tìm kiếm địa điểm thiên vị

Thiên vị kết quả tìm kiếm địa điểm cho một khu vực hình tròn bằng cách sử dụng thuộc tính locationBias và truyền bán kính, như minh hoạ dưới đây:

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

Để xoá locationBias, hãy đặt thành null.

Hạn chế kết quả tìm kiếm địa điểm theo một số loại nhất định

Hạn chế kết quả tìm kiếm địa điểm đối với một số loại địa điểm nhất định bằng cách sử dụng thuộc tính includedPrimaryTypes và chỉ định một hoặc nhiều loại, như minh hoạ dưới đây:

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

Để xem danh sách đầy đủ các loại được hỗ trợ, hãy xem Bảng loại địa điểm A và B.

Định cấu hình phần tử Place Request (Yêu cầu địa điểm)

Thêm trình nghe để cập nhật phần tử Yêu cầu địa điểm khi người dùng chọn một cụm từ gợi ý:

// Event listener for when a place is selected from the autocomplete list.
placeAutocompleteElement.addEventListener('gmp-select', (event) => {
    // Reset marker and InfoWindow, and prepare the details element.
    placeDetailsParent.appendChild(placeDetailsElement);
    placeDetailsElement.style.display = 'block';
    advancedMarkerElement.position = null;
    infoWindow.close();

    // Request details for the selected place.
    const placeDetailsRequest = placeDetailsElement.querySelector(
        'gmp-place-details-place-request'
    );
    placeDetailsRequest.place = event.place.id;
});

Ví dụ này cho bạn biết cách thêm một phần tử Tự động hoàn thành cơ bản vào bản đồ Google.

JavaScript

const placeAutocompleteElement = document.querySelector(
    'gmp-basic-place-autocomplete'
);
const placeDetailsElement = document.querySelector('gmp-place-details-compact');
const placeDetailsParent = placeDetailsElement.parentElement;
const gmpMapElement = document.querySelector('gmp-map');

async function init() {
    // Asynchronously load required libraries from the Google Maps JS API.
    const [{ AdvancedMarkerElement }, { InfoWindow, Circle }, { Size }] =
        await Promise.all([
            google.maps.importLibrary('marker'),
            google.maps.importLibrary('maps'),
            google.maps.importLibrary('core'),
            google.maps.importLibrary('places'),
        ]);

    // Get the initial center directly from the gmp-map element's property.
    const center = gmpMapElement.center;

    // Set the initial location bias for the autocomplete element.
    placeAutocompleteElement.locationBias = center;

    // Update the map object with specified options.
    const map = gmpMapElement.innerMap;
    map.setOptions({
        clickableIcons: false,
        mapTypeControl: false,
        streetViewControl: false,
    });

    // Create an advanced marker to show the location of a selected place.
    const advancedMarkerElement = new AdvancedMarkerElement({
        map,
        collisionBehavior: 'REQUIRED_AND_HIDES_OPTIONAL',
    });

    // Create an InfoWindow to hold the place details component.
    const infoWindow = new InfoWindow({
        minWidth: 360,
        disableAutoPan: true,
        headerDisabled: true,
        pixelOffset: new Size(0, -10),
    });

    // Event listener for when a place is selected from the autocomplete list.
    placeAutocompleteElement.addEventListener('gmp-select', (event) => {
        // Reset marker and InfoWindow, and prepare the details element.
        placeDetailsParent.appendChild(placeDetailsElement);
        placeDetailsElement.style.display = 'block';
        advancedMarkerElement.position = null;
        infoWindow.close();

        // Request details for the selected place.
        const placeDetailsRequest = placeDetailsElement.querySelector(
            'gmp-place-details-place-request'
        );
        placeDetailsRequest.place = event.place.id;
    });

    // Event listener for when the place details have finished loading.
    placeDetailsElement.addEventListener('gmp-load', () => {
        const location = placeDetailsElement.place?.location;
        if (!location) {
            advancedMarkerElement.position = null;
            return;
        }

        // Position the marker and open the InfoWindow at the place's location.
        advancedMarkerElement.position = location;
        infoWindow.setContent(placeDetailsElement);
        infoWindow.open({
            map,
            anchor: advancedMarkerElement,
        });
        map.setCenter(location);
    });

    // Event listener to close the InfoWindow when the map is clicked.
    map.addListener('click', () => {
        infoWindow.close();
        advancedMarkerElement.position = null;
    });

    // Event listener for when the map finishes moving (panning or zooming).
    map.addListener('idle', () => {
        const newCenter = map.getCenter();

        // Update the autocomplete's location bias to a 10km radius around the new map center.
        placeAutocompleteElement.locationBias = new Circle({
            center: newCenter,
            radius: 10000, // 10km in meters.
        });
    });
}

void init();

CSS

html,
body {
    height: 100%;
    margin: 0;
    padding: 0;
}

gmp-map {
    height: 100%;
}

gmp-basic-place-autocomplete {
    position: absolute;
    height: 30px;
    width: 500px;
    top: 10px;
    left: 10px;
    box-shadow: 4px 4px 5px 0px rgba(0, 0, 0, 0.2);
    color-scheme: light;
    border-radius: 10px;
}

HTML

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

        <link rel="stylesheet" type="text/css" href="./style.css" />
        <script type="module" src="./index.js"></script>
        <script>
            // prettier-ignore
            (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: "GOOGLE_MAPS_API_KEY"
            });
        </script>
    </head>
    <body>
        <gmp-map
            zoom="12"
            center="37.4220656,-122.0840897"
            map-id="DEMO_MAP_ID">
            <gmp-basic-place-autocomplete
                slot="control-inline-start-block-start"></gmp-basic-place-autocomplete>
        </gmp-map>
        <!-- Use inline styles to configure the Place Details Compact element because
     it will be placed within the info window, and info window content is inside 
     the shadow DOM when using <gmp-map> -->
        <gmp-place-details-compact
            orientation="horizontal"
            style="
                width: 400px;
                display: none;
                border: none;
                padding: 0;
                margin: 0;
                background-color: transparent;
                color-scheme: light;
            ">
            <gmp-place-details-place-request></gmp-place-details-place-request>
            <gmp-place-standard-content></gmp-place-standard-content>
        </gmp-place-details-compact>
    </body>
</html>