I am facing a problem with ajax updating of div in asp.net mvc3.
I have a View with content
<div id="post_comments">
@{Html.RenderPartial("_RefreshComments", Model);}
</div>
<div id="commentForm">
@using (Ajax.BeginForm("Details", new { id = Model.Post.PostId }, new AjaxOptions
{
HttpMethod = "POST",
InsertionMode = InsertionMode.InsertAfter,
UpdateTargetId = "post_comments"
}
))
{
// form content goes here
<p id="buttons">
<input type="submit" value="@Strings.Save" />
</p>
}
This is my partial view
@model Project.Models.Posts.PostDetailsViewModel
@{
foreach (var c in Model.ApprovedComments)
{
@Html.DisplayFor(x => c)
}
}
I have a controller
public ActionResult Details(int id, FormCollection form )
{
var model = new PostDetailsViewModel(UnitOfWork, id);
return PartialView("_RefreshComments", model);
}
I have following script included in my layout cshtml
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
and also
<appSettings>
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
It really works, I am able to add comments, but controller only returns the PartialView, not contained in the layout. I am found ASP.net MVC3 - Razor Views and PartialViews with Ajax Postbacks but nothing from there helped me.
Does anyone have any ideas?
I would use jquery ajax to call the action and then return the partial view from the controller. Then reload the returned html into the container using jquery.
First, add a refresh button or something you can trigger the ajax event... then do the below javascript.
Do something like this:
<div id="post_comments">
@{Html.RenderPartial("_RefreshComments", Model);}
</div>
<div id="commentForm">
@using (Ajax.BeginForm("Details", new { id = Model.Post.PostId }, new AjaxOptions
{
HttpMethod = "POST",
InsertionMode = InsertionMode.InsertAfter,
UpdateTargetId = "post_comments"
}
))
{
// form content goes here
<p id="buttons">
<input type="submit" value="@Strings.Save" />
<input type="button" id="refreshButton" value="Refresh" />"
</p>
}
$('#refreshButton').click(function(){
$.ajax({
url: 'controller/Details.aspx',
datatype: 'html',
success: function(data) {
$('#post_comments').empty().html(data);
}
});
});
Obviously, the url needs to be the route to your action. Other than that, this should work fine for you.
Usage:
function onUploadComplete()
{
@Ajax.Update("targetId", helper => helper.Action("ActionName"))
}
And the code:
/// <summary>
/// I'd rather stab myself in the eye with a fork than bothering with php ever again and living without extension methods
/// </summary>
/// <param name="helper">makes sense to make it available here. who likes dozens of new helper classes</param>
/// <param name="updateTargetId">simple enough</param>
/// <param name="actionUrlFactory">resharper will show if we're messing stuff up. hurray.</param>
/// <param name="isAsync">speaks for itself</param>
/// <param name="options">might as well reuse that one for callbacks</param>
/// <returns>generated code with compile time checks</returns>
public static IHtmlString Update(this AjaxHelper helper, string updateTargetId, Func<UrlHelper, string> actionUrlFactory, bool isAsync = true, AjaxOptions options = null)
{
var requestUrl = actionUrlFactory(new UrlHelper(helper.ViewContext.RequestContext));
if (options == null)
{
options = new AjaxOptions()
{
AllowCache = false,
HttpMethod = "GET"
};
}
string cache = options.AllowCache ? "true" : "false";
string success = options.OnSuccess.Length > 0 ? ".done(" + options.OnSuccess + ")" : "";
string fail = options.OnFailure.Length > 0 ? ".fail(" + options.OnFailure + ")" : "";
string always = options.OnComplete.Length > 0 ? ".always(" + options.OnComplete + ")" : "";
string isAsyncString = isAsync ? "true" : "false";
// of course you can go way further here, but this is good enough for me. just sharing since i didn't find a nice solution here that doesnt involve writing js manually every time.
string js = string.Format(@"
$.ajax({{
cache : {7},
async : {6},
url : '{0}',
type : '{1}'
}})
.done(function(data){{
$('#{5}').html(data);
}});
{2}
{3}
{4}
", requestUrl, options.HttpMethod, success, fail, always, updateTargetId, isAsyncString, cache);
return new HtmlString(js);
}