1

Explanation of Issue

This isn't an easy one for me to explain as I'm not sure on what is going on at all. Basically I am currently having a play with the following Google APIs:

  • Geocoding API

  • Google Maps JavaScript API v3

  • Places API


I have been working with Google Chrome on Windows 7, and have successfully been able to create a system which uses the Google Maps API V3 and allows me to search a location and pull back businesses near that location based on the Geocoded LatLng created when the given location is sent through the Google Geocoder.

This is working fine on my PC in Google Chrome, but isn't working in FireFox or Internet Explorer. Further to this, it also does not work on my iPad with either Safari or Chrome, however it does work on my HTC M8 on both the native browsers and Chrome.

Basically a user searches a location (only searching "Southport" in the second input box without anything in the first works at the moment) and gets a list of businesses back within 25km. This search function returns results as expect in Chrome, but doesn't return results or center the map on the correct location otherwise.

There is a businesses xml schema produced during the search. This is empty when checking through Firebug in FireFox.

Imasges for how the system should look when working, and how it looks when it's not working are provided at the bottom as google drive downloads... you will need HTTPS:


How the map is generated



Initially load() is ran onload:

<body class="search" onload="load();">



This fires initialize();

The code that is ran is:

function initialize() {
    var input = document.getElementById('loc');
    var options = {componentRestrictions: {}};
                 
    new google.maps.places.Autocomplete(input, options);
}
             
google.maps.event.addDomListener(window, 'load', initialize);

FYI: After this, a number of scripts are called, these are included by the Google API I believe as they are not hard coded (In order: common.js, util.js, geocoder.js, controls.js, places_impl.js, map.js, infowindow.js, onion.js, stats.js and marker.js).

Just before the above bit of script is called, I have a reference to the Google Maps API. This again adds some more references to others .js files that aren't hardcoded:

<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=EXAMPLE_APIKEY&amp;sensor=false&amp;libraries=places"></script>
<script src="https://maps.gstatic.com/maps-api-v3/api/js/20/5/main.js"></script>
<script src="https://maps.gstatic.com/maps-api-v3/api/js/20/5/places.js"></script>  
<script type="text/javascript" src="/library/inc/structure/business/widgets/google-map/google-map.js"></script>



As you may notice, after the call to the Google Map API, main.js and places.js are also called, these are not hardcoded, after this google-map.js is called, and then beneath all this the initialize() function is called along with the other mentioned scripts.

load(); results in the following function being called (the vars at top are public vars for all of google-map.js):

//<![CDATA[
    var map;
    var businesses = [];
    var infoWindow;
    var locationSelect;

    function load() {
      map = new google.maps.Map(document.getElementById("map"), {
        center: new google.maps.LatLng(40, -100),
        zoom: 4,
        mapTypeId: 'roadmap',
        mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU}
      });
      infoWindow = new google.maps.InfoWindow();

      locationSelect = document.getElementById("locationSelect");
      locationSelect.onchange = function() {
        var businessNum = locationSelect.options[locationSelect.selectedIndex].value;
        if (businessNum != "none"){
          google.maps.event.trigger(businesses[businessNum], 'click');
        }
      };
   }



This creates the map, and also listens for when the user selects a location in the search results.


Getting the results

When search.php loads the follow function is ran:

var $_POST = <?php echo json_encode($_POST); ?>;    

        function searchLocation() {
         var address = $_POST["loc"];
         var geocoder = new google.maps.Geocoder();
         geocoder.geocode({address: address}, function(results, status) {
           if (status == google.maps.GeocoderStatus.OK) {
            searchLocationsNear(results[0].geometry.location);
           } else {
             alert(address + ' not found');
           }
         });
       }
        window.onload = searchLocation;




Which in turn runs searchLocationNear(); :

