Using Razor within JavaScript - javascript

Is it possible or is there a workaround to use Razor syntax within JavaScript that is in a view (cshtml)?
I am trying to add markers to a Google map... For example, I tried this, but I'm getting a ton of compilation errors:
<script type="text/javascript">
// Some JavaScript code here to display map, etc.
// Now add markers
#foreach (var item in Model) {
var markerlatLng = new google.maps.LatLng(#(Model.Latitude), #(Model.Longitude));
var title = '#(Model.Title)';
var description = '#(Model.Description)';
var contentString = '<h3>' + title + '</h3>' + '<p>' + description + '</p>'
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var marker = new google.maps.Marker({
position: latLng,
title: title,
map: map,
draggable: false
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, marker);
});
}
</script>

Use the <text> pseudo-element, as described here, to force the Razor compiler back into content mode:
<script type="text/javascript">
// Some JavaScript code here to display map, etc.
// Now add markers
#foreach (var item in Model) {
<text>
var markerlatLng = new google.maps.LatLng(#(Model.Latitude), #(Model.Longitude));
var title = '#(Model.Title)';
var description = '#(Model.Description)';
var contentString = '<h3>' + title + '</h3>' + '<p>' + description + '</p>'
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var marker = new google.maps.Marker({
position: latLng,
title: title,
map: map,
draggable: false
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, marker);
});
</text>
}
</script>
Update:
Scott Guthrie recently posted about #: syntax in Razor, which is slightly less clunky than the <text> tag if you just have one or two lines of JavaScript code to add. The following approach would probably be preferable, because it reduces the size of the generated HTML. (You could even move the addMarker function to a static, cached JavaScript file to further reduce the size):
<script type="text/javascript">
// Some JavaScript code here to display map, etc.
...
// Declare addMarker function
function addMarker(latitude, longitude, title, description, map)
{
var latLng = new google.maps.LatLng(latitude, longitude);
var contentString = '<h3>' + title + '</h3>' + '<p>' + description + '</p>';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var marker = new google.maps.Marker({
position: latLng,
title: title,
map: map,
draggable: false
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, marker);
});
}
// Now add markers
#foreach (var item in Model) {
#:addMarker(#item.Latitude, #item.Longitude, '#item.Title', '#item.Description', map);
}
</script>
Updated the above code to make the call to addMarker more correct.
To clarify, the #: forces Razor back into text mode, even though addMarker call looks a lot like C# code. Razor then picks up the #item.Property syntax to say that it should directly output the contents of those properties.
Update 2
It's worth noting that View code really isn't a good place to put JavaScript code. JavaScript code should be placed in a static .js file, and then it should get the data that it needs either from an Ajax call or by scanning data- attributes from the HTML. Besides making it possible to cache your JavaScript code, this also avoids issues with encoding, since Razor is designed to encode for HTML, but not JavaScript.
View Code
#foreach(var item in Model)
{
<div data-marker="#Json.Encode(item)"></div>
}
JavaScript code
$('[data-marker]').each(function() {
var markerData = $(this).data('marker');
addMarker(markerData.Latitude, markerData.Longitude,
markerData.Description, markerData.Title);
});

I just wrote this helper function. Put it in App_Code/JS.cshtml:
#using System.Web.Script.Serialization
#helper Encode(object obj)
{
#(new HtmlString(new JavaScriptSerializer().Serialize(obj)));
}
Then in your example, you can do something like this:
var title = #JS.Encode(Model.Title);
Notice how I don't put quotes around it. If the title already contains quotes, it won't explode. Seems to handle dictionaries and anonymous objects nicely too!

You're trying to jam a square peg in a round hole.
Razor was intended as an HTML-generating template language. You may very well get it to generate JavaScript code, but it wasn't designed for that.
For instance: What if Model.Title contains an apostrophe? That would break your JavaScript code, and Razor won't escape it correctly by default.
It would probably be more appropriate to use a String generator in a helper function. There will likely be fewer unintended consequences of that approach.

What specific errors are you seeing?
Something like this could work better:
<script type="text/javascript">
//now add markers
#foreach (var item in Model) {
<text>
var markerlatLng = new google.maps.LatLng(#Model.Latitude, #Model.Longitude);
var title = '#(Model.Title)';
var description = '#(Model.Description)';
var contentString = '<h3>' + title + '</h3>' + '<p>' + description + '</p>'
</text>
}
</script>
Note that you need the magical <text> tag after the foreach to indicate that Razor should switch into markup mode.

