RedirectToAction from JSON Form Submission - javascript

I'm uploading a file via a form with the following script tag:
#using (Html.BeginForm("CreateCompResponse", "Surveys", FormMethod.Post, new { enctype = "multipart/form-data", onsubmit = "return myFunction()" }))
Upon successful upload, the controller should RedirectToAction:
return Json(new
{
redirectUrl = Url.Action("CreateBenefitSummary", "Surveys"),
isRedirect = true
});
In the view, I'm handling the function as follows (I copied and pasted this from another SO post, as I don't know JavaScript):
<script type="text/javascript">
success: function(json) {
if (json.isRedirect) {
window.location.href = json.redirectUrl;
}
}
</script>
Rather than returning my desired controller action, it returns a JSON string:
{"redirectUrl":"/Surveys/CreateBenefitSummary","isRedirect":true}
How can I get this to redirect to the proper action?
Thanks!

You are using Html.BeginForm which means that the ActionResult you expect is in the PostBack. The way return Json will work is if you use Ajax.BeginForm and pass the function name to it for onsuccess. You should be doing this:
#using (Ajax.BeginForm("CreateCompResponse", "Surveys", new AjaxOptions { OnSuccess = "onSuccess",HttpMethod = "Post" }))
And your function should be
<script type="text/javascript">
function onSuccess(json) {
if (json.isRedirect) {
window.location.href = json.redirectUrl;
}
}
</script>
If you want to use PostBack then you can use RedirectToAction within the processing controller action to check if the upload is successful or not based on the result you can use the above mentioned return RedirectToAction or return View()

Related

How to set a Model property inside javascript and be able to receive it in POST method

I have a button when that button is clicked I want to set a model property to true and be able to receive it in the back end. Code is a bit messed up but bear with me please as I have taken alot of code out of it.
#model FullConfigurationMV
#using (Html.BeginForm(null, null, FormMethod.Post, new { id = "MyForm" }))
{
#Html.HiddenFor(model => model.IsTemplate)
// Code removed for brevity
<button id="DraftName">Click me</button>
}
<script>
$( document ).ready(function() {
debugger;
$("#DraftName").click(function()
{
#Model.IsTemplate = true; // I AM SETTING THE VALUE AS TRUE
SaveStyles();
});
});
</script>
<script>
function SaveStyles() {
var data = $('#MyForm').serialize();
var URL = "SOME URL"
$.ajax({
url: URL,
type: 'POST',
data: data,
success: function (result) {
},
error: function (error) {
}
});
}
</script>
POST ACTION
public JsonResult SaveStyles(FullConfigurationMV data)
{
// data.IsTemplate is coming out to be false
// Rest of the UI control data is coming back properly
}
EDIT
Since I have below code. is that the issue?
var data = $('#MyForm').serialize();
Think about this problem a little differently.
All the view does is render html. Since you have a form in html, all your javascript has to do is to set the form element's value to true.
You should be able to use the jQuery selector like
$('input:hidden[name=IsTemplate]').val(true);
And your form serialize should pick it up.
Razor view are generated in server side. So when you browser get the HTML there is no razor code in it so the following code will not work:
$("#DraftName").click(function()
{
#Model.IsTemplate = true; // <-- this will not work and will not exist in client side
SaveStyles();
});
You should set the hidden field you just put in your form #Html.HiddenFor(model => model.IsTemplate) which generate <input type='hidden' /> and just update your javascript code by doing this:
$("#DraftName").click(function()
{
$("#MyForm input[type='hidden']").val("true"); // <- Replace your Razor code with this.
SaveStyles();
});

How do i submit form via ajax?