function searchLocationsNear(center) {
     clearLocations();

     var radius = document.getElementById('radiusSelect').value;
     var searchUrl = '/library/inc/structure/business/widgets/google-map/google-map.php?lat=' + center.lat() + '&lng=' + center.lng() + '&radius=' + radius;
     downloadUrl(searchUrl, function(data) {
       var xml = parseXml(data);
       var businessNodes = xml.documentElement.getElementsByTagName("business");
       var bounds = new google.maps.LatLngBounds();
       for (var i = 0; i < businessNodes.length; i++) {
        var business_id = businessNodes[i].getAttribute("business_id");
         var name = businessNodes[i].getAttribute("name");
         var address = businessNodes[i].getAttribute("address");
         createSearchResults(name, distance, i, business_id, address);
         createMarker(latlng, name, address);
         bounds.extend(latlng);
       }
       map.fitBounds(bounds);
       locationSelect.style.visibility = "visible";
       locationSelect.onchange = function() {
         var businessNum = locationSelect.options[locationSelect.selectedIndex].value;
         google.maps.event.trigger(businesses[businessNum], 'click');
       };
      });
    }




This LatLng is pushed through to Google-Map.php through the url:

/library/inc/structure/business/widgets/google-map/google-map.php?lat=' +     center.lat() + '&lng=' + center.lng() + '&radius=' + radius;




In google-map.php the following takes place:

$database="db_name";
$username="db_user";
$password="db_password";

$center_lat = $_GET["lat"];
$center_lng = $_GET["lng"];
$radius = $_GET["radius"];

// Start XML file, create parent node
$dom = new DOMDocument("1.0");
$node = $dom->createElement("businesses");
$parnode = $dom->appendChild($node);

// Opens a connection to a mySQL server
$connection=mysql_connect ($database, $username, $password);
if (!$connection) {
  die("Not connected : " . mysql_error());
}

// Set the active mySQL database
$db_selected = mysql_select_db($database, $connection);
if (!$db_selected) {
  die ("Can\'t use db : " . mysql_error());
}

// Search the rows in the markers table
$get_business_query = sprintf("SELECT business_id, address, name, lat, lng, ( 3959 * acos( cos( radians('%s') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('%s') ) + sin( radians('%s') ) * sin( radians( lat ) ) ) ) AS distance FROM businesses HAVING distance < '%s' ORDER BY distance LIMIT 0 , 20",  mysql_real_escape_string($center_lat),  mysql_real_escape_string($center_lng),
  mysql_real_escape_string($center_lat),
  mysql_real_escape_string($radius));
$get_business_result = mysql_query($get_business_query);

if (!$get_business_result) {
  die("Invalid query: " . mysql_error());
}

header("Content-type: text/xml");
  
while ($get_business_row = @mysql_fetch_assoc($get_business_result))
{
  $businessID         = $get_business_row['business_id'];
 
  $node = $dom->createElement("business");
 
  $newnode = $parnode->appendChild($node);
  $newnode->setAttribute("business_id", $get_business_row['business_id']);
  $newnode->setAttribute("name", $get_business_row['name']);
  $newnode->setAttribute("address", $get_business_row['address']);
}
echo $dom->saveXML();




A clever MySQL query then works out which of these businesses is located with a 25km radius (this is currently hard coded but will be an option eventually).

$get_business_query = sprintf("SELECT business_id, address, name, lat, lng,  ( 3959 * acos( cos( radians('%s') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('%s') ) + sin( radians('%s') ) * sin( radians( lat ) ) ) ) AS distance FROM businesses HAVING distance < '%s' ORDER BY distance LIMIT 0 , 20",  mysql_real_escape_string($center_lat),  mysql_real_escape_string($center_lng),
  mysql_real_escape_string($center_lat),
  mysql_real_escape_string($radius));
$get_business_result = mysql_query($get_business_query);



The rows of the result are then iterated through and an XML node is created for each:



while ($get_business_row = @mysql_fetch_assoc($get_business_result))
{
  $businessID         = $get_business_row['business_id'];
 
  $node = $dom->createElement("business");
 
  $newnode = $parnode->appendChild($node);
  $newnode->setAttribute("business_id", $get_business_row['business_id']);
  $newnode->setAttribute("name", $get_business_row['name']);
  $newnode->setAttribute("address", $get_business_row['address']);
}
echo $dom->saveXML();



