عنصر البحث المتقدّم عن الأماكن

AdvancedPlaceSearchElement هو عنصر HTML يعرض نتائج البحث عن الأماكن في قائمة. هناك طريقتان لإعداد العنصر gmp-advanced-place-search:

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

طلب البحث عن مكان قريب

اختَر نوع مكان من القائمة للاطّلاع على نتائج البحث في الجوار عن نوع المكان هذا.

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

يعرض هذا المثال عنصر "البحث المتقدّم عن الأماكن" استجابةً لطلب بحث في الجوار مع نوع مكان يختاره المستخدم. ويعرض أيضًا AdvancedPlaceDetailsCompactElement للمكان المحدّد.

لإضافة عنصر "البحث المتقدّم عن الأماكن" إلى الخريطة، أضِف عنصر gmp-advanced-place-search مع عنصر gmp-place-nearby-search-request مدمج إلى صفحة HTML.

<gmp-advanced-place-search selectable>
    <!-- Nearby search requests require a location restriction to return results. Often set programmatically. -->
    <gmp-place-nearby-search-request max-result-count="5"></gmp-place-nearby-search-request>
    <template slot="details-item">
        <gmp-place-all-content></gmp-place-all-content>
    </template>
</gmp-advanced-place-search>

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

TypeScript

// Query selectors for various elements in the HTML file.
const map = document.querySelector<google.maps.MapElement>('gmp-map')!;
const placeSearch = document.querySelector<
    HTMLElement & { places?: google.maps.places.Place[] }
>('gmp-advanced-place-search')!;
const placeSearchQuery = document.querySelector<
    HTMLElement & {
        locationRestriction?: {
            center: google.maps.LatLng | google.maps.LatLngLiteral;
            radius: number;
        };
        includedTypes?: string[];
    }
>('gmp-place-nearby-search-request')!;
const placeDetails = document.querySelector<HTMLElement>(
    'gmp-advanced-place-details-compact'
)!;
const placeRequest = document.querySelector<
    HTMLElement & { place?: google.maps.places.Place }
>('gmp-place-details-place-request')!;
const typeSelect = document.querySelector<HTMLSelectElement>('.type-select')!;

// Global variables for the map, markers, and info window.
const markers = new Map<string, google.maps.marker.AdvancedMarkerElement>();
let infoWindow: google.maps.InfoWindow;

// The init function is called when the page loads.
async function init(): Promise<void> {
    // Import the necessary libraries from the Google Maps API.
    const [{ InfoWindow }] = await Promise.all([
        google.maps.importLibrary('maps'),
        google.maps.importLibrary('places'),
    ]);

    // Create a new info window and set its content to the place details element.
    placeDetails.remove(); // Hide the place details element because it is not needed until the info window opens
    infoWindow = new InfoWindow({
        content: placeDetails,
        ariaLabel: 'Place Details',
    });

    // Set the map options.
    map.innerMap.setOptions({
        clickableIcons: false,
        mapTypeControl: false,
        streetViewControl: false,
    });

    // Add event listeners to the type select and place search elements.
    typeSelect.addEventListener('change', () => {
        searchPlaces();
    });

    placeSearch.addEventListener('gmp-select', (event: Event) => {
        const place = (event as Event & { place?: google.maps.places.Place })
            .place;
        if (place?.id) {
            markers.get(place.id)?.click();
        }
    });
    placeSearch.addEventListener('gmp-load', () => {
        void addMarkers();
    });

    searchPlaces();
}
// The searchPlaces function is called when the user changes the type select or when the page loads.
function searchPlaces() {
    // Close the info window and clear the markers.
    infoWindow.close();
    for (const marker of markers.values()) {
        marker.remove();
    }
    markers.clear();

    // Set the place search query and add an event listener to the place search element.
    if (typeSelect.value) {
        const center = map.center!;
        placeSearchQuery.locationRestriction = {
            center,
            radius: 50000, // 50km radius
        };
        placeSearchQuery.includedTypes = [typeSelect.value];
    }
}

// The addMarkers function is called when the place search element loads.
async function addMarkers() {
    // Import the necessary libraries from the Google Maps API.
    const [{ AdvancedMarkerElement }, { LatLngBounds }] = await Promise.all([
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('core'),
    ]);
    const bounds = new LatLngBounds();

    if (!placeSearch.places || placeSearch.places.length === 0) {
        return;
    }

    for (const place of placeSearch.places) {
        if (!place.location) continue;
        const marker = new AdvancedMarkerElement({
            map: map.innerMap,
            position: place.location,
            collisionBehavior: 'REQUIRED_AND_HIDES_OPTIONAL',
            gmpClickable: true,
        });

        markers.set(place.id, marker);
        bounds.extend(place.location);

        marker.addEventListener('gmp-click', () => {
            placeRequest.place = place;
            infoWindow.open(map.innerMap, marker);
        });
    }

    map.innerMap.fitBounds(bounds);
}

