Bootstrap模态表单在提交后不会关闭

时间:2013-12-31 03:10:46

标签: asp.net-mvc modal-dialog twitter-bootstrap-3

我需要做的是显示一个弹出窗口以向我的数据库添加新记录,我使用bootstrap 3并且我喜欢它因为我没有使用单行jquery,而且我的形式非常好(显然它们是基于jquery)。

我通过ajax验证我的表单,但现在的问题是我的模态永远不会关闭,当我尝试重定向到一个Action时,动作被加载到我的模态中,所以我的问题是如何停止我的模态? / p>

这是此代码的作用示例:

我的表格:

enter image description here

验证时的表格:

enter image description here

这个代码很完美:

<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
    <div class="modal-content">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
            <h4 class="modal-title" id="myModalLabel">Add Car</h4>
        </div>
        <div class="modal-body">
            @using (Ajax.BeginForm("ModalAdd", new AjaxOptions() {UpdateTargetId = "mymodalform"}))
            {
                <div id="mymodalform">
                    @Html.Partial("CreatePartialView", new Car())
                </div>
            }
        </div>
    </div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->

和我的部分:

@model ControliBootstrap.Models.Car

    <div class="form-horizontal" >
    @Html.ValidationSummary(true)

    <div class="form-group">
        @Html.LabelFor(model => model.Model, new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Model)
            @Html.ValidationMessageFor(model => model.Model)
        </div>
    </div>

    <!--More fields-->

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default"/>
        </div>
    </div>
</div>

现在的问题是,当我的控制器中的模型有效时,我会转到我的模态中加载的索引动作,所以我的问题是如何关闭我的模态?

enter image description here

这是我的控制器:

public ActionResult ModalAdd(Car car)
    {
        if (ModelState.IsValid)
        {
            db.Cars.Add(car);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return PartialView("CreatePartialView",car);
    }

4 个答案:

答案 0 :(得分:14)

为了记录,我发现我的回答希望它可以帮助别人,很难找到完整的文章。

我不得不使用更多的jquery,但这是一个干净的答案(我认为)。

在我的模型中使用数据注释:

[Required]
public string Name { get; set; }

[Required]
public string Phone { get; set; }

然后我在包含模态表单的共享文件夹中创建了一个部分文件,因此我可以将其设置为全局。

@model Controli.Models.Provider

<!-- Modal -->
<div class="modal fade" id="mdlnewprovider" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
        @using (Html.BeginForm("Add", "Providers", FormMethod.Post, new { id = "frmnewprovider" }))
        {
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
            <h4 class="modal-title" id="myModalLabel">Nuevo Proveedor</h4>
        </div>
        <div class="modal-body">
            <div class="form-group">
                @Html.TextBoxFor(u => u.Name, new { @class = "form-control", @placeholder = HttpUtility.HtmlDecode(@Html.DisplayNameFor(u => u.Name).ToHtmlString()) })
                @Html.ValidationMessageFor(u => u.Name)
            </div>
            <!--More Textboxes and Validaton Messages-->
        </div>
        <div class="modal-footer">
            <input type="submit" value="Agregar" class="btn btn-primary" />
        </div>
        }
        </div><!-- /.modal-content -->
    </div><!-- /.modal-dialog -->
</div><!-- /.modal -->

脚本:

var frmnewprovider = $("#forms-providers-new");
$(document).ready(function () {
frmnewprovider.submit(function (e) {
    e.preventDefault();
    frmnewprovider.validate();
    if (frmnewprovider.valid()) {
        $.ajax({
            url: "/Providers/Add",
            type: "POST",
            contentType: "application/json; charset=utf-8",
            data: JSON.stringify({
                Name: frmnewprovider.find('#Name').val(),
                Phone: frmnewprovider.find('#Phone').val(),
                Email: frmnewprovider.find('#Email').val(),
                Country: frmnewprovider.find('#Country').val(),
                State: frmnewprovider.find('#State').val(),
                Address: frmnewprovider.find('#Address').val()
            }),
            success: function (result) {
                //if record was added to db, then...
                window.location.replace('/Providers/Index'); //we can redirect
                //or simply close our modal.
                //$('#mdlnewprovider').modal('hide');
            },
            error: function(result) {
                alert('error');
            }
        });
    }
});
});

现在我需要做的就是在我需要的地方渲染我的表单是添加这些行:

<button class="btn btn-primary" data-toggle="modal" data-target="#mdlnewprovider">
    Nuevo
</button>

@Html.Partial("Modals/Providers/FrmNew", new Provider())

@section scripts
{
<script src="~/Scripts/Modals/Providers/NewProvider.js"></script>
<!--Where this script is the one above-->
}

最后因为我的模型是客户端验证的我只是将我的模型添加到我的数据库,并重定向到Index视图,而ajax调用隐藏了活动模态 更新: 我建议在ajax调用时决定是重定向还是隐藏模态。喜欢评论。

    public ActionResult Add(Provider provider)
    {
        if (ModelState.IsValid) //Validate in server side too!
        {
            db.Providers.Add(provider);
            db.SaveChanges();
            return Json(new{ success = true}); //return a dummy json, you can pass what
                                               //ever parameter you need. if code reach
                                               //this point. it will always hit success 
                                               //in our ajax call
        }
    }

确保您的web.config包含:

<appSettings>
  <add key="ClientValidationEnabled" value="true" />
  <add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>

我也使用这些脚本:

<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>

如果情况好一些,请告诉我。

答案 1 :(得分:5)

你将不得不写一些jquery - 抱歉

@using (Ajax.BeginForm("ModalAdd", new AjaxOptions() {UpdateTargetId = "mymodalform", OnSuccess= "$('#myModal').modal('hide');"}))

但它只是一行

答案 2 :(得分:3)

这种方法是一个非常常见的基本问题。

我们所拥有的是一个AJAX表单,如果表单无法处理,则部分重新呈现并返回到浏览器,以便原始表单可以替换为新表单。如果表单成功,您希望浏览器重定向到新页面,但问题是浏览器期望返回的页面可以插入到模式中。

问题是该方法是dichotomy。也就是说,您需要执行整页刷新或AJAX请求,但不能同时执行服务器确定适当逻辑的两者。

解决此问题的一种方法:

我能想到的一件事是,当您返回部分指示时,更改服务器对错误请求(400)的响应,尽管您返回了一些HTML,但该过程未成功完成。

这意味着您可以利用OnFailure AjaxOption。如果结果失败,则获取响应数据并将其正常插入模态。

但是,如果状态为200 OK,则返回一个URL并利用OnSuccess并执行简单的javascript重定向到URL。

答案 3 :(得分:1)

我使用JavaScript来控制页面重定向和重新加载。

我使用的选项是:

  1. 当控制器操作成功时,返回一个JavaScript函数来刷新主页而不是RedirectToAction。

      

    返回此。内容(&#34;&lt; script&gt; location.reload()&lt; / script&gt;&#34;);

  2. 返回JavaScript函数以将客户端重定向到页面 How to redirect to another webpage in JavaScript/jQuery?

  3. RedirectToAction,在视图中具有所需的JavaScript重定向或重新加载逻辑