The generated XML output is then read by Google-Map.js in searchLocationNear();

The rest of the Google-Map.js is as follows:

function createMarker(latlng, name, address) {
      var html = "<b>" + name + "</b> <br/>" + address;
      var marker = new google.maps.Marker({
        map: map,
        position: latlng
      });
      google.maps.event.addListener(marker, 'click', function() {
        infoWindow.setContent(html);
        infoWindow.open(map, marker);
      });
      businesses.push(marker);
    }

    function createSearchResults(name, distance, num, business_id, address) {
      var li = document.createElement("li");
      li.value = num;
      li.setAttribute("onmouseover", "selectBusinessOnMap(" + num + ")");
      li.setAttribute("onmouseout", "deselectBusinessOnMap(" + num + ")");
      //Start Search Results ---------------------------------

      //Name
      li.innerHTML += "<div class=\"result-name\"><a href=\"/business/" + business_username + "\" \">" + (num + 1) + ". " + name + "</a></div>";

      //Distance
      li.innerHTML += "<div class=\"result-distance\">(" + distance.toFixed(1) + ")";
      

      //End Search Results ---------------------------------
      locationSelect.appendChild(li);
    }

    function selectBusinessOnMap(num) {
      
        var businessNum = num;
        google.maps.event.trigger(businesses[businessNum], 'click');

    }

    function deselectBusinessOnMap(num) {
      
        infoWindow.close();
    }

    function downloadUrl(url, callback) {
      var request = window.ActiveXObject ?
          new ActiveXObject('Microsoft.XMLHTTP') :
          new XMLHttpRequest;

      request.onreadystatechange = function() {
        if (request.readyState == 4) {
          request.onreadystatechange = doNothing;
          callback(request.responseText, request.status);
        }
      };

      request.open('GET', url, true);
      request.send(null);
    }

    function parseXml(str) {
      if (window.ActiveXObject) {
        var doc = new ActiveXObject('Microsoft.XMLDOM');
        doc.loadXML(str);
        return doc;
      } else if (window.DOMParser) {
        return (new DOMParser).parseFromString(str, 'text/xml');
      }
    }

    function doNothing() {}

    //]]>


Link to Site

MyWorthy.Services

Ignore first input box, and enter Southport in the second and search. As per introduction to question it's only working in Chrome for me, not IE or Firefox etc.


Validation Errors

A couple of validation errors catch my eye but I'm not sure if are the cause, also no values will be submitted into the search through w3c so not sure if that's the reason for some errors

[Errors found while checking this document as HTML 4.01 Transitional!][11]


Links to research I have undertaken

Links to other questions with similar problems that I have attempted to apply to my own situation without much luck due to my lack of understanding of where the issue is actually occuring:

  1. Google maps api 3 with places DEMO works only in Chrome… why? - This one seems to describe my situation the best ...

Same happens in Firefox and IE9... map and elements all fine, but when you press search resets all check boxes, search box and produces no results - effectively resets.

... is mentioned in the comments, and I get the feeling that that is somehow what is happening with my issues, though I'm really not sure.

2. [Google Maps V3 JavaScript works only in Chrome?]

3. [PHP code works on Chrome, but not on Firefox or IE]

4. [Google Maps API GeoJSON not working with IE 11, but works in Chrome] - This link introduced me to this ...

<meta http-equiv="X-UA-Compatible" content="IE=edge" />

... not sure if this will have an affect and will be trying it out as soon as I get home later and will update this question with my findings (EDIT: It appears this is already in my code).

