使用jQuery对话框/局部视图创建子对象

时间:2015-03-13 21:47:28

标签: jquery asp.net-mvc asp.net-mvc-5 partial-views jquery-dialog

我正在使用MVC 5 / jquery 1.10.2和jquery ui 1.11.3

对于这个例子,我有一个带有一个子对象的Parent对象。在父对象的创建视图上,我有一个自动完成的文本框,用户可以从中选择其中一个子对象。如果孩子还不存在,则有一个供用户点击的链接,打开一个包含局部视图的jQuery对话框。

我用来执行此操作的代码如下:

$(function () {
    var dialog = $("#dialog-form").dialog({
        autoOpen: false,
        width: 500,
        height: 450,
        dialogClass: "dialogStyle",
        draggable: true,
        resizable: false,
        modal: true,
        hide: { effect: "fade", duration: 1000 },
        title: "New Donor",
        open: function () {
            $(this).closest(".ui-dialog")
            .find(".ui-dialog-titlebar-close")
            //.removeclass("ui-dialog-titlebar-close")
            .html("<span class='ui-button-icon-primary ui-icon ui-icon-closethick'></span><span class='ui-button-text'>close</span>");
        }
    });

    $("#new-donor").click(function () {
        $("#dialog-form").load("@Url.Action("MinCreate", "Donors")", function () {
            dialog.dialog("open")
        });
    });
});

现在,我有两个问题:

  1. 当我成功提交部分视图表单时,我想关闭对话框并将新创建的子详细信息返回到现有的父表单中。我不知道该怎么做。
  2. 如果验证在服务器端的部分视图上失败,我希望显然将失败返回到现有对话框。目前,它将重定向到部分视图。
  3. 我的部分查看代码在这里:

    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
    
        <div class="form-horizontal">
            @Html.ValidationSummary(true, "", new { @class = "text-danger" })
            <div class="form-group">
                @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label dia-col-md-2" })
                <div class="dia-col-md-10">
                    @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
                </div>
            </div>
    
        // other data entry fields here...
    
            <div class="form-group">
                <div class="dia-col-md-offset-2 dia-col-md-10">
                    <input type="submit" value="Create" class="btn btn-default" />
                </div>
            </div>
        </div>
    }
    

    我的控制器代码在这里:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> MinCreate([Bind(Include = "Id,Name,Email,AddressLine1,City,State,PostalCode,PrimaryPhone")] Donor donor)
    {
        try
        {
            if (ModelState.IsValid)
            {
                db.Donors.Add(donor);
                await db.SaveChangesAsync();
                return RedirectToAction("Index");
            }
        }
        catch (Exception ex)
        {
            return PartialView("_Create");
        }
        return PartialView("_Create", donor);
    }
    

2 个答案:

答案 0 :(得分:0)

jQuery似乎是最好的方法; Razor ajax助手对我来说似乎总是很笨拙。

在进入那部分之前,先看看你的部分内容;如果你有一个div元素,他们的类被设置为水平形式,你在局部视图中实际上没有形式。使用Razor助手@using (Html.BeginForm(....))或使用<form name="this_form" id="this_form" method="post">

添加表单

通过正确设置表单,您可以向partialView添加一些Javascript并使用jQuery提交表单,然后在发布表单成功后,您可以执行$ .get()来更新父表单的内容如果帖子失败,请做其他事情:

var stuff = $('#this_form').serialize();
$.post(url_to_your_controller_action, stuff, function (data) {
    // do a $.get() to retrieve updated data then use jQuery to update your parent form

}).fail(function () {

    // do other stuff...
})

答案 1 :(得分:0)

