Setting marker title in Google Maps API 3 using jQuery - javascript

I am having a couple of problems with Google Maps and jQuery. Wondered if anyone can help with the smaller of the two problems and hopefully it will help me to fixing the bigger one.
I am using the below code to populate a google map, basically it uses generated HTML to populate the maps in the form:
<div class="item mapSearch" id="map52.48228_-1.9026:800">
<div class="box-prise"><p>(0.62km away)</p><div class="btn-book-now">
BOOK NOW
</div>
</div><img src="http://media.toptable.com/images/thumb/13152.jpg" alt="Metro Bar and Grill" width="60" height="60" />
<div class="info">
<h2>Metro Bar and Grill</h2>
<p class="address">73 Cornwall Street, Birmingham, B3 2DF</p><strong class="proposal">2 courses £14.50</strong>
<dl>
<dt>Diner Rating: </dt>
<dd>7.8</dd>
</dl></div></div>
<div class="item mapSearch" id="map52.4754_-1.8999:3195">
<div class="box-prise"><p>(0.97km away)</p><div class="btn-book-now">
BOOK NOW
</div>
</div><img src="http://media.toptable.com/images/thumb/34998.jpg" alt="Filini Restaurant - Birmingham" width="60" height="60" />
<div class="info">
<h2>Filini Restaurant - Birmingham</h2>
<p class="address">Radisson Blu Hotel, 12 Holloway Circus, Queensway, Birmingham, B1 1BT</p><strong class="proposal">2 for 1: main courses </strong>
<dl>
<dt>Diner Rating: </dt>
<dd>7.8</dd>
</dl></div></div>
<div class="item mapSearch" id="map52.47775_-1.90619:10657">
<div class="box-prise"><p>(1.05km away)</p><div class="btn-book-now">
BOOK NOW
</div>
</div><img src="http://media.toptable.com/images/thumb/34963.jpg" alt="B1 " width="60" height="60" />
<div class="info">
<h2>B1 </h2>
<p class="address">Central Square , Birmingham, B1 1HH</p><strong class="proposal">25% off food</strong>
<dl>
<dt>Diner Rating: </dt>
<dd>7.9</dd>
</dl></div></div>
The JavaScript loops though all the divs with class mapSearch and uses this to plot markers using the div ID to get the lat/lon and ID of the venue:
var locations = $(".mapSearch");
for (var i=0;i<locations.length;i++) {
var id = locations[i].id;
if (id) {
var jsLonLat = id.substring(3).split(":")[0];
var jsId = id.substring(3).split(":")[1];
var jsLat = jsLonLat.split("_")[0];
var jsLon = jsLonLat.split("_")[1];
var jsName = $("h2").text();
var jsAddress = $("p.address").text();
var latlng = new google.maps.LatLng(jsLat,jsLon);
var marker = new google.maps.Marker({
position: latlng,
map:map,
icon: greenRestaurantImage,
title: jsName
});
google.maps.event.addListener(marker, 'click', function() {
//Check to see if info window already exists
if (!infowindow) {
//if doesn't exist then create a empty InfoWindow object
infowindow = new google.maps.InfoWindow();
}
//Set the content of InfoWindow
infowindow.setContent(jsAddress);
//Tie the InfoWindow to the market
infowindow.open(map,marker);
});
bounds.extend(latlng);
map.fitBounds(bounds);
}
}
The markers all plot OK on the map, however I am having probs with the infoWindow bit. I want to display info about each venue when clicked, however using my code above it just puts all info in one box when clicked, not individually. Hoping it is a simple fix!
Hoping once I fix this I can work out a way to get the info window displaying if I hover over the div in the html.

As far as my jQuery knowledge is concerned, what you are seeing is right; $("h2").text() will concatenate inner text of all H2s into one string and return it. You better try something along these lines:
// inside your if (id) clause
var jsName = $("h2", locations[i]).text();
var jsAddress = $("p.address", locations[i]).text();
You can .each() over $(".mapSearch") if you want to simplify your code.

$(document).ready(function() {
//<![CDATA[
if (GBrowserIsCompatible()) {
function createMarker(point, html) {
var marker = new GMarker(point);
GEvent.addListener(marker, "click", function() {
marker.openInfoWindowHtml(html);
});
return marker;
}
// Display the map, with some controls and set the initial location
var map = new GMap2(document.getElementById("map"));
map.enableContinuousZoom();
//map.enableScrollWheelZoom();
map.enablePinchToZoom(); // ForiPhone users
map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(51.53177, -0.08001), 16);
var icon = new GIcon();
var point = new GLatLng(51.53177, -0.08001);
var marker = createMarker(point, '<div style="width:240px" id="mapsball"></div>');
map.addOverlay(marker, icon);
}
// display a warning if the browser was not compatible
else {
alert("Sorry, Google Maps is not compatible with your browser");
}
//]]>
});

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>

Generate PDF from HTML with Map (exactly a screenshot)

