Load MVC PartialView via Ajax - ajax

In my View I have:
$.ajax({
url: '/Profile/TryToGetPersonalInfo',
type: 'post',
success: function (outData) {
if (outData.loggedIn == true) {
$('#PersonalInfoData').load(outData.data);
}
}
});
And in my Controller I have:
[HttpGet]
private ActionResult PersonalInfo()
{
return PartialView();
}
[HttpPost]
public JsonResult TryToGetPersonalInfo()
{
// loggedIn is temporary
return Json( new { loggedIn = true, data = this.PersonalInfo() } );
}
How come .load() doesn't do the job? I have also tried .html(), but still, no luck.
Please note that I really want to keep this form (having ProfileInfo() as private), and TryToGetProfileInfo() as post, cause I'm using validation tokens.

You are returning a Json object. You need to return html. In similar cases, I declare the action return type as an ActionResult and return a partial view.

Related

Redirection in ASP.NET MVC to a controller method after the post AJAX call

Present set up -
url: configMap.sitePath + "api/Quiz/" + quizResponse.quizId,
data: JSON.stringify(quizResponse),
success: function (data) {
// Display the data on UI
}
the above post is to a .NET api controller which returns quizResponse.
[ValidateModelState, HttpPost]
public HttpResponseMessage Post(int id, QuizResponse value)
Now as per a new requirement , Once the api has the response I should redirect to another page(a MVC controller and then view). How do I achieve this -
public ActionResult ScptResult()
{
return View();
}
I also thought of redirect after ajax success but not sure if its a correct way.
Also, How do I pass data to the scptresult controller method after post?
In the success function of your JQuery, redirect the page to your MVC page:
window.location = '{controller}/{action}/{quizid}';
Assuming you use the standard MVC routing, and assuming you change your ScptResult function to accept a parameter, so you can pass data to it.
public ActionResult ScptResult(int quizid)
{
return View();
}
Use in java-script after complete your work in success method or anywhere
window.location = '#Url.Action("ScptResult", "YourControllerName")';
I should warn, I'm not very familiar with ajax responses but hopefully this gets close.
API
[ValidateModelState, HttpPost]
public HttpResponseMessage Post(int id, QuizResponse value)
{
//Other stuff...
var redirect = string.Format(#"/controller/ScptResult/{0}", id);
return new HttpResponseMessage()
{
Content = new StringContent(redirect)
};
}
Javascript
url: configMap.sitePath + "api/Quiz/" + quizResponse.quizId,
data: JSON.stringify(quizResponse),
success: function (data) {
window.location = data;
}
Controller
// This follows the default route.
// "/{controller}/{action}/{id}" where id is optional.
// window.location = "/ControllerName/ScptResult/OtherData"
public ActionResult ScptResult(string id)
{
return View();
}

Which one is better? Ajax post or page post[Controller httppost] when only one form is there in a page?

I have a page called Bookprogram which contains 6 input controls namely, txtName, txtEmail, txtPhone, selectcat[dropdown for categories], txtDate, txtMessage. Now when am done with all the validations for the above control, I want to store the data in db. I know how to perform both in ajax as well as complete page posting.
If it's in ajax, after validations, I would just call $.ajax and post the data as a string and fetch it in controller as below:
[HttpPost]
public JsonResult BookProgram(string name, string email, string phone, string category, string date, string message)
{
//code to save into db
return Json(result);
}
If I have to post a whole page, after validations I would just do a $(form).submit(); and write as below in controller:
[HttpPost]
public ActionResult Bookprogram(Mymodel model)
{
//Code to save the data
return View();
}
I just want to know which is better, safe and good to use as I have to display a message after successful submission. I know I can take either of the ways to display message but Is postback[page refresh] really needed in this scenario and if yes what are the advantages of it over ajax post?
EDIT :
I just went through this link and tried to implement 2nd solution of highest voted answer but for my bad luck it wasn't hitting the controller itself. I have kept breakpoint in my controller.
$(form).on("submit", function (e) {
e.preventDefault();
ValidateForm(form);
var selectedVal = $(form).find('select').children(":selected").val();
if(selectedVal=="")
{
$(form).find('div.bootstrap-select').children(":first").addClass('alert-danger');
$(form).find('div.bootstrap-select').next('.text-danger').html('Please select a category!');
}
var formContainer = $(form + ' .text-danger');
if ($(formContainer).text().length == 0) {
$.ajax({
url: '/Home/BookProgram/',
type: "POST",
dataType: 'json',
contentType: "application/json; charset=utf-8",
data: $('#fbookprogram').serializeArray(),
success: function (data) {
if (data.result == "Success") {
alert('success');
}
else {
alert('fail');
return false;
}
return true;
}
});
}
$(form).unbind('submit');
return false;
});
Controller :
public ActionResult BookProgram(MyModel model)
{
if(ModelState.IsValid)
{
//code to save data
}
return Json(new { success = false });
}
What is that I am missing here.
Post Back
Browser Handling - The only advantage I can think of is that the browser will handle redirects and progress loading for you. You don't need to write the logic to redirect users or show a loading bar.
AJAX
Asynsconous -
With AJAX you're getting asyncronous calls so the browsers thread isn't blocked. This allows the user to still interact with the UI whilst waiting for the response from your request.
Better Performance -You generally don't need to reload the entire page resulting in less overhead & HTTP requests being made.
FYI - You can still model bind with JsonResult
public JsonResult BookProgram(Mymodel model)
{
//code to save into db
return Json(result);
}
Post back - is a classic workflow. Delegate most of inner work to your webbrowser. All your responce logic calculated on server side.
AJAX - is a modern way of building dynamic web-applications. Base approach for single-page-applications. Most of work in this case should be done on client side.

Mvc Ajax Jquery Not refreshing view on post

I am new to ajax and mvc... i have a problem with posting back data from jquery. The problem I have is the values are being populated the controller is hit database is updated and then it returns to the page with old data it is not refreshing I have to click f5 to see changes what am I doing wrong? Thanks in advance
Jquery
var values =
{
"PagePartIdentifier": element,
"PagePartContent": data
}
$.post(#Html.Raw(Json.Encode(Url.Action("UploadData", "Home"))),values,function(data)
{
// do stuff;
});
Model
public class PagePartModel
{
public string PagePartIdentifier { get; set; }
public string PagePartContent { get; set; }
}
Controller
[HttpPost, ValidateInput(false)]
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public ActionResult UploadData(PagePartModel pagePartm)
{
UpdatePage(pagePartm);
ModelState.Clear();
//return RedirectToAction("Index");
return Json(new { success = true });
}
Html is rendered from a helper method
public static PagePartModel PageAfterContent(this System.Web.Mvc.HtmlHelper html, int page)
{
string part = "AfterContent";
Blog.PageParts pageParts = new Blog.PageParts();
PagePartModel thispart = pageParts.GetContentForPageByPart(page, part);
return thispart;
}
Returns the model for each part to the page
When using $.post, you're sending the data to the server via ajax, so the page never reloads. I'm not sure what the UpdatePage(pagePartm); call in your post method is doing, but since that method is getting called with ajax, it can't change anything on the page. Now in your success handler on your $.post, you can manipulate the DOM to reflect the success or failure of your $.post call.
In your action, instead of returning your Json(new { success = true }); you should/could return the data that you want to be displayed on the page,
e.g.
return Json(new { pagePartm }); // if that is what should be returned
Then modify your $.post() to append the data into the DOM somewhere.
e.g.
$.post("your_controller_action", { name: "John", time: "2pm" },
function(data){
doStuff(data); // this is your point of interaction with the returned data
// or
$("#my_h3").val(data.pagePartm.PagePartIdentifier);
$("#my_div").append(data.pagePartm.PagePartContent);
});
from the jQuery.post documentation.
This will avoid the need to refresh the page to see the results.
jquery ajax post cache property is false ?
$.ajax({
url: '/youraction',
cache: false,
type: 'post'
success: function (data) {
},
error: function (e) {
alert(e.responseText);
}
});

Partial View Validation Without JavaScript

I have a partial view in which there is a form. I POST this form using the PRG pattern. I am using the AjaxHelper to create my form. I also need this form to work without javascript. The problem is that when model validation fails, it always changes the url to my partial view.
public ActionResult PostForm(PostFormModel postFormModel)
{
if (ModelState.IsValid)
{
return RedirectToAction("SomewhereElse");
}
else
{
if (Request.IsAjaxRequest())
{
return PartialView("_PostForm")
}
else
{
// What do I do here?
}
}
}
Here's what I have tried:
return PartialView("_PostForm", postFormModel);
This just renders the partial view and doesn't contain any of the parent stuff.
return View("Index", new ParentModel() { PostFormModel = postFormModel });
This actually produces the correct result. It displays the parent view, but the URL is that of the partial http://localhost:22485/Controller/PostForm! I feel like this is really close to the solution. What now?
If you want to change url, you should redirect to another action (using PRG pattern). Insert next code instead of '// What do I do here?':
postModelService.Save(postFormModel); //to Session or to DB
return RedirectToAction("Parent");
New action should look like this:
public ActionResult Parent()
{
var postFormModel = postModelService.Load();
return View("Index", new ParentModel() { PostFormModel = postFormModel });
}
Hope it helps.

ASP.NET MVC "Ajax.BeginForm" executes OnSuccess even though model is not valid

I have a "submit feedback" form which uses "Ajax.BeginForm" to render a partial containing the form elements. The OnSuccess event is triggering even if the ModelState is not valid. Is this normal? I was expecting to be able to do a few postbacks resulting in an invalid model, then when the model is valid and there are no errors then the OnSuccess event would trigger?
I handle this issue with a fairly simple javascript technique:
First setup your OnSuccess like this:
OnSuccess = "UpdateSuccessful(data)"
Then your javascript function like this:
function UpdateSuccessful(data) {
if (data.indexOf("field-validation-error") > -1) return;
// Do your valid stuff here
}
This way, there is no need to mess with your controller, or more importantly, your controller can return the Partial View with the model errors without doing anything weird, ie:
public ActionResult SaveDetails(Project model)
{
if (ModelState.IsValid)
{
model.SaveProject();
}
return PartialView("ProjectForm", model);
}
And in your AjaxOptions:
UpdateTargetId = "FormContents"
Now just make sure you have a div or something with id="FormContents" wherever you want your form displayed.
Is this normal?
Yes, of course. If the server sends HTTP 200 the OnSuccess method is called. The notion of modelstate validity is server side only. As long as your controller action returns some view/partial/json/... the OnSuccess will trigger. If an exception is thrown inside your controller action then the OnError will be triggered instead of OnSuccess.
So in order to handle this case you could have your controller action do something along the lines of:
[HttpPost]
public ActionResult Process(MyViewModel model)
{
if (!ModelState.IsValid)
{
return Json(new { success = false });
}
return Json(new { success = true });
}
and then:
function success(result) {
if (result.success) {
// the model was valid
} else {
// the model was invalid
}
}
Now in the case of invalid model you might want to show the error messages to the user by refreshing the form. What you could do in this case is place your form inside a partial and in the event of an invalid modelstate you would return a partialview from your controller action and in the case of success a json object. So in your success handler you could test:
function success(result) {
if (result.success) {
// the model was valid
} else {
// there were errors => show them
$('#myform_container').html(result);
// if you are using client side validation you might also need
// to take a look at the following article
// http://weblogs.asp.net/imranbaloch/archive/2011/03/05/unobtrusive-client-side-validation-with-dynamic-contents-in-asp-net-mvc.aspx
// and reattach the client validators to the form as you are
// refreshing its DOM contents here
}
}
You can do the following:
var OnSuccess = function() {
if ($(".validation-summary-errors").length == 0) {
//Your javascript/jquery code goes here
}
}
Slight variation on Luis' answer:
function OnSuccess() {
if ($("span[class='field-validation-error']").length == 0) {
alert("Target Platform saved Successfully.");
}
}
I return a bad request instead of the View to ensure that the ajax call returns onfail and not onsuccess.
In the xhr.statustext you can find the string written in the bad request and manage correctly the onfail event.
Server side:
if (!ModelState.IsValid)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Model not valid");
}
Client side:
$.ajax({
url: '',
method: 'POST'
}).fail(function (xhr) {
alert(xhr.statustext);
});

Resources