简体   繁体   中英

Infowindow is not looping in google maps

In my project, am taking values from php database and showing as markers in google maps. I want to show service name, in each location as infowindow (Multiple service names are available for each location). I want that service name displayed in infowindow line by line in each marker location.

But when i tried to show only first service name Following is my code, I am showing only essential codes

var markerNodes = xml.documentElement.getElementsByTagName("marker");
           var bounds = new google.maps.LatLngBounds();
           for (var i = 0; i < markerNodes.length; i++) {
             var id = markerNodes[i].getAttribute("id");
             var name = markerNodes[i].getAttribute("locationName");
            // console.log(name);
             var address = markerNodes[i].getAttribute("locationAddress1");
             var distance = parseFloat(markerNodes[i].getAttribute("distance"));
             var servicename = markerNodes[i].getAttribute("serviceName");
var latlng = new google.maps.LatLng(
                  parseFloat(markerNodes[i].getAttribute("locationLat")),
                  parseFloat(markerNodes[i].getAttribute("locationLong")));

                  //console.log (parseFloat(markerNodes[i].getAttribute("locationLong")));
             createOption(name, distance, i);
             createMarker(latlng, name, address,servicename);
             bounds.extend(latlng);

From above code, i will get everything from php databse,from this servicename ,i want to show as infowindow.

Following is the code for adding infowindow

function createMarker(latlng, name, address,servicename ) {
          var html = servicename;
          var marker = new google.maps.Marker({
            map: map,
            draggable: true,
            animation: google.maps.Animation.DROP,
            position: latlng,
            // label: "C",
            icon: {
      url: "{{ asset('img/new_map.png') }}"
    }

          });

          google.maps.event.addListener(marker, 'click', function() {
            infoWindow.setContent(html);
            infoWindow.open(map, marker);
          });
          markers.push(marker);
        }

What is wrong with this code, if i print address or name, it will works fine.

Below is the console data am getting,for reffrence Output

If you were to add a fourth named argument to the createMarker function you can then assign it as a property of the marker itself - which makes it quite simple to access when clicking the marker as you can use this

That said I do not see that you actually use the name nor the address arguments within the function itself so if again they are assigned as custom properties for the marker you can access them in the click event using this - ie: this.name etc

function createMarker( latlng, name, address, servicename ) {
    var marker = new google.maps.Marker({
        html:servicename,
        map:map,
        draggable:true,
        animation:google.maps.Animation.DROP,
        position:latlng,
        name:name,
        address:address,
        icon: {
            url:"{{ asset('img/new_map.png') }}"
        }
    });

    google.maps.event.addListener(marker, 'click', function(e) {
        infoWindow.setContent( this.html );
        infoWindow.open( map, this );
    }.bind( marker ));

    markers.push( marker );
    return marker;
}

After our brief discussion and thinking further about your requirements perhaps you might try like this. As you have ( as you stated ) already added the 4th argument we can add as a custom property to each marker. In the click handler we can iterate over the markers array and compare the current markers html attribute/property ( you originally refer to html hence continuing to do so here ) to the html property of whatever marker in the array and if they match add this to the output to be displayed in the infowindow

function createMarker( latlng, name, address, servicename ) {
    var marker = new google.maps.Marker({
        html:servicename,
        map:map,
        draggable:true,
        animation:google.maps.Animation.DROP,
        position:latlng,
        name:name,
        address:address,
        icon: {
            url:"{{ asset('img/new_map.png') }}"
        }
    });

    google.maps.event.addListener( marker, 'click', function(e) {

        let data=[];
        markers.forEach( mkr=>{
            if( mkr.html==this.html ){
                data.push( mkr.html )
            }
        });

        infoWindow.setContent( data.join( '<br />' ) );
        infoWindow.open( map, this );
    }.bind( marker ));

    markers.push( marker );
    return marker;
}

A fully working demo ( apikey redacted ) based upon the following XML file. The ajax function and it's callback are simply to emulate whatever mechanism used in your code to load markers onto the map, once loaded they do not get used again - the querying of markers is done solely based upon the markers array.

<?xml version="1.0"?>
<markers>
    <marker servicename='a' name="Kinnettles" address="B9127, Angus DD8 1, UK" lat="56.61543329027024" lng="-2.9266123065796137"/>
    <marker servicename='b' name="Nathro" address="1 Goynd Steading, Glenogil, Forfar, Angus DD8 3SW, UK" lat="56.793249595719956" lng="-2.8623101711273193"/>
    <marker servicename='a' name="ArkHill" address="3 Dryburn Cottages, Glenogilvy, Forfar, Angus DD8 1UP, UK" lat="56.57065514278748" lng="-3.0511732892761074"/>
    <marker servicename='b' name="DoddHill" address="4 Backmuir Rd, Duntrune, Tealing, Dundee, Angus DD4 0PT, UK" lat="56.54251020079966" lng="-2.9051538305053555"/>
    <marker servicename='c' name="Govals" address="B9127, Forfar, Angus DD8, UK" lat="56.582320876071854" lng="-2.9509015874633633"/>
    <marker servicename='d' name="Carsegownie" address="B9134, Forfar, Angus DD8, UK" lat="56.67951330362271" lng="-2.8062983350524746"/>
    <marker servicename='a' name="Frawney" address="Kerton Farm, Forfar, Angus DD8, UK" lat="56.56806620951482" lng="-2.9501720266113125"/>
    <marker servicename='a' name="NorthTarbrax" address="4 Nether Finlarg Farm Cottages, Forfar, Angus DD8 1XQ, UK" lat="56.57144715546598" lng="-2.92476614282225"/>
    <marker servicename='e' name="TheCarrach" address="B951, Kirriemuir, Angus DD8, UK" lat="56.6938437674986" lng="-3.131382067657455"/>
    <marker servicename='f' name="Glaxo" address="5 Meridian St, Montrose, Angus DD10 8DS, UK" lat="56.70431711148748" lng="-2.4660869436035"/>
</markers>

The html

<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset='utf-8' />
        <title>Collate attributes from multiple markers to display in single InfoWindow</title>
        <style>
            #map{width:800px;height:600px;}
        </style>
        <script>
            var map;
            var markers=[];
            var infoWindow;

            function ajax(callback){
                let xhr=new XMLHttpRequest();
                    xhr.onreadystatechange=function(){
                        if( this.status==200 && this.readyState==4 )callback(this.response)
                    }
                    xhr.open( 'GET', 'maps.xml', true );
                    xhr.send( null );
            };
            function loadmarkers(r){
                let oParser=new DOMParser();
                let oXML=oParser.parseFromString( r, 'application/xml' );
                let nodes=oXML.documentElement.getElementsByTagName('marker');
                for( let i=0; i < nodes.length; i++ ){
                    let latlng=new google.maps.LatLng( nodes[i].getAttribute('lat'),nodes[i].getAttribute('lng') );
                    let name=nodes[i].getAttribute('name');
                    let address=nodes[i].getAttribute('address');
                    let servicename=nodes[i].getAttribute('servicename');

                    createMarker(latlng,name,address,servicename)
                }
            };


            function createMarker( latlng, name, address, servicename  ) {
                var marker = new google.maps.Marker({
                    html:servicename,
                    map:map,
                    draggable:true,
                    animation:google.maps.Animation.DROP,
                    position:latlng,
                    name:name,
                    address:address
                });

                google.maps.event.addListener( marker, 'click', function(e) {
                    /* query XML to find ALL nodes that have the same location */
                    let data=[
                        this.name,
                        this.address
                    ];
                    markers.forEach( mkr=>{
                        if( mkr.html==this.html ) data.push( mkr.html );
                    });

                    infoWindow.setContent( data.join( '<br />' ) );
                    infoWindow.open( map, this );
                }.bind( marker ));

                markers.push( marker );
                return marker;
            };


            function initMap(){
                let centre=new google.maps.LatLng( 56.7, -2.8 );
                let options = {
                    zoom: 10,
                    center: centre,
                    mapTypeId: google.maps.MapTypeId.ROADMAP,
                    disableDefaultUI: true,
                    mapTypeControl: false,
                    mapTypeControlOptions: {
                        style: google.maps.MapTypeControlStyle.DROPDOWN_MENU,
                        mapTypeIds: ['roadmap', 'terrain','satellite','hybrid']
                    }
                };
                map=new google.maps.Map( document.getElementById('map'), options );
                infoWindow=new google.maps.InfoWindow();
                ajax( loadmarkers );
            }
        </script>
        <script async defer src='//maps.googleapis.com/maps/api/js?key=xxx&callback=initMap'></script>
    </head>
    <body>
        <div id='map'></div>
    </body>
</html>

结果地图

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM