views:

46

answers:

2

i have a screen with multiple little widgets (all with different divs around them). i have one form and when i post (using jquery) right now it updates the single form using ajax.

i want two other divs to refresh as well (that are outside the form). What is the best way to trigger a refresh of multiple different divs on a single jquery ajax post callback?

+1  A: 

Unless you modify your server action to return the appropriate HTML for all the divs that need to be updated (probably using JSON encoded string) you cannot achieve this in a single AJAX request.


UPDATE:

There's another technique I would like to show. You could have a controller action which returns javascript. Let's take for example the following ASCX partial view (RefreshPartials.ascx):

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>

$('#partial1Container').html('<%= Template.RenderPartialToString("~/Views/Home/Partial1.ascx", ViewData) %>');
$('#partial2Container').html('<%= Template.RenderPartialToString("~/Views/Home/Partial2.ascx", ViewData)%>');

Where the RenderPartialToString is taken from here (Remark: this method probably has some flaws and might not work for every cases but you could try it). Next you perform an AJAX request to a controller action which simply renders this partial:

public ActionResult RefreshPartials()
{
    return PartialView("RefreshPartials");
}

You need to specify dataType: script in your ajax request so that the javascript contained in the previous partial is being evaluated:

$.ajax({
    url: '/home/refreshpartials',
    dataType: 'script'
});

One last note is to properly escape the result of the RenderPartialToString method as it may contain characters that brake javascript. Here's one method you might use:

public static string JsEscape(this HtmlHelper html, string content)
{
    content = Regex.Replace(content, "(\r\n)|(\r)|(\n)", @"\n", RegexOptions.Multiline);
    content = Regex.Replace(content, "(?<!\\\\)\"", "\\\"", RegexOptions.Multiline);
    return content;
}

So finally your partial could look like this:

$('#partial1Container').html('<%= Html.JsEscape(Template.RenderPartialToString("~/Views/Home/Partial1.ascx", ViewData)) %>');

You can see that you can put whatever javascript you like in this RefreshPartials.ascx to make your AJAX request fancy.

Remark: The idea is taken from Ruby On Rails Javascript Generators.

Darin Dimitrov
so i guess i can have the callback on one ajax request kickoff the new requests
ooo
Yes, or if they don't depend on each other send in parallel.
Darin Dimitrov
@Darin Dimitrov - the post is updating a db and the refresh of the other divs are dependent on the new data being updated. How do you have a ajax callback kick off another ajax request?
ooo
+1  A: 

Way 1. Have your post action partial view to contain hidden data that you will use to update other divs. I think that's much better than returning special JSON or scripts code. You can probably use .detach() instead of .clone().

<div>Main post result data</div>
<div id="additional1" style="display:none">Moredata</div>

function onFormPostSuccess(data) {
   $("#result").html(data);
   $("#additional_div").html($("#result #additional1").clone().show());
}

Way 2. On form post success do additional $.get()s to update additional divs. Works better if additional data is big; if it's small then #1 is better.

function onFormPostSuccess(data) {
   $("#result").html(data);
   $("#addiotional_div").load("/additional_action/updated_info");
}
queen3