18

On my MVC View I have button:

<input id="btnSave" type="submit" name="Save" value="Save" />

When I click this button I need call one Action, do some stuff there and then Submit my form.

I have this jQuery:

$('#btnSave').click(function () {    
    $.ajax({
        url: "/Home/SaveDetailedInfo",
        type: "POST",
        data: JSON.stringify({ 'Options': someData}),
        dataType: "json",
        traditional: true,
        contentType: "application/json; charset=utf-8",
        success: function (data) {
            if (data.status == "Success") {
                alert("Done");
            } else {
                alert("Error occurs on the Database level!");
            }
        },
        error: function () {
            alert("An error has occured!!!");
        }
    });
});

Then I want to submit my form. In Controller I have 2 Actions:

public ActionResult SaveDetailedInfo(Option[] Options)
{
    return Json(new { status = "Success", message = "Success" });
}

[HttpPost]
public ActionResult Save()
{ 
    return RedirectToAction("Index", "Home");
}

The problem is when I have type="submit" in my button, I can't reach SaveDetailedInfo Action, cause ajax gives me error, but when I remove type="submit", ajax works fine, but Save Action never executes.

Please, any ideas how to execute both Actions? I thought maybe after Ajax > Success try to add type=submit through jquery and use .click(), but it sounds strange to me.

Bryuk
  • 3,295
  • 10
  • 45
  • 74

3 Answers3

25

Use preventDefault() to stop the event of submit button and in ajax call success submit the form using submit():

$('#btnSave').click(function (e) {
    e.preventDefault(); // <------------------ stop default behaviour of button
    var element = this;    
    $.ajax({
        url: "/Home/SaveDetailedInfo",
        type: "POST",
        data: JSON.stringify({ 'Options': someData}),
        dataType: "json",
        traditional: true,
        contentType: "application/json; charset=utf-8",
        success: function (data) {
            if (data.status == "Success") {
                alert("Done");
                $(element).closest("form").submit(); //<------------ submit form
            } else {
                alert("Error occurs on the Database level!");
            }
        },
        error: function () {
            alert("An error has occured!!!");
        }
    });
});
Ehsan Sajjad
  • 61,834
  • 16
  • 105
  • 160
5

Assuming that your button is in a form, you are not preventing the default behaviour of the button click from happening i.e. Your AJAX call is made in addition to the form submission; what you're very likely seeing is one of

  1. the form submission happens faster than the AJAX call returns
  2. the form submission causes the browser to abort the AJAX request and continues with submitting the form.

So you should prevent the default behaviour of the button click

$('#btnSave').click(function (e) {

    // prevent the default event behaviour    
    e.preventDefault();

    $.ajax({
        url: "/Home/SaveDetailedInfo",
        type: "POST",
        data: JSON.stringify({ 'Options': someData}),
        dataType: "json",
        traditional: true,
        contentType: "application/json; charset=utf-8",
        success: function (data) {

            // perform your save call here

            if (data.status == "Success") {
                alert("Done");
            } else {
                alert("Error occurs on the Database level!");
            }
        },
        error: function () {
            alert("An error has occured!!!");
        }
    });
});
Russ Cam
  • 124,184
  • 33
  • 204
  • 266
  • Ok. Now I can reach Home/SaveDetailedInfo, but when I submit form, I can't get into Save() Action – Bryuk Jul 31 '14 at 20:48
2

Your C# action "Save" doesn't execute because your AJAX url is pointing to "/Home/SaveDetailedInfo" and not "/Home/Save".

To call another action from within an action you can maybe try this solution: link

Here's another better solution : link

[HttpPost]
public ActionResult SaveDetailedInfo(Option[] Options)
{
    return Json(new { status = "Success", message = "Success" });
}

[HttpPost]
public ActionResult Save()
{ 
    return RedirectToAction("SaveDetailedInfo", Options);
}

AJAX:

Initial ajax call url: "/Home/Save"
on success callback: 
   make new ajax url: "/Home/SaveDetailedInfo"
Community
  • 1
  • 1
TchiYuan
  • 4,258
  • 5
  • 28
  • 35
  • Action Save has the same name as Button name="Save" type="Submit", so when I click this button, I will get into [HttpPost] ActionResult Save() – Bryuk Jul 31 '14 at 20:50
  • don't use `` . try `` your javascript will trigger on btnSave click. – TchiYuan Jul 31 '14 at 20:52
  • After SaveDetailedInfo Action I need submit this form – Bryuk Jul 31 '14 at 20:52
  • Then in your ajax success callback, evaluate if data.status == "Success" then grab your form field values and build a new json object with it and do a new AJAX call. – TchiYuan Jul 31 '14 at 20:56
  • It's true, but I believe that there is better way to get into Save() ActionResult, and work with Model and other MVC Stuff – Bryuk Jul 31 '14 at 20:57