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).
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?
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);
}
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).
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 modal Update: I recommend to decide if redirect or hide modal at ajax call. like commented.
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:
<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.
You are going to have to write some jquery - sorry
@using (Ajax.BeginForm("ModalAdd", new AjaxOptions() {UpdateTargetId = "mymodalform", OnSuccess= "$('#myModal').modal('hide');"}))
But its just one line
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With