The Server side uses python with flask, and the html template is jinja2. I'm trying to make a marker with google api. The latitude and longitude information are stored in stores[][] which is passed from python. This code is between <script> tag in my html file and it works fine.
var marker = new google.maps.Marker({position: {lat: {{stores[0][5]}}, lng: {{stores[0][6]}}}, map: map});
var marker = new google.maps.Marker({position: {lat: {{stores[4][5]}}, lng: {{stores[4][6]}}}, map: map});
I have multiple lat,lng from which I want to make markers, so I put it inside a for loop.
var i;
for (i = 0; i < 5; i++) {
var marker = new google.maps.Marker({position: {lat: {{stores[i][5]}}, lng: {{stores[i][6]}}}, map: map});
}
Exactly same code, but the index is i was put instead of a number for indexing. It suddenly gives errors saying
jinja2.exceptions.UndefinedError: list object has no element Undefined
I double checked that stores[][] have more than 5 elements. This is very very confusing.
You can't do this. Jinja is evaluated entirely on the server, well before the JS can run on the client. There is no way for Jinja to have access to variables from the JS code.
You should move the loop to Jinja itself.
{% for store in stores %}
var marker = new google.maps.Marker({position: {lat: {{ store[5] }}, lng: {{ store[6] }}}, map: map});
{% endfor %}
Related
I can't figure out how to replace digital longitude and latitude values with dynamic fields from postgres in javascript
how to get the longitude and latitude of a particular place in this script?
<div id='map' style='width: 100%; height: 400px;'></div>
<script>
mapboxgl.accessToken = '{{ mapbox_access_token }}';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v10',
center: [20.890438, 52.256002],
// {{venue.lat}}, {{venue.long}} How to pass fields in a similar way as all other django fields
zoom: 9
});
var marker= new mapboxgl.Marker()
.setLngLat([20.890438, 52.256002])
// {{venue.lat}}, {{venue.long}}
.addTo(map)
</script>
All rendering functions in django. Here's how to send a specific longitude and latitude for a specific event.
def show_venue(request, venue_id):
venue = Venue.objects.get(pk=venue_id)
venue_owner = User.objects.get(pk=venue.owner)
long = Venue.objects.get(pk=venue.long)
lat = Venue.objects.get(pk=venue.lat)
#addresses = Venue.objects.all()
mapbox_access_token = 'pk.eyJ1IjoicGF2ZWxzdHJ5a2hhciIsImEiOiJjbDI2ZmJmcTkyajBwM2lscDd6aDVwOG4xIn0.15o8i7eD1qwyQcnsx2iBmg'
return render(request,
'events/show_venue.html', {
'venue': venue,
'venue_owner':venue_owner,
#'addresses': addresses,
'mapbox_access_token': mapbox_access_token,
'lat':lat,
'long':long,
})
I will be very grateful for your help
In Django i would write like this
{{venue.long}} {{venue.lat}}
and in JavaScript it should be like this
['{{venue.long}}','{{venue.lat}}']
If the problem is the format, you can try this:
center: [{{venue.lat|floatformat:'5'}}, {{venue.long|floatformat:'5'}}]
please i work in project and i want to display many markers on map , i want to display arr[][] from jsp to javascrpit like this code,
please i work in project and i want to display many markers on map , i want to display arr[][] from jsp to javascrpit like this code
for ex:
i want to replace this code :
for (var i = 0; i < 3; i++) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng( 17.088291,78.442383 ),
map: map,
});
to :
for (var i = 0; i < 3; i++) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng( arr[i][0],arr[i][1] ),
map: map,
});
<!DOCTYPE html>
<html>
<head>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyD4DvaNOnpTRUFASvy6lyY0DDVcfXytvnY&libraries=places&&callback=initMap">
</script>
<script>
<%!
double arr[][]= new double[3][2];
%>
<%
arr[0][0]=19.088291;
arr[0][1]= 78.442383;
arr[1][0]=18.088291;
arr[1][1]=78.442383;
arr[2][0]=17.088291;
arr[2][1]=78.442383;
%>
function loadMap() {
var mapOptions = {
center:new google.maps.LatLng(19.373341, 78.662109),
zoom:7
}
var map=new google.maps.Map(document.getElementById("sample"),mapOptions);
//animation:google.maps.Animation.BOUNCE
for (var i = 0; i < 3; i++) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng( 17.088291,78.442383 ),
map: map,
});
}
}
</script>
</head>
<body onload="loadMap()">
<div id="sample" style="width:580px;height:400px;"></div>
</body>
</html>
the simple answer
add this line in jsp code
String json = new Gson().toJson(array);
and in javascript add this line
var arr=<%=json%>;
code will work
I think you have got two options here:
A. Use out.print in the loop, it I think you already tried that but forgot something very important - <% and %>
So the final line of code should look like:
new google.maps.LatLng(<% out.print(arr[i][0]); %>, <% out.print(arr[i][1]); %>
B. Convert the whole JSP array to JSON and decode back. Although not the simplest solution but can be useful in many places like external services etc. You can use a library like Gson.
I want to pass latitude,longitude variables to my template to show location on Google Maps. For that i use template variables in javascript:
<script type="text/javascript">
var map;
function initMap() {
map = new google.maps.Map(document.getElementById("map"), {
center: {lat: {{ m_city.location.y }}, lng: {{ m_city.location.x }}},
zoom: 10
});
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=KEY&callback=initMap"
async defer></script>
It works fine in Firefox, but Chrome(v.42) doesn't show map at all. Although in source code of generated page latitude and longitude are correctly substituted.
If i copy generated latitude and longitude and hard code it in template then code works and Chrome displays map.
Can anyone point me to why this is happening?
UPDATE
As Selcuk pointed in comments, problem was in decimal separator(comma instead of point). Different separators were generated because of different language settings of browsers. Setting USE_L10N to False helped.
I suggest to use localize templatetag, so you can use format localisation without breaking your javascript code.
{% localize off %}
<script type="text/javascript">
var map;
function initMap() {
map = new google.maps.Map(document.getElementById("map"), {
center: {lat: {{ m_city.location.y }}, lng: {{ m_city.location.x }}},
zoom: 10
});
}
</script>
{% endlocalize %}
<script src="https://maps.googleapis.com/maps/api/js?key=KEY&callback=initMap"
async defer></script>
I am working on a flask + jinja2 website which involves plotting some stored markers on a map.
Python code
resultroute['checkpointlist'] = CheckPoint.query.filter_by(route_id=route.code)
return render_template('routes/edit.html',route=resultroute)
Javascript in edit.html
function addExistingMarkers() {
//Individual access to elements
var name0 = '{{route.checkpointlist[0].name}}';
var lat0 = {{route.checkpointlist[0].latitude}};
var long0 = {{route.checkpointlist[0].longitude}};
var marker = new google.maps.Marker({
position: new google.maps.LatLng({{ route.checkpointlist[0].latitude }}, {{ route.checkpointlist[0].longitude }}),
map: map,
title: '{{ route.checkpointlist[0].name }}'
});
//Trying to iterate over the list
{% for checkpoint in route.checkpointlist %}
var lat = checkpoint.latitude;
var long = checkpoint.longitude;
var cpname = checkpoint.name;
var location = new google.maps.LatLng(lat, long);
var marker = new google.maps.Marker({
map: map,
draggable:true,
title:cpname,
animation: google.maps.Animation.DROP,
position: location,
});
{% end for %}
}
Only one marker is getting placed which is from the individual access of [0] element. But somehow the for loop is not working.
{% for checkpoint in route.checkpointlist %}
var lat = {{checkpoint.latitude}};
var long = {{checkpoint.longitude}};
var cpname = {{checkpoint.name}};
var location = new google.maps.LatLng(lat, long);
var marker = new google.maps.Marker({
map: map,
draggable: true,
title: cpname,
animation: google.maps.Animation.DROP,
position: location,
});
{% end for %}
You need to include the double braces when referencing variable in a Jinja template.
Your tips helped me to build my JS function,
but I would like to make an adjustment,
you need to use {% endfor %} instead of {% end for %}.
I'm trying to set up a relatively simple info window using google maps api. I want to put multiple variables into my info window from my django backend. If I only include one variable it works fine. However, if I try to include multiple variables then nothing is rendered. I cannot figure out why. This is the offending line:
'<h1 id="infolayer-title" class="firstHeading">{{ variable1 }} {{ variable2 }}</h1>'+
However, this works fine, strangely:
'<h1 id="infolayer-title" class="firstHeading">{{ variable1 }}</h1>'+
The variables are being properly rendered in the markup, but there is a javascript error. The javascript console says SyntaxError: missing ; before statement on the line printed above, but including a semicolon before or after the variable has not solved the problem.
Here is the full implementation (most of which is straight from the maps api docs):
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script>
function initialize() {
var myLatlng = new google.maps.LatLng(122, 5);
var mapOptions = {
zoom: 15,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var contentString = '<div id="content">'+
'<div id="infolayer">'+
'</div>'+
'<h1 id="infolayer-title" class="firstHeading">{{ variable1 }} {{ variable2 }}</h1>'+
'<div id="bodyContent">'+
'<p><b>Uluru</b>, also referred to as <b>Ayers Rock</b>, is a large ' +
'Heritage Site.</p>'+
...
'</div>'+
'</div>';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: 'Hello World!'
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,marker);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
How can I get the map to render using multiple variables in the Info Layer Window? Thanks for any ideas that may help with this confusing problem!
The apostrohpe in SomeDude's is acting as the end of the contentString for that line, then there is more content after it. You need to escape this variable, which should happen by default so maybe you turned off autoescaping? Try replacing with this:
'<h1 id="infolayer-title" class="firstHeading">{% autoescape on %}{{ variable1 }} {{ variable2 }}{% endautoescape %}</h1>'+
It will encode the ' in SomeDude's as ' for a rendering of SomeDude's which will not break your string.