how can to convert array from jsp to javascript - 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.

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>

Add markers from rails database

I'm creating a map with Google Maps API to reference restaurants based on their location. Each restaurant in my database (sqlite3) has a title, a description and two coordinates (latitude, longitude). I can successfully create entries in my database but struggle to find a solution to call in JS each restaurant's coordinates from the database.
Different solutions have been proposed on Stackoverflow of which this one, another and a last one, but none of the answers my question as I'm working exclusively with JS and Ruby (on rails).
Would you have suggestions ?
First, you need to read this example from Goolge Maps Javascript API and play with this code:
<!DOCTYPE html>
<html>
<head>
<style>
#map {
height: 400px;
width: 100%;
}
</style>
</head>
<body>
<h3>My Google Maps Demo</h3>
<div id="map"></div>
<script>
function initMap() {
var uluru = {lat: -25.363, lng: 131.044};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: uluru
});
var marker = new google.maps.Marker({
position: uluru,
map: map
});
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_GOOGLE_MAPS_API_KEY&callback=initMap">
</script>
</body>
</html>
As you can see here, you need to
create your own GOOGLE_MAPS_API_KEY here
create div with id;
connect Google's javascript, which when will load, will load also js-function initMap()
define initMap-function with map and marker settings.
Next step: getting data from database and passing to JavaScript.
I used gon gem for transferring data from backend to frontend:
in controller:
# app/controllers/application_controller.rb
def root
gon.locations = Location.all
end
in layout:
<!-- app/views/layouts/application.html.erb -->
<head>
<%= include_gon %>
<!-- ... -->
</head>
in view:
<!-- app/views/application/root.html.erb -->
<script>
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: { lat: gon.locations[0].lat, lng: gon.locations[0].lng }
});
for(var i = 0; i < gon.locations.length; i++){
new google.maps.Marker({
position: { lat: gon.locations[i].lat, lng: gon.locations[i].lng },
title: gon.locations[i].name,
map: map
});
}
}
<script>
But, if you don't want use gon gem for passing data from backend to frontend, you can do this by plain rails:
# app/controllers/application_controller.rb
def root
#json_data = {
locations: {
# ...
},
# ...
}.to_json
end
<!-- views/posts/edit.html.erb -->
<script>
var json_data = JSON.parse('<%= raw(escape_javascript(#json_data)) %>');
</script>
Also, I created rails demo application, you can play with it.
This commit doing all job, to write 'ICE' word by markers on Antarctica.
See these files for more details:
app/controllers/application_controller.rb
app/views/application/root.html.erb
app/views/layouts/application.html.erb
I used this online service to create coordinates for 'ICE' word
One way you could try is by using json. For example in the controller.
class RestaurantsController < ApplicationController
def show
#restaurant = Restaurant.find(params[:id])
respond_to do |format|
format.html
format.json {render json: #restaurant}
end
end
end
Then the restaurant can be accessed in javascript (I'll use JQuery)
$.getJSON("show_page_url.json", function(data){
//data will contain the #restaurant object
//so data.latitute should return the value
}
Maybe this helps. I used it for a simple project I did recently, but maybe there are better methods.
To make variables in your rails app accessible for js code, you need to save these values in rendered html and later your js code can take values from html. You can use gon so you don't have to write the solution yourself. Here are the steps to get it working:
install the gem 'gon'.
add <%= Gon::Base.render_data %> to your layout.
set variable: gon.push(restaurants: restaurants).
in your js code, read data and pass it to your map.

Issue calling Google API in Liferay

I have problem with the execution of the javascript inside a jsp page.
I have the following page which works perfectly if I call it from my filesystem, that is, I write in the address bar C:\...\heatmap2.jsp.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<title>Energy Heatmap </title>
<style>
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map-canvas { height: 80% }
h1 { position:absolute; }
</style>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?libraries=visualization&sensor=true?key=AIzaSyCzoFE1ddY9Ofv0jjOvA3yYdgzV4JvCNl4"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type='text/javascript'>
/*Array in cui saranno inseriti i punti da visualizzare nella mappa
*/
var heatMapData = new Array();
function loadHeatMapData(callback)
{
$.ajax
({
type: "GET",
url: "http://localhost:8080/EnergyManagement-portlet/api/secure/jsonws/sample/get-samples-time-by-name?energyName=EnAssGS",
dataType: "jsonp",
crossDomain: true,
cache: false,
success: function(jsonData)
{
for (var i = 0; i < jsonData.length; i++)
{
var decodedData = JSON.parse(jsonData[i]);
var lng = decodedData["_longitude"];
var lat = decodedData["_latitude"];
var energyIntensity = decodedData["_value"];
heatMapData.push({location: new google.maps.LatLng(lat, lng), weight: energyIntensity});
}
return callback(heatMapData);
}
})
}
function drawHeatMap()
{
// map center
var myLatlng = new google.maps.LatLng(40.8333333, 14.25);
// map options,
var myOptions = {
zoom: 5,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.TERRAIN
};
// standard map
map = new google.maps.Map(document.getElementById("map-canvas"), myOptions);
var heatMap = new google.maps.visualization.HeatmapLayer({
data: heatMapData,
dissipating: false
});
heatMap.setMap(map);
/*
Questi punti dovrebbero prevenire da un file.
*/
var vehiclePath = [
new google.maps.LatLng(40.85235, 14.26813),
new google.maps.LatLng(40.85236, 14.26822),
new google.maps.LatLng(40.85236, 14.26822),
new google.maps.LatLng(40.85236, 14.26816),
new google.maps.LatLng(40.85258, 14.26811),
new google.maps.LatLng(40.85364, 14.26793),
new google.maps.LatLng(40.85414, 14.26778),
new google.maps.LatLng(40.8554, 14.2676),
new google.maps.LatLng(40.8579, 14.27286),
new google.maps.LatLng(40.85821, 14.27291),
new google.maps.LatLng(40.8584, 14.27302),
new google.maps.LatLng(40.85859, 14.27325),
new google.maps.LatLng(40.8587, 14.27421),
new google.maps.LatLng(40.85865, 14.27433),
new google.maps.LatLng(40.85866, 14.27446),
new google.maps.LatLng(40.86656, 14.291),
new google.maps.LatLng(40.86653, 14.29102)
];
var path = new google.maps.Polyline({
path: vehiclePath,
geodesic: true,
strokeColor: '#FF0000',
strokeOpacity: 1.0,
strokeWeight: 2
});
path.setMap(map);
}
/*Callback*/
loadHeatMapData(drawHeatMap)
</script>
</head>
<body>
<div id="map-canvas"></div>
<p id="demo"></p>
</body>
</html>
Unfortunately, when I try to call it inside my Liferay portal, I can't see any javascript running.
The following code creates a heatmap (with the Google API), the points are obtained with an asynchronous call to the webserver
via SOAP (it's a method available from an entity of my project).
I also tried to add the tag
<header-portlet-javascript>
"https://maps.googleapis.com/maps/api/js?libraries=visualization sensor=true?key=AIzaSyCzoFE1ddY9Ofv0jjOvA3yYdgzV4JvCNl4"
</header-portlet-javascript>
with no sucess.
Any help is appreciated.
Without being able to test your code currently, I see two issues with it:
Your JSP contains <html>, <head> and <body> elements etc. These are not allowed in portlets and won't work the same way as in a standalone page
Further, your contains superfluous quotes.
<header-portlet-javascript>
"https://maps.googleapis.com/and/so/on"
</header-portlet-javascript>
I'd expect this to literally be added to the page, resulting in double quotes
<script type="text/javascript" src=""https://maps.googleapis.com/and/so/on""></script>
Obviously, this doesn't work. Please check what ends up on the generated page when you add your portlet to it. Also, remove the extra quotes and try again.
Deae Olaf,
I applied your advice to my code.
With the support of the internet explorer debbuger, I found out that the code inside the drawHeatmpaData is like being commented (please, look at the picture)
.
In order to prevent from you code being commented, I found that we cannot use // to comment,
because all the text even the code is treated as comment.
I replace all // with /**/ but it still does not work.

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" ?)

Using Razor within 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>

Categories

Resources