That will work fine, as long as it's in a CSHTML page and not an external JavaScript file.
The Razor template engine doesn't care what it's outputting and does not differentiate between <script> or other tags.
However, you need to encode your strings to prevent XSS attacks.

I prefer "<!--" "-->" like a "text>"
<script type="text/javascript">
//some javascript here
#foreach (var item in itens)
{
<!--
var title = #(item.name)
...
-->
</script>

One thing to add - I found that Razor syntax hilighter (and probably the compiler) interpret the position of the opening bracket differently:
<script type="text/javascript">
var somevar = new Array();
#foreach (var item in items)
{ // <---- placed on a separate line, NOT WORKING, HILIGHTS SYNTAX ERRORS
<text>
</text>
}
#foreach (var item in items) { // <---- placed on the same line, WORKING !!!
<text>
</text>
}
</script>

A simple and a good straight-forward example:
<script>
// This gets the username from the Razor engine and puts it
// in JavaScript to create a variable I can access from the
// client side.
//
// It's an odd workaraound, but it works.
#{
var outScript = "var razorUserName = " + "\"" + #User.Identity.Name + "\"";
}
#MvcHtmlString.Create(outScript);
</script>
This creates a script in your page at the location you place the code above which looks like the following:
<script>
// This gets the username from the Razor engine and puts it
// in JavaScript to create a variable I can access from
// client side.
//
// It's an odd workaraound, but it works.
var razorUserName = "daylight";
</script>
Now you have a global JavaScript variable named razorUserName which you can access and use on the client. The Razor engine has obviously extracted the value from #User.Identity.Name (server-side variable) and put it in the code it writes to your script tag.

The following solution seems more accurate to me than combine JavaScript with Razor. Check this out:
https://github.com/brooklynDev/NGon
You can add almost any complex data to ViewBag.Ngon and access it in JavaScript
In the controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var person = new Person { FirstName = "John", LastName = "Doe", Age = 30 };
ViewBag.NGon.Person = person;
return View();
}
}
In JavaScript:
<script type="text/javascript">
$(function () {
$("#button").click(function () {
var person = ngon.Person;
var div = $("#output");
div.html('');
div.append("FirstName: " + person.FirstName);
div.append(", LastName: " + person.LastName);
div.append(", Age: " + person.Age);
});
});
</script>
It's allows any plain old CLR objects (POCOs) that can be serialized using the default JavascriptSerializer.

There is also one more option than #: and <text></text>.
Using <script> block itself.
When you need to do large chunks of JavaScript depending on Razor code, you can do it like this:
#if(Utils.FeatureEnabled("Feature")) {
<script>
// If this feature is enabled
</script>
}
<script>
// Other JavaScript code
</script>
Pros of this manner is that it doesn't mix JavaScript and Razor too much, because mixing them a lot will cause readability issues eventually. Also large text blocks are not very readable either.