void init();

JavaScript

// Query selectors for various elements in the HTML file.
const map = document.querySelector('gmp-map');
const placeSearch = document.querySelector('gmp-advanced-place-search');
const placeSearchQuery = document.querySelector(
    'gmp-place-nearby-search-request'
);
const placeDetails = document.querySelector(
    'gmp-advanced-place-details-compact'
);
const placeRequest = document.querySelector('gmp-place-details-place-request');
const typeSelect = document.querySelector('.type-select');

// Global variables for the map, markers, and info window.
const markers = new Map();
let infoWindow;

// The init function is called when the page loads.
async function init() {
    // Import the necessary libraries from the Google Maps API.
    const [{ InfoWindow }] = await Promise.all([
        google.maps.importLibrary('maps'),
        google.maps.importLibrary('places'),
    ]);

    // Create a new info window and set its content to the place details element.
    placeDetails.remove(); // Hide the place details element because it is not needed until the info window opens
    infoWindow = new InfoWindow({
        content: placeDetails,
        ariaLabel: 'Place Details',
    });

    // Set the map options.
    map.innerMap.setOptions({
        clickableIcons: false,
        mapTypeControl: false,
        streetViewControl: false,
    });

    // Add event listeners to the type select and place search elements.
    typeSelect.addEventListener('change', () => {
        searchPlaces();
    });

    placeSearch.addEventListener('gmp-select', (event) => {
        const place = event.place;
        if (place?.id) {
            markers.get(place.id)?.click();
        }
    });
    placeSearch.addEventListener('gmp-load', () => {
        void addMarkers();
    });

    searchPlaces();
}
// The searchPlaces function is called when the user changes the type select or when the page loads.
function searchPlaces() {
    // Close the info window and clear the markers.
    infoWindow.close();
    for (const marker of markers.values()) {
        marker.remove();
    }
    markers.clear();

    // Set the place search query and add an event listener to the place search element.
    if (typeSelect.value) {
        const center = map.center;
        placeSearchQuery.locationRestriction = {
            center,
            radius: 50000, // 50km radius
        };
        placeSearchQuery.includedTypes = [typeSelect.value];
    }
}

// The addMarkers function is called when the place search element loads.
async function addMarkers() {
    // Import the necessary libraries from the Google Maps API.
    const [{ AdvancedMarkerElement }, { LatLngBounds }] = await Promise.all([
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('core'),
    ]);
    const bounds = new LatLngBounds();

    if (!placeSearch.places || placeSearch.places.length === 0) {
        return;
    }

    for (const place of placeSearch.places) {
        if (!place.location) continue;
        const marker = new AdvancedMarkerElement({
            map: map.innerMap,
            position: place.location,
            collisionBehavior: 'REQUIRED_AND_HIDES_OPTIONAL',
            gmpClickable: true,
        });

        markers.set(place.id, marker);
        bounds.extend(place.location);

        marker.addEventListener('gmp-click', () => {
            placeRequest.place = place;
            infoWindow.open(map.innerMap, marker);
        });
    }

    map.innerMap.fitBounds(bounds);
}

void init();

CSS

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

body {
    display: flex;
    flex-direction: column;
    font-family: Arial, Helvetica, sans-serif;
}

.container {
    display: flex;
    height: 100vh;
    width: 100%;
}

gmp-map {
    flex-grow: 1;
}

.ui-panel {
    width: 400px;
    margin-left: 20px;
    margin-top: 10px;
    overflow-y: auto;
    font-family: Arial, Helvetica, sans-serif;
}

.list-container {
    display: flex;
    flex-direction: column;
}

gmp-place-search {
    width: 100%;
    margin: 0;
    border: none;
    color-scheme: light;
}

HTML

