I looked through every answer that I can find here and cannot solve it. I am pretty sure that I did not miss anything obvious.
I am trying to load map markers based on long long. The problem is that when I try to return an AJAX response, since responseXML is always null, if I use responseText, it works fine, but obviously the next step doesn't work.
This is the PHP that generates the XML:
<?php header('Content-type: text/xml'); ?> <?xml version="1.0" encoding="ISO-8859-1"?> <properties> <![CDATA[ <?php if ($body != null): foreach ($body as $property): ?> <property> <lat><?php echo $property -> lat; ?></lat> <long><?php echo $property -> long; ?></long> <name><?php echo $property -> property_name; ?></name> </property> <?php endforeach; endif; ?> ]]> </properties>
I see in Fiddler that the request is made ok
GET /letsgo/index.php/hotmaps/get_properties_ajax/22.270888501350186/22.288560098193066/114.13720860290528/114.19827713775635 HTTP / 1.1
Entity Content-type: text / xml
Although, when I look at this in an XML representation in a creak, it seems empty,
here is the original answer
HTTP/1.1 200 OK Date: Tue, 15 Jan 2013 11:04:27 GMT Server: Apache/2.4.2 (Win32) PHP/5.4.4 X-Powered-By: PHP/5.4.4 Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-Length: 310 Keep-Alive: timeout=5, max=100 Connection: Keep-Alive Content-Type: text/xml <?xml version="1.0" encoding="ISO-8859-1"?> <properties> <![CDATA[ <property> <lat>22.2776</lat> <long>114.173</long> <name>Kaxo Tower test</name> </property> <property> <lat>22.2803</lat> <long>114.16</long> <name>Kuno Tower</name> </property> ]]> </properties>
Here is the create marker function, which is called every time the map moves.
// make the ajax request function loadXMLDoc(downUrl){ var xmlhttp; if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp=new XMLHttpRequest(); } else {// code for IE6, IE5 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState==4 && xmlhttp.status==200) { //var propertiesXml = xmlhttp.responseText; // WORKS FINE!! var propertiesXml = xmlhttp.responseXML; // ALWAYS null //alert(propertiesXml); var propertiesRows = propertiesXml.getElementsByTagName("property"); for (var i = 0; i < propertiesRows.length; i++) { var propertiesRow = propertiesRows[i]; var xmlLat = propertiesRow.getElementsByTagName("lat")[0]; var xmlLong = propertiesRow.getElementsByTagName("long")[0]; var propertyLatLong = new google.maps.LatLng(parseFloat(xmlLat.firstChild.data),parseFloat(xmlLat.firstChild.data)); // create each marker createMarker(propertyLatLong); } } } xmlhttp.open("GET", downUrl, false); // false or true? makes no difference xmlhttp.setRequestHeader("Content-type", "text/xml"); xmlhttp.send(); }
and this is the error I get to load getElementsByTagName with a null value, the Chrome console reports
Uncaught TypeError: cannot call getElementsByTagName method from null
This works on my local Apache
Any suggestions?
/ ** UPDATE - WORK CODE ** /
<!DOCTYPE html> <html> <head> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <style type="text/css"> html { height: 100% } body { height: 100%; margin: 0; padding: 0 } #map_canvas { height: 100% } </style> <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=APIKEYHERE&sensor=false"> </script> <script type="text/javascript"> // initialise map function initialize() { // set starting latlong var myLatlng = new google.maps.LatLng(22.2776, 114.173); // set initial map options var mapOptions = { center: myLatlng, zoom: 13, mapTypeId: google.maps.MapTypeId.ROADMAP }; // create the map var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions); // listen for changes in map bounds - after map has stopped moving!! google.maps.event.addListener(map,'idle', function () { loadByBounds(map); }); } // if the bounds have changed function loadByBounds(map) { var bounds = map.getBounds(); var swPoint = bounds.getSouthWest(); var nePoint = bounds.getNorthEast(); // specific co ordinates var swLat = swPoint.lat(); var swLng = swPoint.lng(); var neLat = nePoint.lat(); var neLng = nePoint.lng(); var downUrl = "<?php echo site_url('hotmaps/get_properties_ajax'); ?>/"+swLat+"/"+neLat+"/"+swLng+"/"+neLng; // load the loadXMLDoc(downUrl, map); // clear icons outside of bounding box //.... } // make the ajax request function loadXMLDoc(downUrl, map){ var xmlhttp; if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp=new XMLHttpRequest(); } else {// code for IE6, IE5 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState==4 && xmlhttp.status==200) { var propertiesXml = xmlhttp.responseText; // WORKS FINE!! // remove whitespaces from start and end (.trim() doesnt work) propertiesXml = propertiesXml.replace(/^\s+|\s+$/g,''); // manually parse to XML DOM object var parser = new DOMParser(); var xmlDoc; try { xmlDoc = parser.parseFromString (propertiesXml, "text/xml"); } catch (e) { alert ("XML parsing error."); return false; }; //console.log(xmlDoc); // get each property var propertiesRows = xmlDoc.getElementsByTagName("property"); //alert(console.log(propertiesRows)); for (var i = 0; i < propertiesRows.length; i++) { var propertiesRow = propertiesRows[i]; var xmlLat = propertiesRow.getElementsByTagName("lat")[0]; var xmlLong = propertiesRow.getElementsByTagName("long")[0]; var propertyLatLong = new google.maps.LatLng(parseFloat(xmlLat.firstChild.data),parseFloat(xmlLong.firstChild.data)); // create each marker createMarker(propertyLatLong, map); } } } xmlhttp.open("GET", downUrl, false); xmlhttp.setRequestHeader("Content-type", "text/xml"); xmlhttp.send(); } // create new markers function createMarker(propertyLatLong, map){ var dynamicMarker = new google.maps.Marker({ map:map, draggable:false, position: propertyLatLong }); debugger; } </script> </head> <body onload="initialize()"> <div id="map_canvas" style="width:100%; height:100%"></div> </body> </html>