None of the previous solutions work correctly... I have tried all the ways, but it did not give me the expected result... At last I found that there are some errors in the code... And the full code is given below.
<script type="text/javascript">
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: new google.maps.LatLng(23.00, 90.00),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
#foreach (var item in Model)
{
<text>
var markerlatLng = new google.maps.LatLng(#(item.LATITUDE), #(item.LONGITUDE));
var title = '#(item.EMP_ID)';
var description = '#(item.TIME)';
var contentString = '<h3>' + "Employee " +title+ " was here at "+description+ '</h3>' + '<p>'+" "+ '</p>'
var infowindow = new google.maps.InfoWindow({
// content: contentString
});
var marker = new google.maps.Marker({
position: markerlatLng,
title: title,
map: map,
draggable: false,
content: contentString
});
google.maps.event.addListener(marker, 'click', (function (marker) {
return function () {
infowindow.setContent(marker.content);
infowindow.open(map, marker);
}
})(marker));
</text>
}
</script>

I finally found the solution (*.vbhtml):
function razorsyntax() {
/* Double */
#(MvcHtmlString.Create("var szam =" & mydoublevariable & ";"))
alert(szam);
/* String */
var str = '#stringvariable';
alert(str);
}

Those who, like me, don't have Json.Encode available can try this.
<script type="text/javascript">
var model = #Html.Raw(Json.Serialize(Model))
</script>

Related

MVC show session value in HTML [duplicate]

Is it possible or is there a workaround to use Razor syntax within JavaScript that is in a view (cshtml)?
I am trying to add markers to a Google map... For example, I tried this, but I'm getting a ton of compilation errors:
<script type="text/javascript">
// Some JavaScript code here to display map, etc.
// Now add markers
#foreach (var item in Model) {
var markerlatLng = new google.maps.LatLng(#(Model.Latitude), #(Model.Longitude));
var title = '#(Model.Title)';
var description = '#(Model.Description)';
var contentString = '<h3>' + title + '</h3>' + '<p>' + description + '</p>'
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var marker = new google.maps.Marker({
position: latLng,
title: title,
map: map,
draggable: false
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, marker);
});
}
</script>
Use the <text> pseudo-element, as described here, to force the Razor compiler back into content mode:
<script type="text/javascript">
// Some JavaScript code here to display map, etc.
// Now add markers
#foreach (var item in Model) {
<text>
var markerlatLng = new google.maps.LatLng(#(Model.Latitude), #(Model.Longitude));
var title = '#(Model.Title)';
var description = '#(Model.Description)';
var contentString = '<h3>' + title + '</h3>' + '<p>' + description + '</p>'
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var marker = new google.maps.Marker({
position: latLng,
title: title,
map: map,
draggable: false
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, marker);
});
</text>
}
</script>
Update:
Scott Guthrie recently posted about #: syntax in Razor, which is slightly less clunky than the <text> tag if you just have one or two lines of JavaScript code to add. The following approach would probably be preferable, because it reduces the size of the generated HTML. (You could even move the addMarker function to a static, cached JavaScript file to further reduce the size):
<script type="text/javascript">
// Some JavaScript code here to display map, etc.
...
// Declare addMarker function
function addMarker(latitude, longitude, title, description, map)
{
var latLng = new google.maps.LatLng(latitude, longitude);
var contentString = '<h3>' + title + '</h3>' + '<p>' + description + '</p>';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var marker = new google.maps.Marker({
position: latLng,
title: title,
map: map,
draggable: false
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, marker);
});
}
// Now add markers
#foreach (var item in Model) {
#:addMarker(#item.Latitude, #item.Longitude, '#item.Title', '#item.Description', map);
}
</script>
Updated the above code to make the call to addMarker more correct.
To clarify, the #: forces Razor back into text mode, even though addMarker call looks a lot like C# code. Razor then picks up the #item.Property syntax to say that it should directly output the contents of those properties.
Update 2
It's worth noting that View code really isn't a good place to put JavaScript code. JavaScript code should be placed in a static .js file, and then it should get the data that it needs either from an Ajax call or by scanning data- attributes from the HTML. Besides making it possible to cache your JavaScript code, this also avoids issues with encoding, since Razor is designed to encode for HTML, but not JavaScript.
View Code
#foreach(var item in Model)
{
<div data-marker="#Json.Encode(item)"></div>
}
JavaScript code
$('[data-marker]').each(function() {
var markerData = $(this).data('marker');
addMarker(markerData.Latitude, markerData.Longitude,
markerData.Description, markerData.Title);
});
I just wrote this helper function. Put it in App_Code/JS.cshtml:
#using System.Web.Script.Serialization
#helper Encode(object obj)
{
#(new HtmlString(new JavaScriptSerializer().Serialize(obj)));
}
Then in your example, you can do something like this:
var title = #JS.Encode(Model.Title);
Notice how I don't put quotes around it. If the title already contains quotes, it won't explode. Seems to handle dictionaries and anonymous objects nicely too!
You're trying to jam a square peg in a round hole.
Razor was intended as an HTML-generating template language. You may very well get it to generate JavaScript code, but it wasn't designed for that.
For instance: What if Model.Title contains an apostrophe? That would break your JavaScript code, and Razor won't escape it correctly by default.
It would probably be more appropriate to use a String generator in a helper function. There will likely be fewer unintended consequences of that approach.
What specific errors are you seeing?
Something like this could work better:
<script type="text/javascript">
//now add markers
#foreach (var item in Model) {
<text>
var markerlatLng = new google.maps.LatLng(#Model.Latitude, #Model.Longitude);
var title = '#(Model.Title)';
var description = '#(Model.Description)';
var contentString = '<h3>' + title + '</h3>' + '<p>' + description + '</p>'
</text>
}
</script>
Note that you need the magical <text> tag after the foreach to indicate that Razor should switch into markup mode.
That will work fine, as long as it's in a CSHTML page and not an external JavaScript file.
The Razor template engine doesn't care what it's outputting and does not differentiate between <script> or other tags.
However, you need to encode your strings to prevent XSS attacks.
I prefer "<!--" "-->" like a "text>"
<script type="text/javascript">
//some javascript here
#foreach (var item in itens)
{
<!--
var title = #(item.name)
...
-->
</script>
One thing to add - I found that Razor syntax hilighter (and probably the compiler) interpret the position of the opening bracket differently:
<script type="text/javascript">
var somevar = new Array();
#foreach (var item in items)
{ // <---- placed on a separate line, NOT WORKING, HILIGHTS SYNTAX ERRORS
<text>
</text>
}
#foreach (var item in items) { // <---- placed on the same line, WORKING !!!
<text>
</text>
}
</script>
A simple and a good straight-forward example:
<script>
// This gets the username from the Razor engine and puts it
// in JavaScript to create a variable I can access from the
// client side.
//
// It's an odd workaraound, but it works.
#{
var outScript = "var razorUserName = " + "\"" + #User.Identity.Name + "\"";
}
#MvcHtmlString.Create(outScript);
</script>
This creates a script in your page at the location you place the code above which looks like the following:
<script>
// This gets the username from the Razor engine and puts it
// in JavaScript to create a variable I can access from
// client side.
//
// It's an odd workaraound, but it works.
var razorUserName = "daylight";
</script>
Now you have a global JavaScript variable named razorUserName which you can access and use on the client. The Razor engine has obviously extracted the value from #User.Identity.Name (server-side variable) and put it in the code it writes to your script tag.
The following solution seems more accurate to me than combine JavaScript with Razor. Check this out:
https://github.com/brooklynDev/NGon
You can add almost any complex data to ViewBag.Ngon and access it in JavaScript
In the controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var person = new Person { FirstName = "John", LastName = "Doe", Age = 30 };
ViewBag.NGon.Person = person;
return View();
}
}
In JavaScript:
<script type="text/javascript">
$(function () {
$("#button").click(function () {
var person = ngon.Person;
var div = $("#output");
div.html('');
div.append("FirstName: " + person.FirstName);
div.append(", LastName: " + person.LastName);
div.append(", Age: " + person.Age);
});
});
</script>
It's allows any plain old CLR objects (POCOs) that can be serialized using the default JavascriptSerializer.
There is also one more option than #: and <text></text>.
Using <script> block itself.
When you need to do large chunks of JavaScript depending on Razor code, you can do it like this:
#if(Utils.FeatureEnabled("Feature")) {
<script>
// If this feature is enabled
</script>
}
<script>
// Other JavaScript code
</script>
Pros of this manner is that it doesn't mix JavaScript and Razor too much, because mixing them a lot will cause readability issues eventually. Also large text blocks are not very readable either.
None of the previous solutions work correctly... I have tried all the ways, but it did not give me the expected result... At last I found that there are some errors in the code... And the full code is given below.
<script type="text/javascript">
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: new google.maps.LatLng(23.00, 90.00),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
#foreach (var item in Model)
{
<text>
var markerlatLng = new google.maps.LatLng(#(item.LATITUDE), #(item.LONGITUDE));
var title = '#(item.EMP_ID)';
var description = '#(item.TIME)';
var contentString = '<h3>' + "Employee " +title+ " was here at "+description+ '</h3>' + '<p>'+" "+ '</p>'
var infowindow = new google.maps.InfoWindow({
// content: contentString
});
var marker = new google.maps.Marker({
position: markerlatLng,
title: title,
map: map,
draggable: false,
content: contentString
});
google.maps.event.addListener(marker, 'click', (function (marker) {
return function () {
infowindow.setContent(marker.content);
infowindow.open(map, marker);
}
})(marker));
</text>
}
</script>
I finally found the solution (*.vbhtml):
function razorsyntax() {
/* Double */
#(MvcHtmlString.Create("var szam =" & mydoublevariable & ";"))
alert(szam);
/* String */
var str = '#stringvariable';
alert(str);
}
Those who, like me, don't have Json.Encode available can try this.
<script type="text/javascript">
var model = #Html.Raw(Json.Serialize(Model))
</script>

how can to convert array from jsp to javascript

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.

Getting data from python with JS and plotting it, with Django backend and Google maps api

I've got a project with a django backend that I'm using for logins, and using the mysql DB through my local host. I currently have my gettweets.py script returning an array of coordinates and have a JS script that is supposed to get these results and plot it to google maps api. My JS script fails at $.get. However, if i go to 127.0.0.1/gettweets?tag=%23Pizza, I get something like this:
["-87.634643, 24.396308", "-80.321683, 25.70904", "-79.639319, 43.403221", "-95.774704, 35.995476", "-84.820309, 38.403186", "-120.482386, 34.875868", "-121.385009, 38.716061", "-111.530974, 40.619883"]
I've been trying to get JS to make the call on the button click because I don't think I can get the results to it through Django. Why is it getting stuck?
Here is the JS inside of index.html
<script type="text/javascript">
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 5,
center: new google.maps.LatLng(49.13,-100.32),
mapTypeId: 'roadmap'
});
}
// Loop through the results array and place a marker for each
// set of coordinates.
$('#searchButton').click(function(){
$.get('../../gettweets?tag=%23Trump', function(data, status) {
alert(status);
var data = JSON.parse(this.response);
alert('data');
data.forEach(function(point) {
var coordString = point['coord'];
var x = coordString.substring(0,coordString.indexOf(','));
var y = coordString.substring(coordString.indexOf(',')+1,coordString.length);
console.log(x);
console.log(y);
var coords = results.features[i].geometry.coordinates;
var latLng = new google.maps.LatLng(x,y);
var marker = new google.maps.Marker({
position: latLng,
map: map
});
});
window.myLine.update();
});
//xmlhttp = new XMLHttpRequest();
//var tag = document.getElementById('tagSearch').value;
//if (this.readyState === 4 && this.status === 200) {
//}
//xmlhttp.open("GET","./getTweets.php?tag='" + tag + "'");
//xmlhttp.send();
});
</script>
Button/form:
<form>
<input id="tagSearch" type="text" name="tag" maxlength="100" required placeholder="{{ tag }}" />
<button class="btn waves-effect red" type="submit" id="searchButton" name="search">Submit
<i class="material-icons right">send</i>
</button>
</form>
gettweets.py - NOTE I've got this in my views, as well as a separate file. I'm not sure which one I need with the JS
def tweets(request):
tag = request.GET['tag']
print(tag)
x = models.Tweet.objects.filter(tag=tag)
print(x)
coords = []
for i in x:
coords.append(i.coord)
print(coords)
return JsonResponse(coords, safe=False)
Finally, urls
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^gettweets$', views.tweets, name='gettweets'),
]
You're calling $.get() incorrectly. Its signature is $.get(url[, data][, success][, dataType]), from the docs.
I would prefer using a settings object like so:
$.get({
url: '../../gettweets?tag=%23Hillary',
success: function (data, status) {
...
}
});

