none
Setting all of pushpin icon to be clickable Bing Map v8 RRS feed

  • Question

  • Hey,

    In an attempt to use Bing Map v8 and I'm running into the issue of only half of the custom icon being used for the pushpin being clickable. In addition to only having the lower half of the icon being clickable, there is a large area that is not apart of the pushpin icon that is clickable making it near impossible to cluster groups of pushpin together since, there's no way to click on the exact pushpin.

    pushpin icon:  stephen.mycovalent01.com/map-marker.png

    The clickable area is the area below the light blue section, so if a visitor clicks on the much more attractive light blue area nothing happens. To get an image of what's clickable, there is a circular clickable area and the tip of the icon is at the center of that clickable circular area.

    My question is, how do I change from a circular clickable area to having only the icon be clickable?

    <script type='text/javascript' src='http://www.bing.com/api/maps/mapcontrol'></script>
    <script type="text/javascript">
            function loadMap() {
                    var locations = [data here];
                    var navigationBarMode = Microsoft.Maps.NavigationBarMode;
                    var map = new Microsoft.Maps.Map(document.getElementById('hotelmap'), {
                            credentials: 'Bing Maps Key',
                            showMapTypeSelector: false,
                            zoom: 3,
        		        navigationBarMode: navigationBarMode.compact
                    });
                    Microsoft.Maps.Events.addHandler(map, 'mousewheel', function(e) {
                            map.setOptions({disableZooming: true})
                    });
                    
                    // array is the cfm property results returned from the property manager in json format
                    locations["properties"].forEach(function(property){ 
    			var photoHtml = "";
    			if (property.photo != "") photoHtml = '<img src="/' + property.photo + '" width="100" />';
                        
    			var html = "<div>" + property.propertyName + "<br>" + photoHtml + "<br>" + property.address + "<br>" + property.country + "<br>" + property.phone + "<br>" + property.fax + "</div>";	
    					
                            var center = new Microsoft.Maps.Location(property.latitude, property.longitude);
                            var pushpin = new Microsoft.Maps.Pushpin(center, { icon: 'http://hww.hemc.aromaticlogic.com/images/film/map-marker.png', width: 50, height: 50, anchor: new Microsoft.Maps.Point(25, 50)}, null);
                            //var infobox = new Microsoft.Maps.Infobox(center, { title: property.propertyName, description: property.address + "\n" + property.country + "\n" + property.phone});
    			var infobox = new Microsoft.Maps.Infobox(center, {htmlContent: html});
    					
                            Microsoft.Maps.Events.addHandler(pushpin, 'click', function () {
                                    infobox.setMap(map);
                            })
                            map.entities.push(pushpin);
                    })
                }
    </script>
    <div id='hotelmap' style="width:100%; height: 750px;">
    <script>
    	$(window).load(function($){
    		(jQuery)("#hotelmap").ready(function(){
    			loadMap();
    		});
    	});
    </script>



    • Edited by Ricky_Brundritt Wednesday, May 4, 2016 5:38 PM removed Bing Maps Key
    Wednesday, May 4, 2016 5:09 PM

