How to make a .NET MVC Form inside a Modal using jQuery with validation

杀马特。学长 韩版系。学妹 提交于 2019-11-28 03:51:37

You can use the built-in MVC validation scripts along with the data annotaions on your model

public class AccountProfileEditViewModel
{
    [Display(Name = "Address")]
    [Required()]
    [StringLength(200)]
    public string Address { get; set; }
}

Make a partial view to hold your modal form.

_AccountProfileEdit.cshtml

@model AccountProfileEditViewModel

@using(Html.BeginForm("AccountProfileEdit", "Account",
           FormMethod.Post, new { id = "form-accountedit-appt" }) {
    @Html.ValidationSummary(true)

    @Html.LabelFor(m => m.Address)
    @Html.TextBoxFor(m => m.Address)
    @Html.ValidationMessageFor(m => m.Address)
    <button type="submit">Edit</button>
}

Then reference this in your modal box. If you want pre-populated model you'll need to render an action:

<div class="modal-body" id="form-container">
    @Html.Action("AccountProfileEdit", "Account", new { id=account.Id })
</div>

If you just want a blank form then you can just use:

<div class="modal-body" id="form-container">
    @Html.Partial("_AccountProfileEdit")
</div>

The action uses the id parameter to fetch and populate the model

[HttpGet]
public ActionResult AccountProfileEdit(int id)
{
    AccountProfileEditViewModel model = db.GetAccount(id);  // however you do this in your app

    return PartialView("_AccountProfileEdit", model);
}

AJAX POST

Now you'll need AJAX to submit this form. If you rely on a standard form submission the browser will navigate away from your page (and close your modal).

$("#myModal").on("submit", "#form-accountedit", function(e) {
    e.preventDefault();  // prevent standard form submission

    var form = $(this);
    $.ajax({
        url: form.attr("action"),
        method: form.attr("method"),  // post
        data: form.serialize(),
        success: function(partialResult) {
            $("#form-container").html(partialResult);
        }
    });
});

You need to use the event delegate $(staticParent).on(event, target, handler) for the submit event because the form content may be replaced later.

Post Action

[HttpPost]
public ActionResult AccountProfileEdit(AccountProfileEditViewModel model)
{
    // Request.Form is model

    if (ModelState.IsValid)
    {
        // do work
        return PartialView("_AccountEditSuccess");
    }

    return PartialView("_AccountProfileEdit", model);
}

Client-side validation scripts should prevent them from ever submitting. But if that somehow failed or if you can't validate something on the client then you have ModelState.IsValid. You might also invalidate something server-side manually.

_AccountEditSuccess.cshtml

And the "success" partial view.

<div>Success! <button>Click to close</button></div>

Not Valid is a Fail, Right?

From your AJAX success handler you have

success: function(partialResult) {
    $("#form-container").html(partialResult);
}

But the problem here is we don't know if you are getting a "success" or "validation failure". Adding an error: function(err){ } handler won't help because the validation failure is considered a HTTP 200 response. In both cases the div content is replaced the user will need to manually close the modal. There are ways to pass additional data to distinguish both conditions but that's another long answer post.

Consider put an iframe inside the modal div, instead of rendering partialView, this way you can develop the modal section the same way you develop simple pages, which submit, model, required etc...

this way:

<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog modalAE" role="document">
    <div class="modal-content">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
            <h3><strong>Edit Account Profile - <span class="accountname"></span></strong></h3>
        </div>
            <div class="modal-body">
          <iframe src='myApp/AccountProfileEdit'/>
        </div>
        <div class="modal-footer">
            <button type="submit" id="accountprofileedit-submit" name="accountprofileedit-submit" value="Edit Account" class="btn btn-primary" style="margin-left:5px;">Edit Account</button>
            <button type="button" class="btn btn-primary" data-dismiss="modal">Cancel</button>
        </div>
        }
    </div>
</div>

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!