i'm trying to submit forms without post back via ajax ..my code doesn't work
whats wrong in my script?
i'm new to ajax..help me with ajax scripts..
below is my code
note: i have two submit buttons with in single view. I want to make ajax call for both submit actions
my view
#model AjaxEF.Models.Customer
#using (Html.BeginForm("Index", "Main", FormMethod.Post,new { id="idForm"}))
{
#Html.EditorForModel()
<br />
<input type="submit" name="save" value="Save" />
<input type="submit" name="cancel" value="Cancel" />
}
<script>
$("#idForm").submit(function (e) {
e.preventDefault(); // avoid to execute the actual submit of the form.
var url = "~/Main/Result"; // the script where you handle the form input.
$.ajax({
type: "POST",
url: url,
data: $("#idForm").serialize(), // serializes the form's elements.
success: function (data) {
alert(data); // show response from the php script.
}
});
});
</script>
my controller
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(Customer obj, string save, string cancel)
{
if (!string.IsNullOrEmpty(save))
{
ViewBag.Message = "Customer saved successfully!";
}
if (!string.IsNullOrEmpty(cancel))
{
ViewBag.Message = "The operation was cancelled!";
}
return View("Result", obj);
}
public ActionResult Result()
{
return View();
}
Not sure why the other answer was deleted, but it was 100% correct. The URL you're hitting with your AJAX is your Result action, which does nothing but return a view. You need to post to your Index action, and since the form is already set to post there, the best way to get that URL for your AJAX is to select it from the form:
var url = $('#idForm").attr("action");

Submit on an ASP.NET MVC form?

Is there a way I can get the returned value from an action using .submit event listener in jQuery?
I have a problem which is when the action is completed it returns a JSON file and my browser navigates to an empty page and just display the JSON returned. I don't want that to happen, I want to be able to read the JSON result and based on it decide what to do.
Here's my POC:
View:
#using (Html.BeginForm("SubmitTest", "DMS", FormMethod.Post, htmlAttributes: new { id = "formId" }))
{
<input type="submit" value="Sumbit" />
}
Controller:
public JsonResult SubmitTest()
{
return Json("Done");
}
Script:
$(document).ready(function () {
$("formId").submit(function () {
alert("Submitted");
});
});
you can add event.preventDefault or return false to prevent the default event from occurring . so it won't navigate to an empty page.
$(document).ready(function () {
$("formId").submit(function () {
alert("Submitted");
return false;
});
});
EDIT:
if you want to get the response you need to make an ajax request and get the form data from the fields. you can't get the response with submit function.
$(document).ready(function () {
$("formId").submit(function () {
/// make an AJAX request
$.post(
$(this).attr('action'), //// action url
$(this).serialize(), //// serialize form fields
function(json) {
alert(json);/// json response
}, 'json');
return false; /// prevent navigation
});
});
Use an AJAX form instead of the HTML form, this way you can check the response after it is submitted and do whatever you need using the OnSuccess handler.
For detailed info refer to this article

Different behaviour posting to controller via javascript than directly from submit button

I have this button in a form:
<button id="save" type="submit" formaction="#Url.Action("SaveEvent")" formmethod="post">Save</button>
Which posts to this controller:
public async Task<ActionResult> SaveEventAsync(EventDataModel vm)
{
// save to db etc...
TempData["Saved"] = true;
return RedirectToActionWithReturnUrl("EventDetail", new { eventId = vm.EventId });
}
This redirects me fine to the detail page. But if I then add this JS function to do the post, I don't get redirected nor do I see the value in TempData.
$('#save').click(function(e){
e.preventDefault();
$.post( "SaveEvent", {
EventID: "#Model.EventId",
SomeValue: 123
});
}
I tried redirecting in the JS function but it doesn't return me the newly saved values:
window.location = '#Html.Raw(#Url.Action("EventDetail", new { eventId = #Model.EventId}))';
Could someone please explain why the redirect in the controller does not work when posting from JS?
The Redirect related methods in controller (Redirect,RedirectToAction etc) returns a 302 response with the new url to be redirected to as the value of the location header and browsers will usually issue a new GET request to that.
You should not be making the call to an action method which returns a 302 response from an ajax call. Instead, you should return a json response to the ajax call which is making the request.
public async Task<ActionResult> SaveEventAsync(EventDataModel vm)
{
// save to db etc...
return Json(new {status = "success"});
}
and in your $.post method callback, inspect the response and do the redirection.
$('#save').click(function(e){
e.preventDefault();
var url="#Url.Action("SaveEvent","YourControllerName")";
$.post(url, { EventID: "#Model.EventId", SomeValue: 123 }, function(res){
if (res.status === "success") {
window.location.href =" #Url.Action("EventDetail","YourControllerName",
new { eventId=Model.EventId })";
}
});
});
I updated your code to use Url.Action method to build the correct relative url to the action method(s). If you javascript code is inside a separate js file, build the base url in your razor page and pass to your js code as explained in this post.

On return of Ajax.BeginForm with validation error hide a button.How?

I have a Ajax.BeginForm in my page.
When a validation error is returned i want to hide a button.
example:
I want to save a name .if duplicate name exists the controller returns validation error.
On return of the error i want to hide the nextStep button.
Any idea how to do that?
<script type="text/javascript">
function OnSuccess() {
alert("Success");
$('#btnNextstep').show();
}
</script>
#using (Ajax.BeginForm("Save", "PropertyBuilder", new AjaxOptions()
{
UpdateTargetId = "divSave",
OnSuccess = "OnSuccess",
InsertionMode = InsertionMode.Replace
}))
{
...
}
One way i can it is OnSuccess i will get the #Model but is this a correct way. eg
function OnSuccess() {
if(#Model.Id != 0){ //where id is populated when the data is saved.
$('#btnNextstep').show();
}
}
One way is to change the status code from controller action (500 internal server error). if there is a validation error and then you can hide button hiding functionality in onError callback of Ajax.BeginForm. For further detail on this approach pls visit http://zahidadeel.blogspot.com/2011/07/server-side-validation-with-aspnet-mvc.html . if you don't do it like this then you have to handle any response in success callback (be it a validation error or success). In this case you can opt to always send json from controller action like
public JsonResult test()
{
if(ModelState.IsValid)
{
return json(new{success=true, OtherData = "xyz maybe some html"});
}
return Json(new {success=false, OtherData = "some error occured"});
}
and then in onSuccess callback you have to check
if(data.Success){
//do something
}else{//hide button}

Categories

Resources