<!doctype html>
<html>
    <head>
        <title>Place Search Nearby with Google Maps</title>
        <meta charset="utf-8" />
        <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",
                v: "beta"
            });
        </script>
    </head>
    <body>

        <div class="container">
            <!-- map-id is required to use advanced markers. See https://developers.google.com/maps/documentation/javascript/map-ids/mapid-over. -->
            <gmp-map center="-37.813,144.963" zoom="16" map-id="DEMO_MAP_ID">
            </gmp-map>
            <div class="ui-panel">
                <div class="controls">
                    <label for="type-select">
                        Select a place type:
                        <select id="type-select" class="type-select">
                            <option value="restaurant">Restaurant</option>
                            <option value="cafe" selected>Cafe</option>
                            <option value="electric_vehicle_charging_station">
                                EV charging station
                            </option>
                        </select>
                    </label>
                </div>
                <div class="list-container">
                    <gmp-advanced-place-search selectable>
                        <gmp-place-all-content></gmp-place-all-content>
                        <gmp-place-nearby-search-request
                            max-result-count="5"></gmp-place-nearby-search-request>
                    </gmp-advanced-place-search>
                </div>
            </div>
        </div>

        <!--
        The gmp-advanced-place-details-compact element is styled inline because it is
        conditionally rendered and moved into the info window, which is
        part of the map's shadow DOM.
    -->
        <gmp-advanced-place-details-compact
            orientation="horizontal"
            truncation-preferred
            style="
                width: 400px;
                padding: 0;
                margin: 0;
                border: none;
                background-color: transparent;
                color-scheme: light;
            ">
            <gmp-place-details-place-request></gmp-place-details-place-request>

            <gmp-place-media></gmp-place-media>
            <gmp-place-rating></gmp-place-rating>
            <gmp-place-price></gmp-place-price>
            <gmp-place-accessible-entrance-icon></gmp-place-accessible-entrance-icon>
            <gmp-place-open-now-status></gmp-place-open-now-status>
            <gmp-place-attribution
                light-scheme-color="gray"
                dark-scheme-color="white"></gmp-place-attribution>
        </gmp-advanced-place-details-compact>

    </body>
</html>

يتيح عنصر select للمستخدم اختيار نوع مكان من القائمة. لتبسيط الأمر، تم إدراج ثلاثة أنواع فقط من الأماكن: مطعم ومقهى ومحطة شحن للمركبات الكهربائية.

<div class="controls">
    <label for="type-select">
        Select a place type:
        <select id="type-select" class="type-select">
            <option value="restaurant">Restaurant</option>
            <option value="cafe" selected>Cafe</option>
            <option value="electric_vehicle_charging_station">
                EV charging station
            </option>
        </select>
    </label>
</div>

عندما يختار المستخدم نوع مكان من القائمة، يتم تعديل عنصر gmp-place-nearby-search-request، ويعرض عنصر "البحث المتقدّم عن الأماكن" النتائج.

طلب البحث حسب النص

أدخِل عبارة بحث في حقل الإدخال وانقر على الزر بحث للحصول على قائمة بالأماكن التي تتطابق مع العبارة.

يتم ضبط ميزة &quot;البحث النصي&quot; بشكل أساسي للبحث باستخدام طلب بحث نصي وموقع جغرافي، ويمكن تحسين النتائج حسب مستوى السعر والتقييم وما إذا كانت الأماكن مفتوحة حاليًا. يمكن أيضًا ترتيب النتائج حسب المسافة أو مدى الرواج باستخدام السمة rankPreference. لمزيد من التفاصيل، يمكنك الاطّلاع على المستندات المرجعية لفئة PlaceTextSearchRequestElement.

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

لإضافة عنصر "البحث المتقدّم عن الأماكن" إلى الخريطة، أضِف عنصر gmp-advanced-place-search مع عنصر gmp-place-text-search-request مدمج إلى صفحة HTML.

<gmp-advanced-place-search selectable>
    <gmp-place-text-search-request max-result-count="5"></gmp-place-text-search-request>
    <template slot="details-item">
        <gmp-place-all-content></gmp-place-all-content>
    </template>
</gmp-advanced-place-search>

يتيح عنصر input للمستخدم إدخال نص البحث.

<div class="controls">
    <input
        type="text"
        id="query-input"
        class="query-input"
        placeholder="Search for a place"
        value="cafe" />
    <button id="search-button" class="search-button">
        Search
    </button>
</div>

عندما ينقر المستخدم على الزر بحث، يتم تشغيل دالة البحث، ويتم تعديل العنصر gmp-place-text-search-request، ويعرض عنصر "البحث المتقدّم عن الأماكن" النتائج.

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

TypeScript

