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

前端 未结 3 805
感情败类
感情败类 2020-12-07 16:47

I am really struggling with knowing how to put this all together. I\'ve built forms inside .net MVC pages plenty of times, with and without validation. And I\'ve built for

3条回答
  •  抹茶落季
    2020-12-07 17:23

    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)
        
    }
    

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

    
    

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

    
    

    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.

    Success!

    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.

提交回复
热议问题