0

I have a dynamic table generated in JS which appends a button (and image) in one of the columns of the table:

var btn = $("<button/>", { class: "btn btn-default dropdown-toggle options_btn_custom", }).prepend('<img src="@Url.Content("~/Content/img/Settings.png")" />');

The issue is the Razor image URL within the HTML is rendered incorrectly:

enter image description here

The URL of the image has to be relative (hence the Razor)...

I know its possible to embed Razor within JS directly, but is there a way for it to work also within embedded HTML, or is it too far a long shot?

4
  • Is the js in an external file? (razor is not parsed in external files) Commented Mar 23, 2017 at 4:14
  • oh really? far out, thats annoying... well I think I found a solution, which I'll post in a bit, but yeah I had to put the Razor in the view in the end... Commented Mar 23, 2017 at 4:30
  • You could just create a global var in the view - var img = '@Url.Content(...); and access from the external file(or if you handling an event of an element, add a data-* attribute) Commented Mar 23, 2017 at 4:35
  • yeah I did something similar, check out my answer. Too bad I couldn't keep it all within the external JS file though - that's what I was hoping for. Thanks for the help though, they were some cool pointers Commented Mar 23, 2017 at 4:43

4 Answers 4

1

Quick fix, didn't know I had to keep the Razor within the view... so in my view head I've got:

    <script>
    var baseurl = "@Url.Content("~/")";
    </script>

And then the JS within the external file:

 var btn = $("<button/>", { class: "btn btn-default dropdown-toggle options_btn_custom" }).prepend('<img src="' + baseurl + '/Content/img/Settings.png"/>');
Sign up to request clarification or add additional context in comments.

Comments

0

you can set the value to a global js var and then you can use it in external js file

i.e

> var clientVar = null;
> 
> clientVar = '@Url.Content("~/Content/img/Settings.png")';

in external js file just use the clienVar. it should work

Comments

0

The fact is Razor is not configured to process JS files by default. The easiest solution will be to inject your values in cshtml file in the script tag before your JS file reference:

<script>
    window.data = {
        settingsImageUrl: '@Url.Content("~/Content/img/Settings.png")';
    };
<script>
<script src="your-script.js" />

And then feel free to use data.settingsImageUrl in your-script.js:

var btn = $("<button/>", {
    class: "btn btn-default dropdown-toggle options_btn_custom", 
}).prepend('<img src=" + data.settingsImageUrl + " />');

Alternative solution

Another possible solution is to build the script file with all the values required for your script on the fly. To make this you can setup a special route pointing to an action. In this action you will build your values as a string with JS object definition and return it as a text/javascript content. That will work fine with caching action filter. Then you just point to this route in a script tag injected before your target script.

Comments

0

You could render a data attribute to a container holding the objects you will generate dynamically. Doing so prevents the usage of global javascript variables.

<div id="myAwesomeFunctionalityContainer" data-image-url="@Url.Content("~/Content/img/")"></div>

Then from your javascript file, read the data attribute "image-url"

(function () {
   "use strict";

   $(window).load(function () {
      var $container = $("#myAwesomeFunctionalityContainer");
      var imgPath = $container.data("image-url");
      var classDef = "btn btn-default dropdown-toggle options_btn_custom";
      var btn = $("<button/>", {class: classDef}).prepend('<img src="' + imgPath + '/Setting.png" />');
   });
}());

The benefits are:

  • no global variables which will cause headaches if you code libray grows.
  • the payload is known to the container using data attributes. This works well for a limited amount of data. If you need more data/complex object from razor then you could render a model to a json string object. Afterwards convert the string object back to a json object using jquery.parseJSON

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.