// Query selectors for various elements in the HTML file.
const map = document.querySelector<google.maps.MapElement>('gmp-map')!;
const placeSearch = document.querySelector<
    HTMLElement & { places?: google.maps.places.Place[] }
>('gmp-advanced-place-search')!;
const placeSearchQuery = document.querySelector<
    HTMLElement & {
        textQuery?: string;
        locationBias?: google.maps.LatLng | google.maps.LatLngLiteral;
    }
>('gmp-place-text-search-request')!;
const placeDetails = document.querySelector<HTMLElement>(
    'gmp-advanced-place-details-compact'
)!;
const placeRequest = document.querySelector<
    HTMLElement & { place?: google.maps.places.Place }
>('gmp-place-details-place-request')!;
const queryInput = document.querySelector<HTMLInputElement>('.query-input')!;
const searchButton = document.querySelector<HTMLElement>('.search-button')!;

// Global variables for the map, markers, and info window.
const markers = new Map<string, google.maps.marker.AdvancedMarkerElement>();
let infoWindow: google.maps.InfoWindow;

// The init function is called when the page loads.
async function init(): Promise<void> {
    // Import the necessary libraries from the Google Maps API.
    const [{ InfoWindow }] = await Promise.all([
        google.maps.importLibrary('maps'),
        google.maps.importLibrary('places'),
    ]);

    // Create a new info window and set its content to the place details element.
    placeDetails.remove(); // Hide the place details element because it is not needed until the info window opens
    infoWindow = new InfoWindow({
        content: placeDetails,
        ariaLabel: 'Place Details',
    });

    // Set the map options.
    map.innerMap.setOptions({
        clickableIcons: false,
        mapTypeControl: false,
        streetViewControl: false,
    });

    // Add event listeners to the query input and place search elements.
    searchButton.addEventListener('click', () => {
        searchPlaces();
    });
    queryInput.addEventListener('keydown', (event: KeyboardEvent) => {
        if (event.key === 'Enter') {
            searchPlaces();
        }
    });

    placeSearch.addEventListener('gmp-select', (event: Event) => {
        const place = (event as Event & { place?: google.maps.places.Place })
            .place;
        if (place?.id) {
            markers.get(place.id)?.click();
        }
    });
    placeSearch.addEventListener('gmp-load', () => {
        void addMarkers();
    });

    searchPlaces();
}
// The searchPlaces function is called when the user changes the query input or when the page loads.
function searchPlaces() {
    // Close the info window and clear the markers.
    infoWindow.close();
    for (const marker of markers.values()) {
        marker.remove();
    }
    markers.clear();

    // Set the place search query and add an event listener to the place search element.
    if (queryInput.value) {
        const center = map.center;
        if (center) {
            placeSearchQuery.locationBias = center;
        }
        // The textQuery property is required for the search element to load.
        // Any other configured properties will be ignored if textQuery is not set.
        placeSearchQuery.textQuery = queryInput.value;
    }
}

// The addMarkers function is called when the place search element loads.
async function addMarkers() {
    // Import the necessary libraries from the Google Maps API.
    const [{ AdvancedMarkerElement }, { LatLngBounds }] = await Promise.all([
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('core'),
    ]);
    const bounds = new LatLngBounds();

    if (!placeSearch.places || placeSearch.places.length === 0) {
        return;
    }

    for (const place of placeSearch.places) {
        if (!place.location) {
            continue;
        }

        const marker = new AdvancedMarkerElement({
            map: map.innerMap,
            position: place.location,
            collisionBehavior: 'REQUIRED_AND_HIDES_OPTIONAL',
            gmpClickable: true,
        });

        markers.set(place.id, marker);
        bounds.extend(place.location);

        marker.addEventListener('gmp-click', () => {
            placeRequest.place = place;
            infoWindow.open(map.innerMap, marker);
        });
    }

    map.innerMap.fitBounds(bounds);
}

void init();

JavaScript

// Query selectors for various elements in the HTML file.
const map = document.querySelector('gmp-map');
const placeSearch = document.querySelector('gmp-advanced-place-search');
const placeSearchQuery = document.querySelector(
    'gmp-place-text-search-request'
);
const placeDetails = document.querySelector(
    'gmp-advanced-place-details-compact'
);
const placeRequest = document.querySelector('gmp-place-details-place-request');
const queryInput = document.querySelector('.query-input');
const searchButton = document.querySelector('.search-button');

// Global variables for the map, markers, and info window.
const markers = new Map();
let infoWindow;

