I have a form that i use to add data to my database. I am using Ajax.BeginForm() to post data to the controller and then execute a stored procedure to save data. The result that i want is to show an error if the stored procedure fail to add data and to redirect to an other page in the other case. So I did something like this in my controller.
if (succees)
{
return RedirectToAction("ModificationPage", new { id = posted.articleId });
}
else
ViewData["ErrorMessage"] = msg;
return PartialView("_error");
_error is a simple partialview which display the error message. My problem is that when the stored procedure add data, instead of redirecting to the modification page, the modification page is rendred inside the view. Is there a method in asp mvc that can fix this
You can use onSuccess parameter of ajaxForm
using( Ajax.BeginForm( "action","controlle",
new AjaxOptions( ) {
OnSuccess = "mySuccessFunction",
} ) ) }
And then in js
function mySuccessFunction(){
//check if html with error exist on page
window.location = "url"
}
RedirectToAction is not supported in ajax. You could send the redirect URL back to the client and from the client use window.location to redirect to the new location.
you can in your controlleur
if (succees)
{
Redirect("/AREA/ContolleurName/ModificationPage/?Id=" + posted.articleId+ ")
}
else
ViewData["ErrorMessage"] = msg;
return PartialView("_error");**strong text**
and create action in your conrolleur
public ActionResult ModificationPage(int Id)
{
return //your view
}
Or ajax like this
$("class(.test) or Id (#Test)").on("click", function () {
var id = $(this).attr('id');
/*Création de la chaine en Json...*/
window.location.href = "/AREA/ContolleurName/ModificationPage?Id=" + id +"";
});
Related
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();
}
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.
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);
}
});
Im new to Web Development and its principles so apologies if my question does not seem clear.
Story So Far......
Im writing an Open Source application to learn ASP.NET MVC3. Now im at the stage where im creating my CRUD controller to allow me to create some new Types. Now I have created a SiteAdmin Controller which holds my Dashboard, with has a View. The View will contain tabs . I have been learning how to handle tabs using the following blog post and JQuery UI
http://ericdotnet.wordpress.com/2009/03/17/jquery-ui-tabs-and-aspnet-mvc/
I have decided to use the AJAX example to handle my tabs, whereby I pass an index parameter to a Controller Action Method called AjaxGetTab . This method (as per the blog post) returns a Partial View for the required Type. Within the Partial View there are Create Controller Action Method's, for e.g. CreateTransactionType (HttpPost), which create new records.
"Stop the waffling what is the problem"
The problem is that my list within the tab on the view doesn't refresh after the Create method is finished. This problem only exists in IE9 (Only IE i have tested) but Chrome and Firefox work, i.e. the list refreshes.
I have checked the Database records exists.
My code is here:
JQuery in Dashboard.cshtml:
<script type="text/javascript">
$(document).ready(function() {
$("#tabs").tabs();
getContentTab (1);
});
function getContentTab(index) {
var url='#Url.Content("~/SiteAdmin/AjaxGetTab")/' + index;
var targetDiv = "#tabs-" + index;
var ajaxLoading = "<img id='ajax-loader' src='#Url.Content("~/Content")/ajax-loader.gif' align='left' height='28' width='28'>";
$(targetDiv).html("<p>" + ajaxLoading + " Loading...</p>");
$.get(url,null, function(result) {
$(targetDiv).html(result);
});
}
SiteAdminController AjaxGetTab Method:
/// <summary>
/// AJAX action method to obtain the correct Tab to use.
/// </summary>
/// <param name="index">Tab number</param>
/// <returns>Partial View</returns>
public ActionResult AjaxGetTab(int id)
{
string partialViewName = string.Empty;
object model = null;
//--Decide which view and model to pass back.
switch (id)
{
case 1:
partialViewName = "_TransactionType";
model = db.TransactionTypes.ToList();
break;
case 2:
partialViewName = "_DirectionType";
model = db.DirectionTypes.ToList();
break;
case 3:
partialViewName = "_UserType";
model = db.UserTypes.ToList();
break;
case 4:
partialViewName = "_CurrencyType";
model = db.CurrencyTypes.ToList();
break;
case 5:
partialViewName = "_tabError";
break;
}
return PartialView(partialViewName,model);
}
}
SiteAdminController CreateTransactionType Method:
[HttpPost]
public ActionResult CreateTransactionType(TransactionType model)
{
try
{
// TODO: Add insert logic here
if (ModelState.IsValid)
{
model.id = Guid.NewGuid();
model.RecordStatus = " ";
model.CreatedDate = DateTime.Now;
db.TransactionTypes.AddObject(model);
db.SaveChanges();
}
return RedirectToAction("Dashboard");
}
catch
{
return PartialView("_tabError");
}
}
Replace your
$.get(url,null, function(result) {
$(targetDiv).html(result);
});
By:
$.ajax({
type: 'get',
url: url,
cache: false,
success: function(result) {
$(targetDiv).html(result);
}
});
The problem is that IE caches ajax requests, so by setting cache: false in the settings it should work.
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);
});