Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bootstrap modal form does not close after submit

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:

enter image description here

My form when when validated:

enter image description here

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">&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 -->

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?

enter image description here

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);
    }
like image 819
bto.rdz Avatar asked Dec 31 '13 03:12

bto.rdz


2 Answers

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">&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 -->

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.

like image 104
bto.rdz Avatar answered Oct 03 '22 19:10

bto.rdz


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

like image 27
Greg Ennis Avatar answered Oct 03 '22 17:10

Greg Ennis