// The init function is called when the page loads.
async function init() {
    // Import the necessary libraries from the Google Maps API.
    const [{ InfoWindow }] = await Promise.all([
        google.maps.importLibrary('maps'),
        google.maps.importLibrary('places'),
    ]);

    // Create a new info window and set its content to the place details element.
    placeDetails.remove(); // Hide the place details element because it is not needed until the info window opens
    infoWindow = new InfoWindow({
        content: placeDetails,
        ariaLabel: 'Place Details',
    });

    // Set the map options.
    map.innerMap.setOptions({
        clickableIcons: false,
        mapTypeControl: false,
        streetViewControl: false,
    });

    // Add event listeners to the query input and place search elements.
    searchButton.addEventListener('click', () => {
        searchPlaces();
    });
    queryInput.addEventListener('keydown', (event) => {
        if (event.key === 'Enter') {
            searchPlaces();
        }
    });

    placeSearch.addEventListener('gmp-select', (event) => {
        const place = event.place;
        if (place?.id) {
            markers.get(place.id)?.click();
        }
    });
    placeSearch.addEventListener('gmp-load', () => {
        void addMarkers();
    });

    searchPlaces();
}
// The searchPlaces function is called when the user changes the query input or when the page loads.
function searchPlaces() {
    // Close the info window and clear the markers.
    infoWindow.close();
    for (const marker of markers.values()) {
        marker.remove();
    }
    markers.clear();

    // Set the place search query and add an event listener to the place search element.
    if (queryInput.value) {
        const center = map.center;
        if (center) {
            placeSearchQuery.locationBias = center;
        }
        // The textQuery property is required for the search element to load.
        // Any other configured properties will be ignored if textQuery is not set.
        placeSearchQuery.textQuery = queryInput.value;
    }
}

// The addMarkers function is called when the place search element loads.
async function addMarkers() {
    // Import the necessary libraries from the Google Maps API.
    const [{ AdvancedMarkerElement }, { LatLngBounds }] = await Promise.all([
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('core'),
    ]);
    const bounds = new LatLngBounds();

    if (!placeSearch.places || placeSearch.places.length === 0) {
        return;
    }

    for (const place of placeSearch.places) {
        if (!place.location) {
            continue;
        }

        const marker = new AdvancedMarkerElement({
            map: map.innerMap,
            position: place.location,
            collisionBehavior: 'REQUIRED_AND_HIDES_OPTIONAL',
            gmpClickable: true,
        });

        markers.set(place.id, marker);
        bounds.extend(place.location);

        marker.addEventListener('gmp-click', () => {
            placeRequest.place = place;
            infoWindow.open(map.innerMap, marker);
        });
    }

    map.innerMap.fitBounds(bounds);
}

void init();

CSS

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

body {
    display: flex;
    flex-direction: column;
    font-family: Arial, Helvetica, sans-serif;
}

.container {
    display: flex;
    height: 100vh;
    width: 100%;
}

gmp-map {
    flex-grow: 1;
}

.ui-panel {
    width: 400px;
    margin-left: 20px;
    margin-right: 20px;
    margin-top: 10px;
    overflow-y: auto;
    font-family: Arial, Helvetica, sans-serif;
}

.list-container {
    display: flex;
    flex-direction: column;
}

gmp-place-search {
    width: 100%;
    margin: 0;
    border: none;
    color-scheme: light;
}

.query-input {
    width: 100%;
    padding: 8px;
    margin-bottom: 10px;
    box-sizing: border-box;
}

.search-button {
    width: 100%;
    padding: 8px;
    margin-bottom: 10px;
    box-sizing: border-box;
    background-color: #1a73e8;
    color: white;
    border: none;
    cursor: pointer;
}

.search-button:hover,
.search-button:focus-visible {
    background-color: #1765cc;
}

HTML

