1

I'm working on an MVC project in which jsrender is used. This is my first time working with jsrender (in fact I'm fairly new at javascript and C# too lol) and I've been struggling with one particular problem for a full day now.

I have the following javascript

 $.post('@Url.Action("GetDocs","Place", new { placeID = Model.PlaceId})').done(
        function (data) {
            var template = $.templates("#doc-tmpl");
            var htmlOut = template.render(data.documents);
            $("#documentListContainer").append(htmlOut);
            $(".docCount").html(data.count);
        });

This gets all the data I need for the template below, but I need to create an Url.Action() using a piece of that data.

<script id="doc-tmpl" type="text/x-jsrender">
<div class="col-md-4">
        <h5>{{:Name}}{{:test}}</h5>
        <p id="DocId" class="hidden"><br />{{:DocId}}</p>
        <img src="data:image;base64,{{:FrontCoverImg}}" width="140" height="230" />
    <a href="@Url.Action("DisplayPDF","Place", new { DocId = "{{:DocId}}" })">Link</a>
</div>

I need to supply the docId from the data in the routeValues of the @Url.Action("DisplayPDF","Place", new { docId = "{{:docId}}" }). Obviously this isn't working in it's current state.

I've looked at the jsrender documentation and other Q&A to do with jsrender and MVC but I'm having trouble wrapping my head around the way it works.

one thing I have thought of is to create the @Url.Action() within the javascript and use a tag to pop it in the template, however I haven't been able to figure out how to add to the data from the $.post in order to make a tag available for it.

Edit: What I mean from the above paragraph is, the data returned by the javascript/getDocs post is something like:

  documents": [
    {
        "DocId": "86f86a32-5005-456c-8dd1-c023a66dd794",
        "Name": "How to...",
        "FrontCoverImg": "Base64String(docImg)"
    },

    {
        "DocId": "d29f8afc-3191-47f1-9b88-1de08582ba27",
        "Name": "A Document",
        "FrontCoverImg": "Base64String(docImg)"
    }
 ],
"count": ​2
 }

Which is then set up to fill in the template. I'm hoping there is a way to add the @Url.Action() statement to those key/value pairs, something like:

"viewdoc" : '@@Url.Action("DisplayPDF", "Place", new {DocId = ' + DocId + ', @@class = "btn btn-default" })';

(not sure if the syntax is quite right there) so I could then put {{:viewdoc}} into the template.

Am I at least on the right track? lol

Ego Placebo
  • 157
  • 2
  • 14

2 Answers2

0

try this ,

 var id = $('#docId').val();
 var link = '@URL.Action("download file", "download", new { id = "-1" })';
 link = link.replace("-1", id);

Source : How to access javascript variable within @URL.Action()

Community
  • 1
  • 1
REDEVI_
  • 684
  • 8
  • 18
  • I saw that Q&A but am unsure how to apply it in my situation.. maybe I just need sleep lol.. how do I get the link into the html part of the template? – Ego Placebo Mar 24 '16 at 06:12
0

Ok so after leaving it alone for a week then much experimentation and googling, I found my solution.

I've created the link in the controller, where the JSON data is set. I had to request the leftmost part of the URL and hardcode the controller/action part of the url, otherwise it crammed the new url on the end of the current page url. So the solution is as follows:

The Controller:

foreach (Doc document in docs)
            {
                DocJson dj = new DocJson();
                dj.DocId = document.DocId;
                dj.Name = document.Comments;
                //get base Url
                var request = HttpContext.Request.Url.GetLeftPart(UriPartial.Authority);
                dj.docLink = request + "/Place/DisplayPDF?DocId=" + document.DocId;
                //get image bytes
                var docImg = document.FrontCoverImg;
                dj.FrontCoverImg = Convert.ToBase64String(docImg);

                documents.Add(dj);
            }
return Json(new { documents = documents, count = documents.Count() }, JsonRequestBehavior.AllowGet);

(in the view) The Javascript getting the data:

//getDocs
    $.post('@Url.Action("GetDocs","Place", new { placeID = Model.PlaceId})').done(
        function (data) {
            console.log(data);
            var template = $.templates("#doc-tmpl");
            var htmlOut = template.render(data.documents);
            $("#documentListContainer").append(htmlOut);
            $(".docCount").html(data.count);
        });

(in the view) And the template itself:

@* Document jsrender template *@
<script id="doc-tmpl" type="text/x-jsrender">
<div class="col-md-4">
    <a href="{{:docLink}}" target="_blank">
        <h5>{{:Name}}</h5>
        <p id="DocId" class="hidden"><br />{{:DocId}}</p>
        <img src="data:image;base64,{{:FrontCoverImg}}" width="140" height="230" />
    </a>
</div>
</script>
Ego Placebo
  • 157
  • 2
  • 14