Answers

  • Another way to hide/show the infobox is to add and remove it to the map using setMap. Note that infoboxes in V8 are added to the map using setMap and rather than using map.entities. To get this to work in your app, remove the visible property from your infobox. Don't add the infobox to the map right after it s created. In the displayInfobox function, remove the current infobox logic and add infobox.setMap(map);

    Here is a modified version of your code:

    <script type="text/javascript">
    	var locations = [data];
    	var map = null;
    	var infobox = null;
    	var InfoBoxEntity = null;        
    	var PushPinsEntity = null;
    	var info = [];
            function loadMap() {
                    var navigationBarMode = Microsoft.Maps.NavigationBarMode;
                    map = new Microsoft.Maps.Map(document.getElementById('hotelmap'), {
                        credentials: 'Map Key',
                        showMapTypeSelector: false,
                        zoom: 3,
    		    minZoom: 3,
    		    maxZoom: 11,
        		    navigationBarMode: navigationBarMode.compact
                    });
                    Microsoft.Maps.Events.addHandler(map, 'mousewheel', function(e) {
                        map.setOptions({disableZooming: true})
                    });
    				
    		PushPinsEntity = new Microsoft.Maps.EntityCollection();
    		InfoBoxEntity = new Microsoft.Maps.EntityCollection();
    				
    		infobox = new Microsoft.Maps.Infobox(new Microsoft.Maps.Location(0, 0), { title: "test", description: "super test" });
    				
    		AddData();
    		map.entities.push(PushPinsEntity);
    		map.entities.push(InfoBoxEntity);
    		//Microsoft.Maps.Events.addHandler(map, 'viewchange', function(e) {
    		//	this.setOptions({ visible: false });
    		//}.bind(infobox));
    
                }
    			
    	function AddData() {
    		var properties = locations.properties;
    		for(var i = 0; i < properties.length; i++){ 
    			var center = new Microsoft.Maps.Location(properties[i].latitude, properties[i].longitude);
                            var pushpin = new Microsoft.Maps.Pushpin(center, { icon: 'stephen.mycovalent01.com/map-marker.png', title: properties[i].propertyName, width: 50, height: 50, anchor: new Microsoft.Maps.Point(25, 50)}, null);
                        
    			var photoHtml = "";
    			if (properties[i].photo != "") photoHtml = '<img src="/' + properties[i].photo + '" width="100" />';                  
    			var html = "<div class=\"bingMapInfoBox\">" + properties[i].propertyName + " <a class=\"infobox-close\" style=\"float: left; color: ##fff;\" href=\"javascript:closeInfobox()\">[x]</a>" + "<br>" + photoHtml + "<br>" + properties[i].address + "<br>" + properties[i].country + "<br>" + properties[i].phone + "<br>" + properties[i].fax + "</div>";			
    			info[center] = html;
    											
    			Microsoft.Maps.Events.addHandler(pushpin, 'click', displayInfobox);					
                            PushPinsEntity.push(pushpin);
                    }
    	}
    			
    	function displayInfobox(e){
    		if (e.targetType == 'pushpin') {
                    infobox.setLocation(e.target.getLocation());
    		//infobox.setHtmlContent(info[e.target.getLocation()]);
    		
                    infobox.setMap(map);
    				
    		console.log(infobox);
                  }
    	}


    [Blog] [twitter] [LinkedIn]

    Friday, May 6, 2016 4:36 PM
  • My developers looked into this and it looks like they already had a fix for this and it was pushed out to the release branch this morning. I tried to reproduce the issue and no longer see it. Can you verify on your side that you aren't seeing this issue anymore.

    Also, a tip, it looks like you are trying to disable the maps zooming via the mouse wheel. The code you have added will disable all zooming of the map. We will be exposing a map option that will make it easy to disable the map zooming function when the mouse wheel is used over top the map, and the page will scroll as it usually does. This should be available in the next month or so. Note that I have seen some other sites disable this function in the past and to be honest, the general feedback from users is that it creates a broken experience as many are used to using their mousse wheel with the map on other sites.


    [Blog] [twitter] [LinkedIn]

    Thursday, May 5, 2016 7:24 PM
  • Instead of using visible, do infobox.setMap(null); to hide it.

    [Blog] [twitter] [LinkedIn]

    Monday, May 9, 2016 4:34 PM
  • When reopening it you would use infobox.setMap(map); and shouldn't see any errors.

    That said, the original issue with infobox visible option has been corrected and is available in the experimental branch. You can test this by adding "&branch=experimental" to the map script URL. You can then use infobox.setOptions({visible: [true/false]}); to hide/show it. This fix will be merged into the release branch in the next couple of weeks. Be sure to remove the experimental branch URL parameter from your app before going into production.


    [Blog] [twitter] [LinkedIn]

    Tuesday, May 10, 2016 1:25 AM

