Dismissile
Dismissile

Reputation: 33071

Need advice on the flow of my AJAX form in MVC

I need some help/guidance in how to write the AJAX piece of my application.

I have a button that when clicked will pop up a modal dialog. On the dialog I have an Ajax form which has a text box and a button to Save the values:

@using( Ajax.BeginForm("SaveText", new AjaxOptions{ OnSuccess = "ajaxSuccess" }) )
{
    @Html.TextBoxFor(m => m.Text)

    <p>
        <input type="submit" value="Save" />
    </p> 
}

When the AJAX completes successfully I want to close the dialog and refresh a grid on my main page:

function ajaxSuccess() {
    closeDialog();
    refreshGrid();
}

I ran into problems when I tried to implement validation. I'm not really sure how to accomplish what I want. Here is my controller:

public ActionResult SaveText(SaveTextViewModel model)
{
    if( ModelState.IsValid )
    {
        return PartialView("SaveTextPartial", model);
    }

    repository.SaveText(...);

    return PartialView("SaveTextPartial");
}

Here is where I'm having difficulty: when I submit the form and there are validation errors, the controller returns a partial view but the AJAX OnSuccess method completes. I don't know how to distinguish between a success with errors and a success without errors. When I have validation errors my form closes and my grid refreshes, which is not what I want.

Does anyone have any ideas? Do I need to restructure the entire flow of my AJAX call or do it completely different?

Upvotes: 2

Views: 436

Answers (2)

kamranicus
kamranicus

Reputation: 4387

It appears like you don't need this form to work without Javascript (since you're always passing back a partial view), so why not, on success, pass back a simple JSON object?

return Json(new { success = true })

And if there's an error, return the partial view so you can replace the HTML.

Then test for it in your callback...

if (result.success) { }

That way, on success, you can close the dialog safely but on a validation error, you swap out the dialog's HTML with the HTML you received on the AJAX request.

I don't know what parameters are available for your onSuccess callback but I'm sure the response body is one of them.

Upvotes: 1

Darin Dimitrov
Darin Dimitrov

Reputation: 1038850

You could add a custom HTTP header in case of error:

public ActionResult SaveText(SaveTextViewModel model)
{
    if( !ModelState.IsValid )
    {
        // a validation error occurred
        Response.AppendHeader("X-Error", "true");
        return PartialView("SaveTextPartial", model);
    }

    repository.SaveText(...);

    return PartialView("SaveTextPartial");
}

and on the client:

function ajaxSuccess(e, status, xhr) {
    if (xhr.getResponseHeader('X-ERROR')) {
        alert('failure');
    } else {
        alert('success');
    }
}

Upvotes: 0

Related Questions