Search code examples
javascriptoopleaflet

Adding a on click event handler that uses an object method


I'm trying to build a wrapper JavaScript class for leaflet. I need to bind on click events to the map (and next to buttons inside the popups) and I honestly have no idea how to do it.

I can't get the class method selectorClick() to run at all. I need to be able to pass parameters into it as well.

Code: https://codepen.io/hendr1x/pen/GRKLjrW

class Map {
    self = this;
    name = '';
    elem;
    theme = 'http://b.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png';

    constructor(name) {
        self.name = name;
        self.elem = L.map(name).fitWorld().zoomIn();
        L.tileLayer(this.theme, {
            attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors',
            maxZoom: 18,
        }).addTo(self.elem);
    }

    selector(url, message) {
        self.elem.on("click", self.selectorClick(url, message));
    }

    selectorClick(url, message) {
        alert(message);
    }
}
var mapMap = new Map('map');
mapMap.selector('/index.php', 'test message');

Edit

Let me explain that the example I provided removed a lot of complexity from my actual situation because I am storing a lot on the data server. So for what we are looking at currently I have something like this in my controller

$this->c->map->init('mapElem');
$this->c->map->selector('/example/submit/index.php', 'You clicked this example');

which eventually echo's the following

echo "window." . $name . "Map = new Map('" . $name . "');";
echo $name . "Map.selector('" . $url . "', '" . $message . "');";

So with that in mind I am trying to run as much code via an external js file and send in all dynamic values as I use it (as I did above). So to answer your question I need to pass in url and message so when the map gets click I have the data to create the popup properly.


Solution

  • There are plenty of ways to handle something like this.. It all just depends on what you are wanting to accomplish.

    Which parameters do you want to pass to the selectorClick method? What do you want to accomplish with selectorClick?

    class Map {
      constructor(id) {
        this.elem = L.map(id).fitWorld().zoomIn();
        this.name = id;
        this.theme = "http://b.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png";
        this.url = "";
        this.message = "";
        
        this.selectorClick = this.selectorClick.bind(this);
        this.elem.on("click", this.selectorClick);
        
        L.tileLayer(this.theme, {
          attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors',
          maxZoom: 18
        }).addTo(this.elem);
      }
      
      selector(url, message) {
        this.url = url;
        this.message = message;
      }
    
      selectorClick(event) {//<--- event is automatically passed in because of the 'onclick' handler
        let location = event.latlng;
        alert(`POST DATA HERE:\n\n${JSON.stringify(location, null, 2)}`)
      }
    }
    
    const mapMap = new Map("map");
    mapMap.selector("/index.php", "test message");
    #map { height: 180px; }
    <html>
    
    <head>
      <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin="" />
      <script src="https://unpkg.com/[email protected]/dist/leaflet.js" integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og==" crossorigin=""></script>
    </head>
    
    <body>
      <div style="text-align:center;">
        <h2>Click Anywhere On Map</h2>  
      </div>
      <div id="map"></div>
      </div>
    </body>
    
    </html>