All replies

  • This is a very odd issue. Just tried loading a single pushpin using the settings you provided and all the mouse events in the interactive SDK using the JavaScript panel and worked on it perfectly. However, when I ran the exact same code in an HTML page I was able to reproduce your issue. I'll have the dev team look into this.


    [Blog] [twitter] [LinkedIn]

    Wednesday, May 4, 2016 5:54 PM
  • My developers looked into this and it looks like they already had a fix for this and it was pushed out to the release branch this morning. I tried to reproduce the issue and no longer see it. Can you verify on your side that you aren't seeing this issue anymore.

    Also, a tip, it looks like you are trying to disable the maps zooming via the mouse wheel. The code you have added will disable all zooming of the map. We will be exposing a map option that will make it easy to disable the map zooming function when the mouse wheel is used over top the map, and the page will scroll as it usually does. This should be available in the next month or so. Note that I have seen some other sites disable this function in the past and to be honest, the general feedback from users is that it creates a broken experience as many are used to using their mousse wheel with the map on other sites.


    [Blog] [twitter] [LinkedIn]

    Thursday, May 5, 2016 7:24 PM
  • It appears to be resolved, thanks for that. The zoom range does work and the zooming via mouse wheel is working as intended. If changes are needed I will look at what you have mention for the future. I have a follow up question, but it's regarding the infobox.

    As far as I know, there should only be one instance of the infobox per map and that instance should just have it's content updated. I've changed the code listed above to what I believe is the more correct way to implement that. However, the info box is no long showing up at all. I'll looked to the developer tools in the browser and the infobox has the properties visible: true, zIndex: 10, title: some text, description: some text. I've binded the click event on the pushpin to toggle the visible from property from false to true, and that seems to be working. Could you tell me where I'm missing up?

    <script type="text/javascript">
    	var locations = [data];
    	var map = null;
    	var infobox = null;
    	var InfoBoxEntity = null;        
    	var PushPinsEntity = null;
    	var info = [];
            function loadMap() {
                    var navigationBarMode = Microsoft.Maps.NavigationBarMode;
                    map = new Microsoft.Maps.Map(document.getElementById('hotelmap'), {
                        credentials: 'Map Key',
                        showMapTypeSelector: false,
                        zoom: 3,
    		    minZoom: 3,
    		    maxZoom: 11,
        		    navigationBarMode: navigationBarMode.compact
                    });
                    Microsoft.Maps.Events.addHandler(map, 'mousewheel', function(e) {
                        map.setOptions({disableZooming: true})
                    });
    				
    		PushPinsEntity = new Microsoft.Maps.EntityCollection();
    		InfoBoxEntity = new Microsoft.Maps.EntityCollection();
    				
    		infobox = new Microsoft.Maps.Infobox(new Microsoft.Maps.Location(0, 0), { visible:false, title: "test", description: "super test" });
    				InfoBoxEntity.push(infobox);
    		AddData();
    		map.entities.push(PushPinsEntity);
    		map.entities.push(InfoBoxEntity);
    		//Microsoft.Maps.Events.addHandler(map, 'viewchange', function(e) {
    		//	this.setOptions({ visible: false });
    		//}.bind(infobox));
    
                }
    			
    	function AddData() {
    		var properties = locations.properties;
    		for(var i = 0; i < properties.length; i++){ 
    			var center = new Microsoft.Maps.Location(properties[i].latitude, properties[i].longitude);
                            var pushpin = new Microsoft.Maps.Pushpin(center, { icon: 'stephen.mycovalent01.com/map-marker.png', title: properties[i].propertyName, width: 50, height: 50, anchor: new Microsoft.Maps.Point(25, 50)}, null);
                        
    			var photoHtml = "";
    			if (properties[i].photo != "") photoHtml = '<img src="/' + properties[i].photo + '" width="100" />';                  
    			var html = "<div class=\"bingMapInfoBox\">" + properties[i].propertyName + " <a class=\"infobox-close\" style=\"float: left; color: ##fff;\" href=\"javascript:closeInfobox()\">[x]</a>" + "<br>" + photoHtml + "<br>" + properties[i].address + "<br>" + properties[i].country + "<br>" + properties[i].phone + "<br>" + properties[i].fax + "</div>";			
    			info[center] = html;
    											
    			Microsoft.Maps.Events.addHandler(pushpin, 'click', displayInfobox);
    					
                            PushPinsEntity.push(pushpin);
                    }
    	}
    			
    	function displayInfobox(e){
    		if (e.targetType == 'pushpin') {
                    infobox.setLocation(e.target.getLocation());
    		//infobox.setHtmlContent(info[e.target.getLocation()]);
                    infobox.setOptions({ visible: true, zIndex: 10 });
    		console.log(infobox);
                  }
    	}
    I did also try starting off with the infobox visible option as true, and it was still not visible.


    Thursday, May 5, 2016 8:16 PM
  • There is a know bug with the infobox at the moment where the visible property has no effect after closing the infobox using the x-button. We just noticed this yesterday. A dev will look at it shortly.

    [Blog] [twitter] [LinkedIn]

    Thursday, May 5, 2016 9:27 PM
  • That's good to know, but I can't get it to show initially either. The these problems related, and does the code I posted look correct?
    Thursday, May 5, 2016 11:25 PM
  • Another way to hide/show the infobox is to add and remove it to the map using setMap. Note that infoboxes in V8 are added to the map using setMap and rather than using map.entities. To get this to work in your app, remove the visible property from your infobox. Don't add the infobox to the map right after it s created. In the displayInfobox function, remove the current infobox logic and add infobox.setMap(map);

    Here is a modified version of your code:

    <script type="text/javascript">
    	var locations = [data];
    	var map = null;
    	var infobox = null;
    	var InfoBoxEntity = null;        
    	var PushPinsEntity = null;
    	var info = [];
            function loadMap() {
                    var navigationBarMode = Microsoft.Maps.NavigationBarMode;
                    map = new Microsoft.Maps.Map(document.getElementById('hotelmap'), {
                        credentials: 'Map Key',
                        showMapTypeSelector: false,
                        zoom: 3,
    		    minZoom: 3,
    		    maxZoom: 11,
        		    navigationBarMode: navigationBarMode.compact
                    });
                    Microsoft.Maps.Events.addHandler(map, 'mousewheel', function(e) {
                        map.setOptions({disableZooming: true})
                    });
    				
    		PushPinsEntity = new Microsoft.Maps.EntityCollection();
    		InfoBoxEntity = new Microsoft.Maps.EntityCollection();
    				
    		infobox = new Microsoft.Maps.Infobox(new Microsoft.Maps.Location(0, 0), { title: "test", description: "super test" });
    				
    		AddData();
    		map.entities.push(PushPinsEntity);
    		map.entities.push(InfoBoxEntity);
    		//Microsoft.Maps.Events.addHandler(map, 'viewchange', function(e) {
    		//	this.setOptions({ visible: false });
    		//}.bind(infobox));
    
                }
    			
    	function AddData() {
    		var properties = locations.properties;
    		for(var i = 0; i < properties.length; i++){ 
    			var center = new Microsoft.Maps.Location(properties[i].latitude, properties[i].longitude);
                            var pushpin = new Microsoft.Maps.Pushpin(center, { icon: 'stephen.mycovalent01.com/map-marker.png', title: properties[i].propertyName, width: 50, height: 50, anchor: new Microsoft.Maps.Point(25, 50)}, null);
                        
    			var photoHtml = "";
    			if (properties[i].photo != "") photoHtml = '<img src="/' + properties[i].photo + '" width="100" />';                  
    			var html = "<div class=\"bingMapInfoBox\">" + properties[i].propertyName + " <a class=\"infobox-close\" style=\"float: left; color: ##fff;\" href=\"javascript:closeInfobox()\">[x]</a>" + "<br>" + photoHtml + "<br>" + properties[i].address + "<br>" + properties[i].country + "<br>" + properties[i].phone + "<br>" + properties[i].fax + "</div>";			
    			info[center] = html;
    											
    			Microsoft.Maps.Events.addHandler(pushpin, 'click', displayInfobox);					
                            PushPinsEntity.push(pushpin);
                    }
    	}
    			
    	function displayInfobox(e){
    		if (e.targetType == 'pushpin') {
                    infobox.setLocation(e.target.getLocation());
    		//infobox.setHtmlContent(info[e.target.getLocation()]);
    		
                    infobox.setMap(map);
    				
    		console.log(infobox);
                  }
    	}


    [Blog] [twitter] [LinkedIn]

    Friday, May 6, 2016 4:36 PM
  • That seems to have worked. I think I only have one question left. The close button. Since it is a custom infobox box, I created a close button for it. I'm using the following code to code it, but it's not working.

    function hideInfobox(e){
    	infobox.setOptions({ visible: false });
    }

    I'm getting to the function when I hit the X but the inbox.setOptions doesn't work. I was thinking that I might have to do the opposite of infobox.setMap(map), but I don't actually know what the reverse it. I looked at the API guide and didn't see setMap under the Infobox Class, https://msdn.microsoft.com/en-us/library/mt712643.aspx

    Thanks,

    Stephen

    Monday, May 9, 2016 2:30 PM
  • Instead of using visible, do infobox.setMap(null); to hide it.

    [Blog] [twitter] [LinkedIn]

    Monday, May 9, 2016 4:34 PM
  • Setting it the map to null does hide the infobox, but when I try to reopen there's an error Uncaught TypeError: Cannot read property 'offsetLeft' of undefined. Do I have to redefine some of the options with .setOptions()?
    Monday, May 9, 2016 6:29 PM
  • When reopening it you would use infobox.setMap(map); and shouldn't see any errors.

    That said, the original issue with infobox visible option has been corrected and is available in the experimental branch. You can test this by adding "&branch=experimental" to the map script URL. You can then use infobox.setOptions({visible: [true/false]}); to hide/show it. This fix will be merged into the release branch in the next couple of weeks. Be sure to remove the experimental branch URL parameter from your app before going into production.


    [Blog] [twitter] [LinkedIn]

    Tuesday, May 10, 2016 1:25 AM
  • It seems like the issue to isolated to when I use the setHtmlContent() property in the displayInfobox function after trying to reopen the infobox. If I use the default infobox, then every works just as you mentioned. Is there a reason why using setHtmlContent prevents the infobox from generating after the first time? 
    Tuesday, May 10, 2016 3:19 PM
  • To do a walk through of what leads to the error:

    step 1: Map loads and pins are visible

    step 2: Click on pushpin and custom infobox displays next to pushpin

    step 3: Click on close button and infobox disappears

    step 4: Click on pushpin again and infobox doesn't display

    step 5: Check console in Chrome developer tools. Error after the step 4 saying "Uncaught TypeError: Cannot read property 'offsetLeft' of undefined"

    The code is what you have above with the changes you stated or made.

    After trying to look for a cause, I commented out the line "infobox.setHtmlContent(info[e.target.getLocation()]);" in the displayInfobox function in the code. Afterwards the infobox reverted back to the original infobox, but the open and close functionality worked properly. This make me believe that the issue is revolving around the setHtmlContent property.

    Tuesday, May 10, 2016 3:48 PM
  • Hi,

    I worked around the close button (X) problem by putting a click event on the outer div so that clicking anywhere in the infobox (other than on the main clickable items) calls a function that hides it, e.g.

    ...setHtmlContent(
    "<div id="ibx" onclick="hideInfoBox();" style="pointer-events:auto; cursor:default; background-color:rgb(240,240,240); border:1px solid rgb(192,192,192); width:200px; min-height:72px; font-size:16px;">
        <b style="; top:10px; left:16px; font-size:18px;">Title of Infobox</b>
        <a onclick="ibxDirectionsClicked();" style="cursor:pointer; ; top:40px; left:16px;">Directions</a>
        <a onclick="ibxWebsiteClicked();" style="cursor:pointer; ; top:40px; right:16px;">Website</a>
    </div>");

    The show/hideInfobox functions just set visible t/f - this works fine provided the X is not there or never clicked.

    JPL


    • Edited by JPL5780 Friday, May 13, 2016 2:27 PM
    Friday, May 13, 2016 2:26 PM
  • As noted in my last post in this thread. The bug was fixed already and is in the experimental branch of the SDK. You can test it there. It will be pushed into the release branch in the next week or two.

    [Blog] [twitter] [LinkedIn]

    Friday, May 13, 2016 5:56 PM