Can't call javascript function from a anchor element in innerhtml - undefined

45 Views Asked by At

I have a list of collapsible divs that is populated with data from a geoJson file and updated dynamically when you zoom in and out of a map, to reflect the markers that are within the bounds of the map.

When you click on the collapsible div it opens to show details about the feature.

I would like to add a link/button underneath the information shown that says 'Zoom To Marker', that zooms the map to the marker location when it is clicked.

I have tried many ways of doing this but whatever I do the ZoomTo() function I call is always undefined. The ZoomTo() function is above the function in the external javascript file that creates the list and link.

This is driving me crazy, it seems like it should be so simple. The link shows ok but when it is clicked on the following error occurs

Uncaught ReferenceError: ZoomTo is not defined
javascript:ZoomTo(extent);:1

I have tried a variety of suggestion from StackOverflow but to no avail, making it global, having the function above, using buttons and apending them. The functions are within an initMap function that is called when the window loads

FeatureType function is called from eventhandlers when the map changes.

function ZoomTo(extent) {
  //map.getView().fit(extent,{padding: [100, 100, 100, 100],maxZoom:15, duration:500}); 
  alert(extent);
}

function FeatureType(mapfeaturetype, mapExtent) {
  htmlStr = "<div class='accordion' id="
  accordianExample ">";

  // iterate through the feature array
  for (var i = 0, ii = mapfeaturetype.length; i < ii; ++i) {
    var featuretemp = mapfeaturetype[i];

    // get the geometry for each feature point
    var geometry = featuretemp.getGeometry();
    var extent = geometry.getExtent();
    extent = ol.proj.transformExtent(extent, 'EPSG:3857', 'EPSG:4326');

    //If the feature is within the map view bounds display its details
    //in a collapsible div in the side menu
    var inExtent = (ol.extent.containsExtent(mapExtent, extent));
    if (inExtent) {

      htmlStr += "<div class='accordion-item'><div class='accordion-header' id='oneline'>"
      htmlStr += "<span class='image'><img src=" + imgType + "></span><span class='text'>"
      htmlStr += "<a class='btn' data-bs-toggle='collapse' data-bs-target='#collapse" + i + "' href='#collapse" + i + ""
      htmlStr += "aria-expanded='false' aria-controls='collapse" + i + "'>" + featuretemp.get('Name') + "</a></span>"
      htmlStr += "</div><div id='collapse" + i + "' class='accordion-collapse collapse' data-bs-parent='#" + accordionid + "'>"
      htmlStr += "<div class='accordion-body'><h3>" + featuretemp.get('Address') + "</h3><h3>" + featuretemp.get('ContactNo') + "</h3>"
      htmlStr += "<h5><a href=" + featuretemp.get('Website') + " target='_blank'> " + featuretemp.get('Website') + " </a></h5>"
      htmlStr += "<h5>" + featuretemp.get('Email') + "</h5><h5>" + featuretemp.get('Descriptio') + "</h5>"
      htmlStr += "<div id='zoom'><a href='javascript:ZoomTo(extent);'>Zoom to Marker</a></div>"
      htmlStr += "</div></div></div>";

    }; //end if 
  }; //end loop

  htmlStr += "</div>"
  document.getElementById("jsoncontent").innerHTML += htmlStr
}
1

There are 1 best solutions below

0
Graeme Stuart On

Use a button with an event listener

Your problem can be reduced to this example:

A simple HTML document with a script (I've used a module).

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="module" src="script.js"></script>
</head>
<body>
    
</body>
</html>

The script defines two functions and calls one.

function ZoomTo(extent) {
    alert(extent);
}

function FeatureType() {
    document.body.innerHTML += "<a href='javascript:ZoomTo(extent);'>Zoom to Marker</a>";
}

FeatureType()

The above code reproduces your error exactly.

We can fix it by using a more sophisticated approach to HTML generation and event handling.

Here we create a button and call the ZoomTo function in an event handler.

function FeatureType() {
    const button = document.createElement('button');
    button.textContent = 'Zoom to marker';
    document.body.append(button);
    button.addEventListener('click', ev => {
        ZoomTo('test');
    });
}