Search code examples
javascriptleafletmarkers

Change marker text with button on Leaflet map


I have a map with markers, generated by a json file, that contain a text with numeric value. For markers generation I use the Beaufify Markers Plugin. This is a part of code that I'm using

var map = L.map('mapid').setView([43.08, 12.34], 9);

for ( var i=0; i < markers.length; ++i ) {
    options = {
      isAlphaNumericIcon: true,
      text: markers[i].temperatura,
      iconSize: [28, 28],
      borderColor: markers[i].color,
      backgroundColor: markers[i].color,
      innerIconAnchor: [0, 4],
      textColor: '#000;'
    };
    var popup = L.popup({
      pane: 'fixed',
      className: 'popup-fixed',
      autoPan: false,
    }).setContent('my html code');

    L.marker( [markers[i].lat, markers[i].lng], {
        icon: L.BeautifyIcon.icon(options),
        virtual: true
    })
    .bindPopup(popup)
    .addTo( map );
}

I would like the best and cleanest way, to change the variable text on options ('markers[i].temperatura'), with an onclick action on a button.


Solution

  • To update marker icon text:

    1) save the list of markers into global variable, for example:

    var markerObjects = [];
    for (var i=0; i < markers.length; ++i ) {
        //...
    
        var markerObject = L.marker( [markers[i].lat, markers[i].lng], {
            icon: L.BeautifyIcon.icon(options),
            virtual: true
        })
        .bindPopup(popup)
        .addTo( map );
        markerObjects.push(markerObject);
    
    }
    

    2) once the button is clicked, update marker icon via Marker.setIcon method:

    btn.onclick = () => {
        const selectedIndex = ...;  //get the selected index of marker 
        const selectedMarker = markerObjects[selectedIndex];
        let iconOptions = selectedMarker.options.icon.options; //get existing icon properties
        iconOptions.text = txtName.value; //update icon property
        selectedMarker.setIcon(L.BeautifyIcon.icon(iconOptions)); //update marker icon 
    };
    

    Demo

    const map = L.map("map").setView([53.339025, 18.065818], 4);
    
    L.tileLayer("http://{s}.tile.osm.org/{z}/{x}/{y}.png", {
      attribution:
        '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map);
    
    const locations = [
      {
        name: "Oslo",
        lat: 59.923043,
        lng: 10.752839
      },
      {
        name: "Stockholm",
        lat: 59.339025,
        lng: 18.065818
      },
      {
        name: "Copenhagen",
        lat: 55.675507,
        lng: 12.574227
      },
      {
        name: "Berlin",
        lat: 52.521248,
        lng: 13.399038
      },
      {
        name: "Paris",
        lat: 48.856127,
        lng: 2.346525
      }
    ];
    
    const markers = locations.map(location => {
      let options = {
        isAlphaNumericIcon: true,
        text: location.name,
        iconSize: [98, 28],
        textColor: "#000;"
      };
      let popup = L.popup({
        className: "popup-fixed",
        autoPan: false
      }).setContent(location.name);
    
      return L.marker([location.lat, location.lng], {
        icon: L.BeautifyIcon.icon(options),
        virtual: true
      })
        .bindPopup(popup)
        .addTo(map);
    });
    
    initControl();
    
    function initControl() {
      
    
      let selectLocations = document.getElementById("selectLocations");
      let idx = 0;
      for (const marker of markers) {
        const option = document.createElement("option");
        option.value = idx;
        option.text = marker.options.icon.options.text;
        selectLocations.appendChild(option);
        idx++;
      }
    
      let txtName = document.getElementById("txtName");
      txtName.value = locations[selectLocations.selectedIndex].name;
      selectLocations.onchange = e => {
        txtName.value = markers[e.target.value].options.icon.options.text;
      };
    
      let btnUpdate = document.getElementById("btnUpdate");
      btnUpdate.onclick = () => {
        const selectedIndex = selectLocations.selectedIndex;
        const selectedMarker = markers[selectedIndex];
        let iconOptions = selectedMarker.options.icon.options; //get existing icon properties
        iconOptions.text = txtName.value; //update text property
        selectedMarker.setIcon(L.BeautifyIcon.icon(iconOptions)); //set icon 
      };
    }
    <link
      rel="stylesheet"
      href="https://unpkg.com/leaflet@1.3.4/dist/leaflet.css"
    />
    <link rel="stylesheet" href="style.css" />
    <script src="https://unpkg.com/leaflet@1.3.4/dist/leaflet.js"></script>
    
    
    <link
      rel="stylesheet"
      href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css"
    />
    <link
      rel="stylesheet"
      href="https://marslan390.github.io/BeautifyMarker/leaflet-beautify-marker-icon.css"
    />
    
    <script src="https://marslan390.github.io/BeautifyMarker/leaflet-beautify-marker-icon.js"></script>
    
    
    <select id="selectLocations">
    </select>
    <input id="txtName" type="text"/>
    <button id="btnUpdate">Update</button> 
    <div id="map" style="height:410px; width:570px;"></div>