5. [What's the difference if exists or not?]

6. [Google Maps v2 to v3 API wrapper working in Chrome but not in Firefox / IE]

7. [Google Maps V3 JavaScript works only in Chrome?]

8. [Google Maps API and Javascript problem. It works perfectly in Firefox, WHY NOT Internet Explorer?] - Slightly unrelated I would have thought at first as the Error is only with IE, however I noticed this ...

okay i have figured it out. turned out I had a clash of variable names. I fixed it by renaming the map div DOM element from map to something else. it works great in Firefox and IE now. Thanks for all the help i did receive here.

... this has made me think that perhaps I too have the map div DOM element named as 'map'. EDIT: Tried this, changed a few bits called "map" but didn't change anything, not sure if it was the DOM element though.

9. [Google maps api not showing in Firefox and IE but showing in Chrome and safari][9] - I have also seen this error on my travels a number of times but I don't think it is this that is occurring, however I could be wrong. Basically in FF and IE some users get a grey box where the map should be due to a CSS bug. I am actually seeing the map centered on the USA.

So ... Please Help ... !!!

Any feedback on the question, the layout, the research etc etc would be appreciated so I learn how to really contribute to StackOverflow.

Also any help and advice at all would be massively appreciated as I have no idea where to start with this issue as I am not really used to having this only working in Chrome! Normally used to just IE not working!!!


------------ Please view links to question that I couldn't add due to only allowing 2 urls -----------

2: http://gotoanswer.com/?q=Google+Maps+V3+JavaScript+works+only+in+Chrome%3F

3: http://stackoverflow.com/questions/19693799/php-code-works-on-chrome-but-not-on-firefox-or-ie

4: http://stackoverflow.com/questions/26678721/google-maps-api-geojson-not-working-with-ie-11-but-works-in-chrome

5: http://stackoverflow.com/questions/6771258/whats-the-difference-if-meta-http-equiv-x-ua-compatible-content-ie-edge-e

6: http://stackoverflow.com/questions/20099944/google-maps-v2-to-v3-api-wrapper-working-in-chrome-but-not-in-firefox-ie

7: http://stackoverflow.com/questions/9760727/google-maps-v3-javascript-works-only-in-chrome

8: http://software.programming4.us/forums/t/101675.aspx

9: http://groups.google.com/forum/#!topic/google-maps-api/50z4juKrYEM

11: http://validator.w3.org/check?uri=http%3A%2F%2Fmyworthy.services%2Fsearch.php&charset=%28detect+automatically%29&doctype=Inline&ss=1&outline=1&group=1&No200=1&st=1&user-agent=W3C_Validator%2F1.3+http%3A%2F%2Fvalidator.w3.org%2Fservices





EDITS



This is what it should look like when searching "Southport" and getting results:

! http://drive.google.com/file/d/0B7Rzr6uvzmvAUVBfeWUzNU5FX0k/view?usp=sharing

This is what it should look like when it's not working in both FF and IE:

! http://drive.google.com/file/d/0B7Rzr6uvzmvAdzlGTGhiQldpZmM/view?usp=sharing

laser
  • 1,378
  • 13
  • 13
Adam
  • 53
  • 6
  • "Minimal". I've actually read your whole question but still don't know what the problem is. I've tested your website in both Chrome and IE10 and it "works" the same. By "works" I mean the location search typeahead works and when I click "Search" a map is displayed - strangely it's centered on the location I selected in IE10 but not in Chrome. – Sergiu Paraschiv Mar 30 '15 at 20:11
  • I've updated the initial description of the problem to explain it more and I have also add links to images on google drive for anyone to download. The only location that will work is "Southport" as the only businesses in the system are based there. When it works the map is of Southport Town Centre,and quite zoomed in. When it's not working it's centered on the USA label in the middle of the US. – Adam Mar 30 '15 at 20:34

1 Answers1

0

Your issue is with window.onload that you use in "search.php". It does not fire in IE10 or Firefox for me, but does fire on Chrome. I did not find what and where but I'm pretty sure there's something else using window.onload somewhere else in your code or some library you are including. That won't work, only the last callback you assign to window.onload will actually fire. Read this: Best practice for using window.onload

Community
  • 1
  • 1
Sergiu Paraschiv
  • 9,575
  • 5
  • 33
  • 45
  • Thanks, that was it, I was using window.onload to fire searchLocation();. I've added `searchLocation();` to the ``, and inside the function itself used a bit of logic to ensure it only actually does anything (other than the logic) when on the search page! Thank you so much for your massively speedy response and answer! You've been a massive help! – Adam Mar 30 '15 at 21:15