Google maps v3 api, center map based on location

I'm trying to center my map based on the location of the visitor, but somehow it doesn't work.
I have a PHP variable containing the country code of my visitor, which works fine when i check the source code in my browser. It looks like this;
<head>
...
<script type="text/javascript">
var lang = <?php echo $lang; ?>;
</script>
<script type="text/javascript" src="js/script.js"></script>
</head>
<body onload="initialize()">
...
My script.js contains these lines;
function initialize() {
if (lang == NL) {
var centerlat = 52.150892;
var centerlng = 5.534668;
var zoomlvl = 7;
}
else {
var centerlat = 52.367896;
var centerlng = 5.219407;
var zoomlvl = 13;
}
var myLatlng = new google.maps.LatLng(centerlat,centerlng);
var myOptions = {
zoom: zoomlvl,
center: myLatlng,
...
}
map = new google.maps.Map(document.getElementById("kaart"), myOptions);
When i load the page containing the map it just doesnt appear. In the source code i can see the PHP variable displaying correctly.
Firebug says lang is undefined. Any idea whats going on here?
//edit: I have another variable done in the same way which works fine. But its outside the initialize function.
Solved: Forgot quotes ^^
Try surround NL with "".
As an aside have you looked into HTML 5 geolocation? Its relatively simple to implement and will give you a much more accurate location.
Take a look here: https://developers.google.com/maps/documentation/javascript/examples/map-geolocation and here:http://www.w3schools.com/html/html5_geolocation.asp
Any idea whats going on here?
sorry, I don't have the rep to 'comment'
Is NL a string variable or a value (should it be "NL" ?)

Google Maps Info Window Not Allowing Mulitple Django Variables

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.

Categories

Resources