Validate JQuery UI modal form within another form

2019-03-22 07:03发布

I have a form in MVC 4 which contains several fields and, depending on the value of a combo, I need to open a modal dialog form and load into that one 3 additional fields that will impact against the same entity that I'm creating/editing in the main form. For this modal dialog I'm using the one from jQuery UI.

Now, what I need to do is to validate (Required) the fields within the modal dialog in order to allow the user to retain the entered values which will be submited later by the main form.

My problem is how to perform the validation of those 3 fields from within the modal form (because they wouldn't be able to submit the main form until dialog is closed).

Any hints or ideas?

Regards, Cesar.

1条回答
▲ chillily
2楼-- · 2019-03-22 07:22

You could use AJAX to submit the form modal to the server. The modal form will have of course a separate view model associated with it. Let's exemplify:

Main view model:

public class MyViewModel
{
    [DisplayName("select a value")]
    public string SelectedValue { get; set; }
    public IEnumerable<SelectListItem> Values { get; set; }
    public string SomeOtherProperty { get; set; }
}

Modal dialog view model:

public class DialogViewModel
{
    [Required]
    public string Prop1 { get; set; }
    [Required]
    public string Prop2 { get; set; }
    [Required]
    public string Prop3 { get; set; }
}

Then you could have a controller containing 4 actions:

public class HomeController : Controller
{
    // Renders the main form
    public ActionResult Index()
    {
        var model = new MyViewModel
        {
            Values = new[]
            {
                new SelectListItem { Value = "1", Text = "item 1" },
                new SelectListItem { Value = "2", Text = "item 2" },
                new SelectListItem { Value = "3", Text = "item 3" },
            }
        };
        return View(model);
    }

    // Processes the submission of the main form
    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        return Content(
            string.Format(
                "Thanks for filling out the form. You selected value: \"{0}\" and other property: \"{1}\"",
                model.SelectedValue,
                model.SomeOtherProperty
            )
        );
    }

    // Renders the partial view which will be shown in a modal
    public ActionResult Modal(string selectedValue)
    {
        var model = new DialogViewModel
        {
            Prop1 = selectedValue
        };
        return PartialView(model);
    }

    // Processes the submission of the modal
    [HttpPost]
    public ActionResult Modal(DialogViewModel model)
    {
        if (ModelState.IsValid)
        {
            // validation of the modal view model succeeded =>
            // we return a JSON result containing some precalculated value
            return Json(new
            {
                value = string.Format("{0} - {1} - {2}", model.Prop1, model.Prop2, model.Prop3)
            });
        }

        // Validation failed => we need to redisplay the modal form
        // and give the user the possibility to fix his errors
        return PartialView(model);
    }
}

Next you could have a main view (~/Views/Home/Index.cshtml):

@model MyViewModel

@using (Html.BeginForm())
{
    <div>
        @Html.LabelFor(x => x.SelectedValue)
        @Html.DropDownListFor(x => x.SelectedValue, Model.Values, new { id = "ddl" })
    </div>
    <div>
        @Html.LabelFor(x => x.SomeOtherProperty)
        @Html.TextBoxFor(x => x.SomeOtherProperty, new { id = "otherProperty" })
        @Html.ActionLink(
            "click here to open a modal and help you fill the value",
            "Modal",
            "Home",
            null,
            new { id = "showModal" }
        )
    </div>
    <button type="submit">OK</button>
}

<div id="modal"></div>

and a partial view to contain the modal form (~/Views/Home/Modal.cshtml):

@model DialogViewModel

@using (Ajax.BeginForm(new AjaxOptions { OnSuccess = "handleModalSubmit" }))
{
    <div>
        @Html.LabelFor(x => x.Prop1)
        @Html.EditorFor(x => x.Prop1)
        @Html.ValidationMessageFor(x => x.Prop1)
    </div>
    <div>
        @Html.LabelFor(x => x.Prop2)
        @Html.EditorFor(x => x.Prop2)
        @Html.ValidationMessageFor(x => x.Prop2)
    </div>
    <div>
        @Html.LabelFor(x => x.Prop3)
        @Html.EditorFor(x => x.Prop3)
        @Html.ValidationMessageFor(x => x.Prop3)
    </div>
    <button type="submit">OK</button>
}

OK, now all that's left is write some javascript to make the whole thing alive. We start by making sure that we have included all the required scripts first:

<script src="@Url.Content("~/Scripts/jquery-1.7.1.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery-ui-1.8.20.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>

and then write our own:

$(function () {
    $('#showModal').click(function () {
        $.ajax({
            url: this.href,
            type: 'GET',
            cache: false,
            data: { selectedValue: $('#ddl').val() },
            success: function (result) {
                $('#modal').html(result).dialog('open');
            }
        });
        return false;
    });

    $('#modal').dialog({
        autoOpen: false,
        modal: true
    });
});

function handleModalSubmit(result) {
    if (result.value) {
        // JSON returned => validation succeeded => 
        // close the modal and update some property on the main form
        $('#modal').dialog('close');
        $('#otherProperty').val(result.value);
    } else {
        // validation failed => refresh the modal to display the errors
        $('#modal').html(result);
    }
}
查看更多
登录 后发表回答