【问题标题】:Create child object using jQuery dialog/partial view使用 jQuery 对话框/局部视图创建子对象
【发布时间】:2015-03-17 23:16:20
【问题描述】:

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

对于这个例子,我有一个父对象和一个子对象。在为父对象创建视图上,我有一个自动完成文本框,用户可以从中选择其中一个子对象。如果孩子还不存在,用户可以点击一个链接打开一个包含部分视图的 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. 如果在服务器端的部分视图上验证失败,我显然想将失败返回到现有对话框。目前它会重定向到局部视图。

我的部分视图代码在这里:

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

【问题讨论】:

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


    【解决方案1】:

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

    在进入那部分之前,先看看你的部分;虽然您有一个 div 元素的类设置为 form-horizo​​ntal,但您实际上在局部视图中没有 form。使用 Razor 助手 @using (Html.BeginForm(....)) 或使用 &lt;form name="this_form" id="this_form" method="post"&gt; 添加表单

    正确设置表单后,您可以在 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...
    })
    

    【讨论】:

      【解决方案2】:

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

      1. 我必须从父视图启动所有 JavaScript 代码。
      2. 我在局部使用了 Ajax 表单并使用了对话框“提交”按钮 调用 $.ajax 并发送我的表单数据并定义一个“成功”事件。
      3. 成功事件检查来自控制器的返回值,如果 我设置了 retObject.success == true 然后它找到了 父窗体并设置捐助者名称和 ID,然后我关闭 jQuery 对话。
      4. 如果 retObject.success 为空,那么我知道我已经返回 Invalid ModelState 所以我将该返回值设置为对话框 使用 jQuery 选择器形成 .html 属性。

      我大概了解下面 95% 的情况,所以可能会有一些不必要的代码。如果您发现有更好的地方,请告诉我!

      我的部分视图(Donors/_Create.cshtml - 注意没有 html 提交按钮,因为我正在使用 jQuery 对话框命令中的提交按钮:

      @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 的新手,我确实需要一个确切的例子。所以,我希望有人觉得这很有用。

      【讨论】:

        猜你喜欢
        • 2012-05-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多