Search code examples
c#jqueryasp.net-mvctwitter-bootstraptwitter-bootstrap-2

Twitter Bootstrap modal does not work properly when implementing in asp.net mvc


I have integrated twitter bootstrap modal in MVC using partial view but it does not work properly, some part of the modal popup is there on the parent screen before i load the modal by clicking on the create button and after closing the modal pop up modal pop up content is shown on the parent screen without any css. I want to use it for editing data. Below is the working code. Please help to solve this issue. Thanks..

_Create.cshtml (Partial View)

@using MvcTwitterBootstrap.Models
@model MyViewModel


<div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
    <h3 id="myModalLabel">Create Foo Bar</h3>
</div>

@using (Html.BeginForm("Create", "Home", FormMethod.Post, new { @class = "modal-form" }))
{
@Html.ValidationSummary()

<div class="modal-body">
    <div>
        @Html.LabelFor(x => x.Foo)
        @Html.EditorFor(x => x.Foo)
        @Html.ValidationMessageFor(x => x.Foo)
    </div>
    <div>
        @Html.LabelFor(x => x.Bar)
        @Html.EditorFor(x => x.Bar)
        @Html.ValidationMessageFor(x => x.Bar)
    </div>
</div>

<div class="modal-footer">
    <button class="btn" data-dismiss="modal" aria-hidden="true">Undo</button>
    <button class="btn btn-primary" type="submit">Save</button>
</div>
}

Index.cshtml

<link href="@Url.Content("~/bootstrap/css/bootstrap.min.css")" rel="stylesheet" type="text/css" />
<script src="@Url.Content("~/bootstrap/js/bootstrap.min.js")" type="text/javascript"></script>
@Html.ActionLink("Create", "Create", null, null, new { id = "btnCreate", @class = "btn btn-small btn-info" })
<div id='dialogDiv' class='modal fade in'>
    <div id='dialogContent'>
    </div>
</div>
<script type="text/javascript">
    $(function () {

        //Optional: turn the chache off
        $.ajaxSetup({ cache: false });

        $('#btnCreate').click(function () {
            $('#dialogContent').load(this.href, function () {
                $('#dialogDiv').modal({
                    backdrop: 'static',
                    keyboard: true
                }, 'show');
                bindForm(this);
            });
            return false;
        });
    });

    function bindForm(dialog) {
        $('form', dialog).submit(function () {
            $.ajax({
                url: this.action,
                type: this.method,
                data: $(this).serialize(),
                success: function (result) {
                    if (result.success) {
                        $('#dialogDiv').modal('hide');
                        // Refresh:
                        // location.reload();
                    } else {
                        $('#dialogContent').html(result);
                        bindForm();
                    }
                }
            });
            return false;
        });
    }

</script>

HomeController

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcTwitterBootstrap.Models;

namespace MvcTwitterBootstrap.Controllers
{
    public class HomeController : Controller
    {
        //
        // GET: /Home/
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Create()
        {
            return PartialView("_Create");
        }


        [HttpPost]
        public ActionResult Create(MyViewModel model)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    SaveChanges(model);
                    return Json(new { success = true });
                }
                catch (Exception e)
                {
                    ModelState.AddModelError("", e.Message);
                }

            }
            //Something bad happened
            return PartialView("_Create", model);
        }


        static void SaveChanges(MyViewModel model)
        {
            // Uncommment next line to demonstrate errors in modal
            //throw new Exception("Error test");
        }

    }
}

Solution

  • Why to have two action calls. You can try this way

    Index.cshtml

    <link href="@Url.Content("~/bootstrap/css/bootstrap.min.css")" rel="stylesheet" type="text/css" />
    <script src="@Url.Content("~/bootstrap/js/bootstrap.min.js")" type="text/javascript"></script>
        <script type="text/javascript">
    
            function bindForm() {
                $.ajax({
                    url: "/Home/Create",
                    data: $('#createForm').serialize(),
                    type: 'post',
                    success: function (data) {
                        if (data.Success) {
                            // DO your code
                            $("#createModal").modal('hide');
                        }
                        else { //Display error message
                        }
                    },
                    error: function (xhr, status) {
                        //Display error message
                    }
                });
                return false;
            }
    
        </script>
    <a href="#" class="btn btn-primary" onclick="$('#createModal').modal('show')">Create</a>
    <div id="createModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style="display: none; margin-left: -500px; width: 70%;">
       <div class="modal-header">
           <div class="row-fluid">
               <h3 class="span11">Create Foo Bar</h3>
               <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
           </div>
       </div>
       <div class="modal-body">
           @using (Html.BeginForm("Create", "Home", FormMethod.Post, new { id="createForm", @class = "form-horizontal" }))
           { 
               @Html.ValidationSummary()
               <div class="control-group">
                   <label class="control-label">@Html.LabelFor(x => x.Foo)</label>
                   <div class="controls">
                       @Html.EditorFor(x => x.Foo)
                       @Html.ValidationMessageFor(x => x.Foo)
                   </div>
               </div>
               <div class="control-group">
                   <label class="control-label">@Html.LabelFor(x => x.Bar)</label>
                   <div class="controls">
                       @Html.EditorFor(x => x.Bar)
                       @Html.ValidationMessageFor(x => x.Bar)
                   </div>
               </div>
            }
        </div>
        <div class="modal-footer">
            <button class="btn" data-dismiss="modal" aria-hidden="true">Undo</button>
            <button class="btn btn-primary" type="submit" onclick="return bindForm()">Save</button>
        </div>
    </div>
    

    And in controller, you could remove get call for create

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using MvcTwitterBootstrap.Models;
    
    namespace MvcTwitterBootstrap.Controllers
    {
        public class HomeController : Controller
        {
            //
            // GET: /Home/
            public ActionResult Index()
            {
                return View();
            }
    
            [HttpPost]
            public ActionResult Create(MyViewModel model)
            {
                if (ModelState.IsValid)
                {
                    try
                    {
                        SaveChanges(model);
                        return Json(new { success = true });
                    }
                    catch (Exception e)
                    {
                        ModelState.AddModelError("", e.Message);
                    }
    
                }
                //Something bad happened
                return PartialView("_Create", model);
            }
    
    
            static void SaveChanges(MyViewModel model)
            {
                // Uncommment next line to demonstrate errors in modal
                //throw new Exception("Error test");
            }
    
        }
    }