好的,所以我花了几天的时间思考这个问题,而我认为 scurrie可能一直试图指引我朝这个方向发展。以下是我提出的解决方案:

  1. 我必须从父View启动所有JavaScript代码。
  2. 我在partial上使用了Ajax表单并使用了对话框&#34; Submit&#34;按键 调用$ .ajax并发送我的表单数据并定义&#34;成功&#34;事件
  3. 成功事件检查Controller的返回值以及是否 我设置retObject.success == true然后它找到了值 父表单并设置Donor名称和Id,然后关闭jQuery 对话。
  4. 如果retObject.success为null,那么我知道我已经返回了 无效的ModelState所以我将该返回值设置为对话框 使用jQuery选择器形成.html属性。
  5. 我理解下面有95%的内容,所以可能会有一些不必要的代码。如果你看到更好的东西,请告诉我!

    My Partial view(Donors / _Create.cshtml - 注意没有html提交按钮,因为我使用了jQuery对话框命令中的Submit按钮:

    @using (Ajax.BeginForm("MinCreate", "Donors", new AjaxOptions() { HttpMethod = "Post", InsertionMode = InsertionMode.Replace}, new { id = "DonorForm" })){
    <div class="form-horizontal">
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label dia-col-md-2" })
            <div class="dia-col-md-10">
                @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @id = "DonorFormName", @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
            </div>
        </div>
    
        <More Form Fields... />
    </div>
    }
    

    我的父表单(Items / Create.cshtml):

    <script>
    $(function () {
        $("#DonorName").autocomplete({
            source: '@Url.Action("Autocomplete")',
            select: function (event, ui) {
                $("#DonorId").val(ui.item.value);
                $("#DonorName").val(ui.item.label);
                return false;
            },
            focus: function (event, ui)
            {
                $("#DonorName").val(ui.item.label);
                return false;
            },
            change: function (e, ui) {
                if (!ui.item)
                {
                    $("#dialog-form").load("@Url.Action("MinCreate", "Donors")", function () {                        
                        $("#DonorFormName").val(e.target.value);
                        dialog.dialog("open");
                        $("#DonorFormEmail").focus();
                        e.target.value = "";
                    });
                }
            }
        });
    
        var dialog = $("#dialog-form").dialog({
            autoOpen: false,
            width: 500,
            height: 475,
            dialogClass: "dialogStyle",
            draggable: true,
            resizable: false,
            modal: true,
            hide: { effect: "fade", duration: 1000 },
            title: "New Donor",
            open: function () {
                $(this).closest(".ui-dialog")
                .find(".ui-dialog-titlebar-close")
                .html("<span class='ui-button-icon-primary ui-icon ui-icon-closethick'></span><span class='ui-button-text'>close</span>");
            },
            buttons: {
                Submit: function () {
                    $.ajax({
                        url: "@Url.Action("MinCreate", "Donors")",
                        type: "POST",
                        data: $("#DonorForm").serialize(),
                        success: function (data) {
                            if (data.success) {
                                $("#dialog-form").dialog("close");
                                $("#DonorId").val(data.retObject.Id);
                                $("#DonorName").val(data.retObject.Name);
                            }
                            else {
                                $("#dialog-form").html(data);
                            }
                        }
                    });
                    return false;
                },
            }
        });
    
        $("#new-donor").click(function () {
            $("#dialog-form").load("@Url.Action("MinCreate", "Donors")", function () {
                dialog.dialog("open")
            });
        });
    });
    

    @using (Html.BeginForm()) {    
    <div class="form-horizontal" id="CreateItem">
        <h4>Item</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.Donor.Name, "Donor", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Donor.Name, new { htmlAttributes = new { @class = "form-control", @id = "DonorName" } })<a href="#" id="new-donor">New Donor</a>
                @*<input name="donor" class="control-label col-md-2" data-trf-autocomplete="@Url.Action("Autocomplete")" />*@
                @Html.HiddenFor(model => model.DonorId, new { htmlAttributes = new { @id = "DonorId" } })
                @Html.ValidationMessageFor(model => model.DonorId, "", new { @class = "text-danger" })
            </div>
        </div>
    
        <More unimportant form fields... />
    
        </div>
    <div id="dialog-form"></div>
    }
    

    最后来自控制器Donors / MinCreate行动的代码:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult MinCreate([Bind(Include = "Id,Name,Email,AddressLine1,City,State,PostalCode,PrimaryPhone")] Donor donor)
    {
        try
        {
            if (ModelState.IsValid)
            {
                db.Donors.Add(donor);
                db.SaveChanges();
                var result = new { success = true, retObject = donor  };
                return Json(result, JsonRequestBehavior.DenyGet);
            }
        }
        catch (Exception ex)
        {
            return Json(new { success = false, retObject = donor });
        }
    
        return PartialView("_Create", donor);
    }
    

    我知道这里可能会有很多无用的绒毛,但我是MVC的新手,一个确切的例子就是我所需要的。所以,我希望有人认为这很有用。