Best Practice for showing Page after Post - ajax

I have a View with a Form that calls a controller action Post Method to "Complete" a Package. It then needs to refresh the page its on as that contains information that will be updated, both within the view itself and also within a partial. It does use two different Controllers in different MVC Areas.
The Post works correctly and the redirect is issued, but the page is not refreshed.
I have read that instead, I should use OnSuccess within the Ajax call that calls Complete, but I thought that was for in page calls, not ones that navigate to different pages.
View Form
#using (Ajax.BeginForm("Complete", "Packages", new { Area = "Core" },
new AjaxOptions
{
HttpMethod = "POST"
}))
{
Core(Area) Packages Controller
[HttpPost]
public ActionResult Complete(int ID)
{
// Update code
// Refresh the full page
return RedirectToAction("Summary", new { Area = "Control", id = packageBuilder.CurrentPackage.ID });
}
Control (Area) Packages Controller
[HttpGet]
public ActionResult Summary(int id)
{
// Get Model
return View("Summary", model);
}
Any pointers would be warmly welcomed.
Thanks,
Chris.

The reason that your page is not refreshed after you submit the form and the redirect is not issued in the browser, is that you are submitting the request over AJAX. This is a request issued by the browser behind the scenes.
If you want to submit the form and for the page to be refreshed, I'd recommend changing your code from Ajax.BeginForm(... to Html.BeginForm(... and then it will load the page and perform the redirect as expected.

I am not quite sure how your ajax calls are structured, but if you are using the MVC Ajax helper you can just call `location.reload(); in the OnComplete method, like so:
#using (Ajax.BeginForm(new AjaxOptions{OnComplete = "javascriptfunction"}))
{
//Data and submit button
}
<script>
function javascriptfunction(){
location.reload();
}
</script>

Related

Post a form mvc3

I have a link and search button. Clicking on search button posts the page to a predefined action. Now clicking on a link should post the page to another action and should post all the values hidden varible values to another action. Can it be done.
Typically A link will generate an anchor tag and it usually gives you an HTTP GET request. Not the post request. You can supply parameters in your link which will be accepted as the parameters of the action method
#Html.ActionLink("Search","Search","Items",new { #id="nokia" },null);
This will generate a link with a querystring key called id with value nokia.
../Items/Search/nokia
or
../Items/Search?id=nokia
And your action method with id parameter can handle this GET request
public ActionResult Search(string id)
{
//Do whatever you want to do with the value in id. return a view with results
}
IF you really want to do an HTTPPost from a link, You can grab the click event of the link in the javascript and make an httppost call. The below script does that with jQuery library.
$(function(){
$("a").click(function(e){
e.preventDefault();
$.post($(this).attr("href"),function(result){
//do whatever with the results
});
});
});
But make sure you have an HttpPost version of the ActionMethod in your controller to handle this request
[HttpPost]
public ActionResult Search(string id)
{
//This is a POST request.Do whatever you want to do with the value in id. return a view with results
}
You can't use #Html.ActionLink for HTTP POST (edited: unless you use javascript function to submit the form via specifying onClick HtmlAttribute) . You can use submit buttons instead and style them as hyperlinks using jQuery. In this case you should be able to post your model with whatever values.
Alternatively you can use #Ajax.ActionLink and specify AjaxOptions { HttpMethod = "POST" }

Partial rendering in MVC3

I'm trying to render a particular section/div click a particular link or button. Suppose link/button is in the A.cshtml page , and b.cshtml is a partial view that I want to load in A.cshtml page within a particular section/div. I tried Ajax.ActionLink but can't do. Any help or suggestions?
I tried ajaxactionlink but cant do
That's really not the way to ask a question here. Cant do is not a precise problem description. Next time when you ask a question on SO show what you have tried.
This being said, let me provide you with an example:
#Ajax.ActionLink("click me", "SomeAction", new AjaxOptions {
UpdateTargetId = "result"
})
<div id="result"></div>
and then you will have an action which will render this partial view:
public ActionResult SomeAction()
{
return PartialView("_NameOfYourPartial");
}
Finally make sure that you have referenced the jquery.unobtrusive-ajax.js script to your page which uses the HTML5 data-* attributes emitted by the Ajax.ActionLink helper to hijack the click event and send an AJAX request instead of the normal request:
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
The controller can return a partial view as action result:
public ActionResult Details()
{
var model = // your model
var viewName = // your partial view name
return PartialView(viewName, model);
}
Ajax.ActionLink should do it, may be you missed somwthing.
Check this post it may give you the answer

Refreshing parent view when a partial view's form is submitted

I'm looking into using partial views in MVC3 using Razor, and I get my partial view to render and it works fine.
What I'd like to do, though, is refresh the parent view when the partial view is submitted.
Code in my parent view to render partial view
<div id="mydiv">
#{ Html.RenderAction("Add", "Request"); }
</div>
Action for parent view is simple,
public ActionResult Index()
{
List<obj> reqs = //some query
return View(reqs);
}
In my partial view's get action I have:
public ActionResult Add()
{
AddRequestViewModel vm = new AddRequestViewModel();
//set some stuff on the VM here
return PartialView(vm);
}
In the post action called by the partial view, if modelstate isn't valid, return PartialView(vm)
If it is valid, I'd like the parent and partial views to refresh.
I tried RedirectToAction, but this can't be called in an action called by a partial, apparently, and I tried return Index();, but this causes an issue with the code used to render the partial view,
Exception Details: System.InvalidOperationException: The model item passed into the dictionary is of type 'System.Collections.Generic.List'1[DatRequests.Models.ReqRequest]', but this dictionary requires a model item of type 'DatRequests.ViewModels.AddRequestViewModel'.
Any suggestions on how to do this would be appreciated. The purpose of the page is to show a list of elements, and the partial contains a form to add a new element to the list.
Edit: The partial's model is different, as it contains data for selection, which is from a db, which is why I tried RenderAction, but I'm not sure if there are other ways of doing this.
When the partial view is submitted normally you submit it to some controller action. You could either submit it using a normal request or an AJAX request. If you use a normal request you could perform a standard redirect to the Index inside the POST controller action that will handle the form submission. If you use AJAX, you could return a JSON result pointing to the url that you want to redirect:
[HttpPost]
public ActionResult Foo(MyViewModel model)
{
if (!ModelState.IsValid)
{
return PartialView(model);
}
return Json(new { url = Url.Action("Index") });
}
and inside your AJAX success callback:
success: function(result) {
if (result.url) {
// we have a success
window.location.href = result.url;
} else {
// invalid modelstate => refresh the partial
$('#mydiv').html(result);
}
}
Probably RenderAction should not be used this way.
When using Html.RenderAction, a new/seperate request would be sent to the server. And you got another chance to load some data from db or somewhere else to display to the client. Also, you could apply OutputCache to this action. this is usually the way doing global cache.
Here you are doing a POST to the server. Either directly put a element here or using a partial view to do the Post. And in the corresponding action, do a RedirectToAction.
Do it with ajax or not isn't the point. my opinion is more about the right way using RenderAction

Creating a ajax login dialog box with MVC 3 and jQueryUI

I'm using Asp.Net MVC 3 (with Razor) and jQuery/jQueryUI to create a dialog login box.
I'm still quite new to these technologies and have run into a problem.
The login form is in a partial view, I use the following jQuery code to load it into the page:
$('#log-in').click(function () {
if (ServerModel.UserId == 0) {//User not logged in, open login dialog
$("<div></div>")
.addClass("dialog")
.addClass("form-dialog")
.attr("id", "login-dialog")
.appendTo("body")
.dialog({
title: 'LOGIN',
close: function () { $(this).remove() },
modal: true,
width: 323,
resizable: false
})
.load(ActionUrls.LogOn);
}
});
ActionUrls.LogOn, has the path for the Logon action method in the controller.
The partial view with the login form looks along these lines:
#using (Ajax.BeginForm(new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "login-dialog" }))
{
//Login form fileds in here with submit button at the end
}
Here's the code for the controller:
[HttpGet]
public ActionResult LogOn()
{
return PartialView("_Logon");
}
[HttpPost]
public ActionResult LogOn(LogOnModel model)
{
if (ModelState.IsValid)
{
CustomSqlMembershipProvider provider = new CustomSqlMembershipProvider();
if (provider.ValidateUser(model.UserName, Security.ComputeHash(model.Password)))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
return RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
// something failed, redisplay partial view with the model
return PartialView("_Logon", model);
}
This all works fine, however the problem I'm having, is that when the user is authenticated, as can be seen in the controller code. I try to RedirectToAction("Index", "Home"), this with the intent that the page should reload with the user logged in and the dialog closed.
However at the moment, just the login dialog box reloads with the whole page content in it. I understand that this is probably normal behavior, as I'm telling the form in the logon view to update the UpdateTargetId of the dialog box.
So the question is, can I reach my desired result of the whole page reloading and if so, how??
Any help and hints would be most appreciated.
/Ola
Instead of using a form parameter you can use jquerys ajax method and send in the username and password and in the success function of the ajax method if the user is successfully authenticated redirect the user to your index page.
note the index page should still have a way to determine that the user is authenticated or not else anyone can typein the url.
What do you think?
On your .load ajax call, the data that is returned contains redirect information. I'm not sure if this is only for JSON POSTS, but it's worth a try:
...
.load(ActionUrls.LogOn, function(data) {
if (data.redirect) {
window.location.href = data.redirect;
else {
// other
}
});
Update:
The callback event that you need to hook onto is the one that submits the login information, not the one that loads the login page. I asked you to hook onto the wrong ajax call on top, the one you need to latch onto is this one:
#using (Ajax.BeginForm(new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "login-dialog" }))
{
//Login form fileds in here with submit button at the end
}
Unfortunately, I do not know how to hook onto that event. This article may help:
How to get an ASP.NET MVC Ajax response to redirect to new page instead of inserting view into UpdateTargetId?
I noticed it's an old question, but I hope my reply may help to someone.
For something similar I redirected to a 'helper' page in the controller action, which contained (for me almost) only some JavaScript in the scipt tag (or you should link it of course).
In this case that's enough:
window.location.href = "http://www.foo.com";
...and I also find and close the dialog there:
$('#login-dialog').dialog('close');
For me it was well, but I also appreciate better solutions.

Multiple Renderactions in View MVC3

I have multiple renderactions in a MVC3 view.
I'd like to get a partial View and then the results as the parialviews get in.
(like some placeholders on the page and then the page gets filed up with the renderaction results as the partialviews poor in).
I now have several Html.RenderAction("Action", "controller"); in with different actions on the Main view returning some partial views to be rendered. How do I get them async in return instead of waiting with the render until the last one pops in?
Do I need some ajax or is this done using the AsyncController?
I always prefere to use jQuery ajax. You can simply return PartialView as a ajax action result and then in the jQuery (on the browser side) replace content of specipic part of you page with just returned PartialView.
Quick and easy and no page reload!
Take look a this:
$.ajax({
type: "POST",
data: { "supporterId": supporterId },
url: '#Url.Action("ShowDetails")',
success: function (result) {
$("#popupDetails").html(result); - here you are replaceing content of you page with partial view returned by the action
},
error: function (error) {
alert("error");
}
});
And here is the action:
public ActionResult ShowDetails(int supporterId)
{
Supporter supporter = ... //get supporter object from the database
return PartialView("Details", supporter);
}

Resources