Mix Razor and JavaScript Code

Mix Razor and Javascript code

Use <text>:

<script type="text/javascript">

var data = [];

@foreach (var r in Model.rows)
{
<text>
data.push([ @r.UnixTime * 1000, @r.Value ]);
</text>
}
</script>

ASP.NET MVC mix Razor and JavaScript

You can not pass a JavaScript value to Razor. The reason is when in the page page life cycle the code is executed:

  • Razor code is executed on the server before the page is returned to the client
  • JS code is executed on the client after the page was returned

But you can solve your concrete problem by creating the URL initially with a placeholder, then replace it in the JS code.

<script type="text/javascript">

var urlPattern = '@Url.Action("__ACTION_NAME_TO_BE_REPLACED__", "Doctors", new { id = Model.Id })';

function GetTabPane(val) {
var url = urlPattern.replace('__ACTION_NAME_TO_BE_REPLACED__', val);
$('#'+val).load(url, function () { $('#'+val).tab-pane('show'); });
}
</script>

How can I mix Razor syntax with JavaScript inside JavaScript file?

Based on the question, it seems that you want to contract a link dynamically at client-side with value from JSVar.

If so, you could just append JSVar to URL. For example,

<input id="txtValue" type="text" value="Stackoverflow" />
<a id="myId">Navigate to Page</a>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
$("#myId").click(function () {
var JSVar = $("#txtValue").val();
location.href = "@Url.Action("About", "Home")/id=" + JSVar;
});
})
</script>

Mixing Razor with Javascript

You are mixing 2 completely different technologies.

Razor renders server-side

So your function would be just

function beginSubmit() {

}
//notice empty line, cuz Console.WriteLine("DELETING....."); doesn't return anything

Because c# Console.WriteLine("DELETING....."); doesn't return anything, it just logs DELETING..... when razor engine compiles cshtml file.

JavaScript renders client-side

So you are asking browser to do something for you, call alert, console.log(this is different from c# log) something, or any other thing that browsers allows you to do, not your server.

And you cannot call server-side code from javascript, unless you have (REST)API for that call. Even in this case, you need ajax for calling it from client

How to correctly combine javascript with razor syntax

Given your concrete example, I would start by reducing the number of <text> blocks needed by instead just wrapping the shorter C# bits with @{ … }. This improves readability & lessens confusion. For example:

var listPuntos =[];
function onSelect(e) {
var dataItem = this.dataSource.view()[e.item.index()];
@{ var proveedorID = 0; }
proveedorID = dataItem.ProveedorID;
@{ var list = new UnitOfWork().PuntosVentaProveedorRepository.Get().Where(x => x.ProveedorID == proveedorID); }
proveedorID = 0;
listPuntos = @Json.Encode(list);
var displayText;
$.each(listPuntos, function (key, value) {
if (displayText == undefined)
displayText = value.Nombre + ', ';
else
displayText = displayText + value.Nombre + ', ';
});
document.getElementById("puntos").value = displayText.slice(0,-2);
}

Next, to inject a C# value into JavaScript code being emitted by the server, you need to encode the value in JavaScript. The best way to do this is to convert it into JSON. This is done above using Json.Encode. In particular, the line reading:

        listPuntos = @Json.Encode(list);

I've used Json.Encode but of course you are free to use whatever JSON library du jour that fits your project.

How not works mix code JS in a Razor View

Razor interprets @ as razor syntax. You should escape your code with @@

@@:data2.push({
@@:label: "@data.Results[i].Timestamp",
@@:value: "@data.Results[i].Value",
});

Using Razor within JavaScript

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);
});


Related Topics



Leave a reply



Submit