4

I found this code click here and edited to show the marker coordinates in textarea field once the user clicks on the map to add a marker but it gave an error Uncaught TypeError: document.getElementById(...) is null.

I need someone to help making this works. thank you.

map = folium.Map(location=[lat, lng], zoom_start=20)
# country = location.country
marker = folium.Marker(
    [lat, lng],
    zoom_start=20,
    tooltip=tooltip,
    width=100,
    height=70,
    icon=folium.Icon(color="red", icon=""),
    popup=site,
).add_to(map)
map.add_child(folium.LatLngPopup())

mapJsVar = map.get_name()

map.get_root().html.add_child(
    folium.Element(
        """
<script type="text/javascript">

$(document).ready(function () {
{map}.on("click", addMarker);

function addMarker(e) {
    // ustawiamy aby marker był przesuwalny
    const marker = new L.marker(e.latlng, {
    draggable: true,
    }).addTo({map});
    document.getElementById('clk_lat1').innerHTML = marker.getLatLng().lat;
    document.getElementById('clk_lng1').innerHTML = marker.getLatLng().lng;
}
});

</script>
""".replace(
            "{map}", mapJsVar
        )
    )
)
map = map._repr_html_()
context = {"map": map}

this is the HTML code:

<div align="center" class="form-group"></div>
<p style="font-size:18px; color:blue;">Marker Location:</p>
<div >
   Lat:  
   <text-area name="clk_lat1" id = "clk_lat1" >
   </text-area>
   Lng: 
   <text-area name="clk_lng1" id = "clk_lng1" ></text-area>
</div>
</div>
Abdelrahman
  • 525
  • 1
  • 4
  • 13
