0

I have the following ajax call :

    $.ajax({
                    url: "@Url.Action("GetMatch", "Test")",
                    data: {
                        Name: $("[name='Name']").val(),
                        Surname: $("[name='Surname']").val(),
                        Email: $("[name='Email']").val(),
                    },
                    dataType: "text",
                    type: "POST",
                    success: function (data, textStatus, jqXHR) {
                        alert(data.length);
                        if (data.length <= 13){
                            SaveQuote();
                        } else {
                            alert("matche")
                            }
});

The GetMatch action in the controller is as below:

[HttpPost]
public ActionResult GetClientMatch(ClientBusinessModel contactPerson)
{
    *search for a list*
    if (list.Count > 0)
    {
        return PartialView("~/Views/Shared/Partials/_Client.cshtml", list);
    } else
        return Json(new { data = contactPerson }, JsonRequestBehavior.AllowGet);
}

What I want to do is upon success, if the list is not empty, display the partial view _Client.cshtml. This is ok. But in case the the list is empty, call another action of the controller:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CreateClient(SchoolModel school, ClientBusinessModel contactPerson, long QuotationId, long LeadId)
{
    *some aciotns*
}

The first thing is how do I test if the data returned, upon the ajax call to action GetClientMatch, is a partial View or the contactPerson? Right now, I am doing the test on the length of the data. And also how do I save the form data AND the contactPerson returned by the first ajax call?

My SaveQuote function:

function SaveQuote() {
        var obj = $('#frmSchool').serialize();
        var jsonObj = @Html.Raw(Json.Encode(Model));
        $.ajax({
                 type: "POST",
                 url: "@Url.Action("CreateClient", "Test")",
                 data: obj + "
                            Name: $("[name='Name']").val(),
                            Surname: $("[name='Surname']").val(),
                            Email: $("[name='Email']").val(),
                 success: function (data) {
                     $('#ProductInformation').html(data);
                 },
                 error: function (xhr, status, error) {
                     alert(error);
                 }
             });
    }

How can I hit the controller action with the form data and the contactPerson model when the list returned in the first ajax call is empty?

refresh
  • 1,319
  • 2
  • 20
  • 71
  • Hint: You need to use `serializeArray()` instead of `serialize()` to be able to push additional data. The pushed data can still be posted with same way as `serialize()` one. – Tetsuya Yamamoto Aug 10 '18 at 11:56
  • @TetsuyaYamamoto : How can I use serializeArray() for the form data and the model? – refresh Aug 10 '18 at 11:59
  • Simply use `var obj = $('#frmSchool').serializeArray();` and use series of `obj.push()` methods to append additional data. Then use `data` property in AJAX call like `data: obj`. – Tetsuya Yamamoto Aug 10 '18 at 12:02

1 Answers1

0

Instead of using serialize() to serialize the form, you need to use serializeArray() which enables pushing additional data before assigning to AJAX callback like the following example (see related issue here):

function SaveQuote() {
    var obj = $('#frmSchool').serializeArray();

    // pushing additional data to existing array
    obj.push({ name: "Name", value: $("[name='Name']").val() });
    obj.push({ name: "Surname", value: $("[name='Surname']").val() });
    obj.push({ name: "Email", value: $("[name='Surname']").val() });

    var jsonObj = @Html.Raw(Json.Encode(Model));
    $.ajax({
        type: "POST",
        url: "@Url.Action("CreateClient", "Test")",
        data: obj,
        success: function (data) {
            $('#ProductInformation').html(data);
        },
        error: function (xhr, status, error) {
            alert(error);
        }
    });
}

Additionally, if you want to check if the response returns partial view or JSON response containing contactPerson, put an if-condition to check existence of specified object key:

Controller

[HttpPost]
public ActionResult GetClientMatch(ClientBusinessModel contactPerson)
{
    // *search for a list*
    if (list.Count > 0)
    {
        return PartialView("~/Views/Shared/Partials/_Client.cshtml", list);
    } 
    else
    {
        // key name intentionally changed for disambiguation
        return Json(new { contact = contactPerson }, JsonRequestBehavior.AllowGet);
    }
}

jQuery

function SaveQuote() {
    var obj = $('#frmSchool').serializeArray();
    obj.push({ name: "Name", value: $("[name='Name']").val() });
    obj.push({ name: "Surname", value: $("[name='Surname']").val() });
    obj.push({ name: "Email", value: $("[name='Surname']").val() });

    var jsonObj = @Html.Raw(Json.Encode(Model));
    $.ajax({
        type: "POST",
        url: "@Url.Action("CreateClient", "Test")",
        data: obj,
        success: function (data) {
            // check if contact person exists
            if (data.contact == undefined) {
                // returns partial view
                $('#ProductInformation').html(data);
            }
            else {
                // call another action here, e.g. create client function
                createClient(data.contact, ...);
            }
        },
        error: function (xhr, status, error) {
            alert(error);
        }
    });
}

The method to call another action depends on action attribute set in that action (GET/POST method) and required parameters to pass with that action.

Tetsuya Yamamoto
  • 24,297
  • 8
  • 39
  • 61