<!doctype html>
<html>
    <head>
        <title>Place Text Search with Google Maps</title>
        <meta charset="utf-8" />
        <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",
                v: "beta"
            });
        </script>
    </head>
    <body>

        <div class="container">
            <div class="ui-panel">
                <div class="controls">
                    <input
                        type="text"
                        id="query-input"
                        class="query-input"
                        placeholder="Search for a place"
                        value="cafe" />
                    <button class="search-button">Search</button>
                </div>
                <div class="list-container">
                    <gmp-advanced-place-search selectable>
                        <gmp-place-all-content></gmp-place-all-content>
                        <gmp-place-text-search-request
                            max-result-count="5"></gmp-place-text-search-request>
                    </gmp-advanced-place-search>
                </div>
            </div>
            <!-- map-id is required to use advanced markers. See https://developers.google.com/maps/documentation/javascript/map-ids/mapid-over. -->
            <gmp-map center="-37.813,144.963" zoom="16" map-id="DEMO_MAP_ID">
            </gmp-map>
        </div>

        <!--
        The gmp-advanced-place-details-compact element is styled inline because it is
        conditionally rendered and moved into the info window, which is
        part of the map's shadow DOM.
        -->
        <gmp-advanced-place-details-compact
            orientation="horizontal"
            truncation-preferred
            style="
                width: 400px;
                padding: 0;
                margin: 0;
                border: none;
                background-color: transparent;
                color-scheme: light;
            ">
            <gmp-place-details-place-request></gmp-place-details-place-request>

            <gmp-place-name></gmp-place-name>
            <gmp-place-media></gmp-place-media>
            <gmp-place-rating></gmp-place-rating>
            <gmp-place-price></gmp-place-price>
            <gmp-place-accessible-entrance-icon></gmp-place-accessible-entrance-icon>
            <gmp-place-open-now-status></gmp-place-open-now-status>
            <gmp-place-attribution
                light-scheme-color="gray"
                dark-scheme-color="white"></gmp-place-attribution>
        </gmp-advanced-place-details-compact>

    </body>
</html>

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

تخصيص أزرار الإجراءات

أضِف أزرار الإجراءات كعناصر فرعية داخل العنصر <template slot="details-item"> في مكوّن "البحث المتقدّم عن الأماكن". استخدِم <gmp-place-link> للاتصالات التنقّلية العادية، وحدِّد السمة action بشكل صريح. يمكنك تحديد السمة slot اختياريًا. الإجراءات المحدّدة مسبقًا الصالحة هي open-website وopen-directions وopen-map وcall. في حال حذف السمة slot، يتم ضبطها تلقائيًا على action-main.

<gmp-advanced-place-search selectable>
  <gmp-place-text-search-request text-query="pizza" max-result-count="5"></gmp-place-text-search-request>
  <template slot="details-item">
    <gmp-place-name></gmp-place-name>
    <gmp-place-link action="open-website" target="_blank"></gmp-place-link>
    <gmp-place-link action="open-directions" slot="action-corner"></gmp-place-link>
  </template>
</gmp-advanced-place-search>

فلترة المراجعات والوسائط

تعرض عيّنة التعليمات البرمجية هذه الوسائط والمراجعات التي تتضمّن كلمة "قهوة" فقط.

<gmp-advanced-place-search selectable>
  <gmp-place-text-search-request text-query="pizza" max-result-count="5"></gmp-place-text-search-request>
  <template slot="details-item">
    <gmp-place-name></gmp-place-name>
    <gmp-place-media query="coffee"></gmp-place-media>
    <gmp-place-reviews query="coffee" rank-preference="newest"></gmp-place-reviews>
  </template>
</gmp-advanced-place-search>

ضبط إعدادات تحديد مصدر المكان

لضبط الإحالة المرئية، أضِف عنصر <gmp-place-attribution> لعرض إعدادات إحالة بيانات Maps API الشاملة، مثل مصدر صورة أو مراجعة. ويجب إضافته كعنصر شقيق مباشر لـ <template>. سيتم تجاهل معلومات تحديد المصدر الموضوعة داخل العنصر <template>.

<gmp-advanced-place-search selectable>
  <gmp-place-text-search-request text-query="pizza" max-result-count="5"></gmp-place-text-search-request>
  <template slot="details-item">
    <gmp-place-name></gmp-place-name>
  </template>
  <gmp-place-attribution light-scheme-color="black" dark-scheme-color="gray"></gmp-place-attribution>
</gmp-advanced-place-search>

التعامل مع اختيار الأماكن والأخطاء

عند توفّر السمة selectable، يمكنك الاستماع إلى الحدث gmp-select لاسترداد المكان الذي اختاره المستخدم. يمكنك أيضًا الاستماع إلى الحدث gmp-error للتعامل بسلاسة مع السيناريوهات التي يتعذّر فيها جلب بيانات المكان.

const searchElement = document.querySelector('gmp-advanced-place-search');

searchElement.addEventListener('gmp-select', (e) => {
  console.log('User selected place: ', e.place);
});

searchElement.addEventListener('gmp-error', (e) => {
  // e.detail contains the structured error payload
  console.error('Failed to load places: ', e.detail.error);
});