9

Let me preface this question with the fact that I am very new to MVC.

I have an instance where I am rendering a devexpress grid in a partial view.

@Html.Partial("MyGridPartial", Model)

I need to kick off a javascript function at the moment that the model has been populated via this partial view render. I attempted to do this via this. :

settings.ClientSideEvents.EndCallback

I can get to this point, but at that time I do not have the model itself populated so it does no good. I was wondering if anyone is aware of a generic way of kicking/attaching to a partial view render in order to jump into some clientside javascript code.

Bill Blankenship
  • 3,167
  • 5
  • 41
  • 71
  • You mean "run JavaScript on server when half of he HTML is rendered?" – Alexei Levenkov Jan 22 '13 at 23:42
  • Basically, I need access to the data (model) provided by the partial view on the clientside after the partial view has rendered. I have tried numerous ways to kick off a javascript function so that I can run some clientside code that would perform manipulations against the model, but every attempt that I have made has been severely unsuccessful. – Bill Blankenship Jan 23 '13 at 00:02

2 Answers2

8

If it's a PartialView you're rendering in a View on the serverthen Dave's method would work best. Simply wire-up your code to the DOM ready event.

$(document).ready(function(){
    //Javascript logic to fire goes here
});

or if you prever the shorthand version...

$(function(){
    //Javascript logic to fire goes here
});

If you're rendering a partial view that is being loaded via Ajax then the same method will work. jQuery will run javascript in the html passed back to the client via Ajax once it's attached to the DOM if I recall correctly (feel free to test this I'm just going by memory about it firing once attached to the DOM, but I believe this is a feature of the load() method), assuming the javascript you want to run is in the response. If it's in the parent page sending the Ajax request then you're best bet is to hook it up to the complete event. (I'm populating the parameter on the client side here)

$("#wrapperAwaitingContent").load("/Grids/MyGridPartial", {id: null /*parameters*/}, function(text, status, xhr){
    //Javascript logic to fire goes here
});

For me the url used in the .load() call is resolved using the UrlHelper on the server

$("#wrapperAwaitingContent").load("@Url.Action("MyGridPartial", "Grids")", {id: null /*parameters*/}, function(text, status, xhr){
    //Javascript logic to fire goes here
});

You also have the option of doing something similar to this using Unobtrusive Ajax. (I'm populating the parameter on the server side here)

@Ajax.ActionLink("Load Data", "MyGridPartial", "Grids", new { id = null/*parameters*/ }, new AjaxOptions() { UpdateTargetId = "wrapperAwaitingContent", OnComplete="onCompleteMethodName" })

There are more properties you can set for the AjaxOptions other than the element to receive the HTML and the method to call when it's finished but I find I'll reuse functions defined in a shared javascript file and populate them only if they are not already populated from there, something like this...

$("a[data-ajax='true']").each(function () {
    var ajaxUpdate = $(this).closest("data-ajax-container");
    $(this).attr("data-ajax-update", $(this).attr("data-ajax-update") ? $(this).attr("data-ajax-update") : ajaxUpdate);
    $(this).attr("data-ajax-mode", $(this).attr("data-ajax-mode") ? $(this).attr("data-ajax-mode") : "replace");
    $(this).attr("data-ajax-success", $(this).attr("data-ajax-success") ? $(this).attr("data-ajax-success") : "AjaxSuccess");
    $(this).attr("data-ajax-complete", $(this).attr("data-ajax-complete") ? $(this).attr("data-ajax-complete") : "AjaxComplete");
    $(this).attr("data-ajax-failure", $(this).attr("data-ajax-error") ? $(this).attr("data-ajax-error") : "AjaxError");
});
Nick Albrecht
  • 15,828
  • 8
  • 64
  • 95
  • Both correct, I finally got it working but I ended up doing it differently than both of the above answers – Bill Blankenship Jan 24 '13 at 14:14
  • 4
    @UserSmith kindly post your solution as well – Ehsan Sajjad Dec 20 '13 at 11:33
  • Unfortunately, I have moved away from using Devexpress and can't seem to find this code anywhere. Dan above asked the same thing a while back and by that time I had went down a completely different route of implementing the entire project. I meant to reply to Dan but lost track amid a mountain of coding needing to be done. – Bill Blankenship Dec 20 '13 at 23:45
5

If you are rendering this partial as part of the normal flow of a View being rendered, the answer is NO.

Reason for this is the Partial is converted into a string before the parent View is even rendered. At that point, none of your markup has been seen by the browser, no jscript has been read.

If, on the other hand, you rendered the partial in your JQuery Ready function:

$(document).ready(function() {

I think you would need to use an Action Partial (Partial that gets called by an action method). Action Partials can be called within your JQuery Ready function by referencing the url (restfully):

$('#divMyGridPartial').load('/Grids/MyGridPartial/{id}');

and any follow up jscript/jquery functions can be called within the ready series.

The other advantage of an Action Partial, the Model is formed within the action method and can be created contextually to what you need (ideally hinging off an id passed).

Dave Alperovich
  • 31,680
  • 8
  • 71
  • 97