Khalid Seflan
  • 71
  • 1
  • 6
  • Can you create a JSFiddle or something of the like so we could play around with the problem you have? – Lajos Arpad Apr 15 '23 at 11:56
  • 1
    Please check this [link] (https://jsfiddle.net/seflanka/6cghd04j/32/). thank you. – Khalid Seflan Apr 16 '23 at 10:09
  • Thanks, Khalid! The link does not quite work yet, you are closing the script tag in your Javascript section. Can you provide reproduction steps so we can see the problem? Thanks! – Lajos Arpad Apr 16 '23 at 13:21
  • thanks Lajos.. please check this [link](https://jsfiddle.net/247oqtve/15/). regards, – Khalid Seflan Apr 17 '23 at 19:54
  • I have taken a look, but the repro steps of the problem are still unclear to me. Please excuse me if I'm missing something. – Lajos Arpad Apr 18 '23 at 21:50
  • It is working fine from inside javascript file. but if you run the same code by Python it does give same error document.getElementById(...) is null. this is the code I am using: map.get_root().html.add_child(folium.Element(""" """.replace("{domap}", mymap))) – Khalid Seflan Apr 20 '23 at 19:39
  • @KhalidSeflan I will look at the problem in python with folium, hopefully will answer you tomorrow. By the way, it's best to use "@username" when you're mentioning a user for them to be notifiedabout your comment or comment on the answer. goodnight! – Abdelrahman Apr 20 '23 at 21:08
  • @KhalidSeflan could yo provide the values of `tooltip` and `site` in the `marker = folium.Marker` in the python code – Abdelrahman Apr 22 '23 at 09:47
  • 1
    @KhalidSeflan also I want to know your end goal for using `folium`. I want answer to those three questions: **1.** Do you want to add popups (that includes custom data) to markers added by folium? **2.** Are the markers positions predefined in your data or are there added later in the map when the user click and you want to bind data from python to those newly generated markers? **3.** Is the data you want to bind to the markers are just the marker position or other custom data that may depend on the marker positions? – Abdelrahman Apr 22 '23 at 09:57
  • 1
    @Abdelrahman answering your questions: 1- yes, I need to add popups to markers added by folium. 2- the markers will be added later by clicking on the map by the user. 3- the data I want to collect from the added markers is only the positions. – Khalid Seflan Apr 27 '23 at 06:30
  • 1
    @KhalidSeflan If the markers are added by the user on the map html later, currently it's not possible to communicate user input in the map through javascript back to the folium python code, you may read this issue in [here in Github](https://github.com/python-visualization/folium/issues/1070). Hence, in folium you can only add markers with popups if the positions are known before hand. Any later added markers positions can't be accessed by python, they're only avaialbe on the html page as in the answer below. – Abdelrahman Apr 27 '23 at 11:09
  • 1
    @KhalidSeflan However, it's possible to collect whatever user input data you like (in your case marker positions) on the map and send them to a server where you can use those data and manipulate them as you like whether you're using python or any other language and libraries, and send back any results you like to display on the map. In this case, it's a website with client and server communication. – Abdelrahman Apr 27 '23 at 11:14
  • 1
    @Abdelrahman I got your point. But what about writing javascript using am using: map.get_root().html.add_child(folium.Element(""" """.replace("{domap}", mymap))) and get the clicked marker position. The issue I faced when I click on the map I got this error document.getElementById(...) is null. Is it because the html element within the page itself?. Thank you for your help. – Khalid Seflan Apr 27 '23 at 14:05
  • @KhalidSeflan that's depends on your `popup`, as if the html of the `popup` element is added after clicking on the marker, the element won't be present on the map document, that's why searching it by its id returns null. That's why I wanted to know the `popup` and `tooltip` values. But if the elements you search for are present from the beginning inside the map, it shouldn't return null. You're welcome, brother. – Abdelrahman Apr 27 '23 at 16:32

1 Answers1

2

Try this, I commented out the alert in alert(newLatLng). Your code did work by the way, but there was some errors due to putting incorrectly scripts in javascript file, script tags should be in the html file (preferably at the bottom of the body, so they access the dom after it's loaded, otherwise the script would work before the dom document is loaded and querySelector and findbyid would return undefined).

Notes:

  • It's not recommended to use textarea to display an output, you can use span or div and customize it as you like. HTML elements such as textarea are used as input fields.

// Map initialization
var map = L.map("map").setView([23.8859, 45.0792], 6);

//osm layer
var osm = L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
  attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
});
osm.addTo(map);

function onMapClick(e) {
  map.on("click", addMarker);

  function addMarker(e) {
    // ustawiamy aby marker był przesuwalny
    const marker = new L.marker(e.latlng, {
      //draggable: true,
    }).addTo(map);

    var lat = (e.latlng.lat);
    var lng = (e.latlng.lng);
    var newLatLng = new L.LatLng(lat, lng);
    // alert(newLatLng);
    document.getElementById('clk_lat1').innerHTML = lat;
    document.getElementById('clk_lng1').innerHTML = lng;
  }

}
map.on('click', onMapClick);
.page{ 
 display: flex; 
 height: 100vh;
 width: 100vw;
 padding: 0;
 
}
.divmap {
  flex: 2;
}
.map{
 height: 100%;
 width: 100%;
}

.form-group {
  flex: 1;
  padding: 1rem;
}

div.overlay {
  position: absolute;
  left: 100px;
  float: right;
  clear: both;
}

#overlay {
  position: absolute;
  width: 20%;
  height: 100%;
  left: 0;
  top: 0;
  float: left;
  clear: left;
}

form.myform {
  position: absolute;
  left: 15px;
  margin-top: -1px;
  width: 20%;
  height: 30%;
  float: left;
  clear: left;
}

div.markers {
  margin-top: -1px;
  float: left;
  width: 15%;
  margin-left: 390px;
  text-align: center;
}

div.card {
  float: left;
  width: 250px;
  margin-top: -1px;
  border-width: 1px;
  border-radius: 0rem;
  padding: 0rem;
  margin-left: 350px;
}
<head align="center">


  <!--<meta http-equiv="refresh" content="120">-->
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1, user-scalable=no, shrink-to-fit=no" />


  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" />
  <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />

  <link rel="stylesheet" href="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.css" />

  <!-- leaflet css  -->
  <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />

</head>

<div class="page">
  <div class="form-group">
    <p style="font-size:18px; color:blue;">Marker Location:</p>
    <div>
     <div>Lat: </div>
    <textarea rows="1" class="coord-result" name="clk_lat1" id="clk_lat1">
    </textarea>
     <div>Lng: </div>
      <textarea rows="1" class="coord-result" name="clk_lng1" id="clk_lng1"></textarea>
    </div>
  </div>
  <div class="divmap">
    <div class="map" id="map"></div>
  </div>

</div>

<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
Abdelrahman
  • 525
  • 1
  • 4
  • 13