Hi I have this html with some content and a map, using Leaflet api for map rendering (jsfiddle) This whole content is part of a modal panel which open on a button click after user input some data. I want to export all content into a pdf with some client side solution.
I have tried jspdf like but it does not works. tried combination of canvastohtml and jspdf like but could not able to make it work either. Point to mentione here is my content contains map which export jspdf doesn't support
Anyone knows a solution, please share. I have included the code below
PS: Using phamtomjs screenshot utilities is not an option
<script src="https://npmcdn.com/leaflet#1.0.0-rc.3/dist/leaflet.js"></script>
<link href="https://npmcdn.com/leaflet#1.0.0-rc.3/dist/leaflet.css" rel="stylesheet" />
<body>
<script>
function createMap(mapPlaceHolderId) {
var OSM_MAP_TILE_SERVER_URL = 'http://{s}.tile.openstreetmap.se/hydda/full/{z}/{x}/{y}.png';
var DEFAULT_MAP_CENTER = L.latLng(25.296854389343867, 51.48811340332031);
var DEFAULT_MAP_ZOOM = 12;
var MAP_ZOOM_MAX = 19;
var MAP_ZOOM_SEARCH = 17;
var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
var osmAttrib = 'Map data © OpenStreetMap contributors';
var osm = new L.TileLayer(osmUrl, {
minZoom: 8,
maxZoom: 12,
attribution: osmAttrib
});
var map = L.map(mapPlaceHolderId).setView([51.505, -0.09], 13);
map.addLayer(osm);
return map;
}
</script>
<div id="vrSubReportContainer">
<div class="mapPopupTableContainer">
<div class="mapPopupTableData"><b>Plate Number:</b> 009-001GL-297286, <b>Driver Name:</b> Unknown driver
<br><b>Latitude,Longitude</b>: 25.215238,51.605439</div>
</div>
<div id="mapContainer" class="map-container">
<div class="map" id="fd_map_canvas"></div>
</div>
</div>
<script>
(function() {
createMap('fd_map_canvas');
})();
</script>
</body>

Bias location returns on Google Places API autocomplete

I am using the Google places API to autocomplete street address searches. I want to bias the results to a 50 mile radius around a specific longitude and latitude (this is a fixed location, it doesn't depend on the user). Currently, it autocompletes addresses, but it doesn't bias them based on location (other than doing within the U.S.). Specifically, I want to bias a 300 mile radius around latitude: 34.159947, longitude: -118.257017.
<script src="https://maps.googleapis.com/maps/api/js?sensor=false&libraries=places"></script>
...
<input id="address-search" type="text" value="" name="subject">
$(document).ready(function() {
var input = document.getElementById('address-input');
var options = {componentRestrictions: {country: 'us'} };
new google.maps.places.Autocomplete(input, options);
google.maps.event.addDomListener(window, 'load', initialize);
});
       
You can't give it a radius, but you can give it rectangular bounds
var defaultBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(-33.8902, 151.1759),
new google.maps.LatLng(-33.8474, 151.2631)
);
var options = {bounds: defaultBounds };
See the Places Autocomplete documentation

OpenWeatherMap - map is showing only moscow

I am trying to get the weather information for a certian cities(cities are coming dynamically) and i came across this map api which is very easy to integrate. but once i tried it, it is showing only moscow even if i gave the lat and lon of another city, say, munich.
this is the code:
<html>
<head>
<script src="http://openlayers.org/api/OpenLayers.js"></script>
<script src="http://openweathermap.org/js/OWM.OpenLayers.1.3.4.js" ></script>
</head>
<body onload="init()">
<div id="basicMap"></div>
</body>
<script type="text/javascript">
function init() {
//Center of map
var lat = 48.24806; // <--- some dynamic location
var lon = 11.90166; //<--- some dynamic location
var lonlat = new OpenLayers.LonLat(lon, lat);
var map = new OpenLayers.Map("basicMap");
// Create overlays
// OSM
var mapnik = new OpenLayers.Layer.OSM();
// Stations
var stations = new OpenLayers.Layer.Vector.OWMStations("Stations");
// Current weather
var city = new OpenLayers.Layer.Vector.OWMWeather("Weather");
//Addind maps
map.addLayers([mapnik, stations, city]);
map.setCenter( lonlat, 10 );
}
</script>
</html>
i just want to save some loading energy for my server and do this weather issue in frontend with js. if this would work, it would be wonderful, please help if you can. why am i stuck to moscow here even if give different lat and lons. this is the link for api:
http://openweathermap.org/tutorial/openlayers
Apparently you need to set the Projection for it to work correctly.
Here is an example of the code centering at London:
<html>
<head>
<script src="http://openweathermap.org/js/OWM.OpenLayers.1.3.4.js" ></script>
</head>
<body onload="init()">
<div id="basicMap"></div>
</body>
<script type="text/javascript">
function init() {
//Center of map
var lat = 51.5112139; // <--- some dynamic location
var lon = -0.1198244; //<--- some dynamic location
var map = new OpenLayers.Map("basicMap");
var fromProjection = new OpenLayers.Projection("EPSG:4326"); // Transform from WGS 1984
var toProjection = new OpenLayers.Projection("EPSG:900913"); // to Spherical Mercator Projection
var position = new OpenLayers.LonLat(lon, lat).transform( fromProjection, toProjection);
// Create overlays
// OSM
var mapnik = new OpenLayers.Layer.OSM();
// Stations
var stations = new OpenLayers.Layer.Vector.OWMStations("Stations");
// Current weather
var city = new OpenLayers.Layer.Vector.OWMWeather("Weather");
//Addind maps
map.addLayers([mapnik, stations, city]);
map.setCenter( position, 5 );
}
</script>
</html>
To get the Longitude and Latitude of your place, you can use this URL:
http://www.mapcoordinates.net/en
Hope this helps

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