asp.net-mvc Bootstrap 模态表单在提交后不关闭
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20851165/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bootstrap modal form does not close after submit
提问by bto.rdz
What I need to do is to show a popup to add a new record to my database, im using bootstrap 3 and I love it because im not using a single line of jquery, and I have really nice form (obvioulsy they are based in jquery).
我需要做的是显示一个弹出窗口来向我的数据库添加一条新记录,我使用的是引导程序 3,我喜欢它,因为我没有使用一行 jquery,而且我的表单非常好(显然它们基于 jquery )。
I am validating my form via ajax, but the problem now is that my modal never closes, when I try to redirect to an Action the action is loaded inside my modal, so my question is how do I stop my modal?
我正在通过 ajax 验证我的表单,但现在的问题是我的模态永远不会关闭,当我尝试重定向到一个动作时,动作会加载到我的模态中,所以我的问题是如何停止我的模态?
This is an example of what this code does:
这是此代码的作用的示例:
My form:
我的表格:


My form when when validated:
验证时我的表单:


this is perfect with this code:
这是完美的这段代码:
<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">×</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 -->
and my partial:
和我的部分:
@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>
the problem now is than when model is valid in my controller I go to Index Action which is loaded inside my modal so my question again is how do I close my modal?
现在的问题是当模型在我的控制器中有效时,我转到加载在我的模态中的索引操作,所以我的问题再次是如何关闭我的模态?


here is my controller:
这是我的控制器:
public ActionResult ModalAdd(Car car)
{
if (ModelState.IsValid)
{
db.Cars.Add(car);
db.SaveChanges();
return RedirectToAction("Index");
}
return PartialView("CreatePartialView",car);
}
回答by bto.rdz
Just for the record, I found my answer hope it helps someone else, it is really hard to find a full article of this.
只是为了记录,我找到了我的答案希望它可以帮助别人,很难找到完整的文章。
I had to use more of jquery but It is a clean answer (I think).
我不得不使用更多的 jquery,但这是一个干净的答案(我认为)。
Using data annotations in my model:
在我的模型中使用数据注释:
[Required]
public string Name { get; set; }
[Required]
public string Phone { get; set; }
Then I created a partial in my shared folder that contains my modal form, so I can make it global.
然后我在我的共享文件夹中创建了一个包含我的模态表单的部分,这样我就可以将它设为全局。
@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">×</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 -->
And the script:
和脚本:
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');
}
});
}
});
});
Now all I have to do to render my form where ever I need it is to add these lines:
现在我要做的就是在我需要的地方渲染我的表单,就是添加这些行:
<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-->
}
Finally since my model was client-side validated I just add my model to my database, and redirect to Index view, while the ajax call hides active modalUpdate:I recommend to decide if redirect or hide modal at ajax call. like commented.
最后,因为我的模型是客户端验证的,所以我只是将我的模型添加到我的数据库中,然后重定向到索引视图,而 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
}
}
make sure your web.config contains:
确保您的 web.config 包含:
<appSettings>
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
Im using these scripts too:
我也使用这些脚本:
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
Please let me know if something could be better.
请让我知道是否有更好的办法。
回答by Greg Ennis
You are going to have to write some jquery - sorry
你将不得不写一些 jquery - 抱歉
@using (Ajax.BeginForm("ModalAdd", new AjaxOptions() {UpdateTargetId = "mymodalform", OnSuccess= "$('#myModal').modal('hide');"}))
But its just one line
但它只有一行
回答by Rowan Freeman
This is a pretty common fundamental problem with this approach.
这是这种方法的一个非常常见的基本问题。
What we have is an AJAX form that, if the form fails to process, then the partial is re-rendered and returned to the browser so that the original form can be replaced with the new one. If the form succeeds, you want the browser to redirect to a new page but the problem is that the browser is expecting a page returned that it can insert into the modal.
我们拥有的是一个 AJAX 表单,如果表单无法处理,则部分会重新呈现并返回到浏览器,以便原始表单可以替换为新表单。如果表单成功,您希望浏览器重定向到一个新页面,但问题是浏览器期望返回一个可以插入到模态中的页面。
The problem is that the approach is a dichotomy. That is, you need to either do a full page refresh or an AJAX request, but not both in which the appropriate logic is determined by the server.
问题是这种方法是一种二分法。也就是说,您需要执行完整页面刷新或 AJAX 请求,但不能同时执行两者,其中适当的逻辑由服务器确定。
One solution to this problem:
此问题的一种解决方案:
One thing that I can think of is to change the server's response to a Bad Request (400) when you are returning the partial to indicate that, although you are returning some HTML, the process did not complete successfully.
我能想到的一件事是在您返回部分时将服务器的响应更改为错误请求 (400),以表明尽管您正在返回一些 HTML,但该过程没有成功完成。
This means that you can take advantage of the OnFailureAjaxOption. If the result is a failure, then take the response data and insert it as normal in to the modal.
这意味着您可以利用OnFailureAjaxOption。如果结果是失败,则获取响应数据并将其正常插入到模态中。
However if the status is 200 OK then return a URL and take advantage of OnSuccessand perform a simple javascript redirect to the URL.
但是,如果状态为 200 OK,则返回一个 URL 并利用OnSuccess并执行一个简单的 JavaScript 重定向到该 URL。
回答by MrCheese
I used JavaScript to control the page redirection and reloading.
我使用 JavaScript 来控制页面重定向和重新加载。
Options which I used are:
我使用的选项是:
Return a JavaScript function to refresh the host page instead of a RedirectToAction, when the controller action is successful.
return this.Content("< script >location.reload()< /script >");
Return a JavaScript function to redirect the client to the page.
How to redirect to another webpage in JavaScript/jQuery?RedirectToAction which has the required JavaScript redirection or reloading logic within the view
当控制器操作成功时,返回一个 JavaScript 函数来刷新主机页面而不是 RedirectToAction。
return this.Content("< script >location.reload()</script >");
返回一个 JavaScript 函数以将客户端重定向到页面。
如何在 JavaScript/jQuery 中重定向到另一个网页?RedirectToAction 在视图中具有所需的 JavaScript 重定向或重新加载逻辑

