Reputation: 1251
I noticed an issue when spawning a bootstrap modal using jQuery. Adding further javascript within the dynamically spawned partial view (my modal) causes a double backdrop to appear. Anyone know why this happens? I'm using jquery-1.8.2.js and Bootstrap v3.1.1. Many thanks.
App.js
$(document).ready(function () {
$('.modal-button').on('click', function (e) {
// Remove existing modals.
$('.modal').remove();
$.ajax({
url: '/Ajax/GetSearchModal/',
type: "get",
cache: false,
success: function (data) {
var modal = $(data);
$(data).modal({
backdrop: 'static',
keyboard: false,
});
}
});
});
});
The partial view (my modal)
@model MVCApp.Web.Models.ModalSearchModel
<div id="Ajax-Modal" class="modal fade" aria-hidden="true" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h3>
Select Something
</h3>
</div>
@using (Html.BeginForm(Model.Action, Model.Controller, FormMethod.Post))
{
<div class="modal-body">
@Html.HiddenFor(m => m.SelectedDropDownID, new { @class = "select-something-ddl", style = "width:100%", placeholder = "Search..." })
</div>
<div class="modal-footer">
<button type="submit" value="Continue">Continue</button>
<button type="button" value="Cancel" data-dismiss="modal">Cancel</button>
</div>
}
</div>
</div>
</div>
<script type="text/javascript">
$(document).ready(function () {
// This here causes the drop backdrop
// select2 code here
});
</script>
UPDATE
Moving the javascript from the modal to the success handler didn't work for what I'm trying to achieve. I wish to fire up the select2 drop down list. The only way I could get it to work in the success handler was with the following:
modal.on('shown.bs.modal', function () {
$('#SelectedDropDownID').select2({
ajax: {
url: '/Ajax/FetchResults/',
dataType: 'json',
delay: 250,
data: function (searchTerm) {
return { query: searchTerm };
},
results: function (data) {
return { results: data };
}
},
minimumInputLength: 2,
formatResult: formatRepo,
formatSelection: formatRepoSelection
});
});
However, there is a delay in the select2 activating because the shown event doesn't fire until the modal has completed animating into the screen. If I run the code outside of the shown event, select2 never activates.
SOLVED
Huge thanks to both Pasha Zavoiskikh and cvrebert. I had to update Bootstrap and jQuery to fixed the double backdrop. Further to Pasha's comment, appending the modal to the body before calling select2 fixed select2 not firing. Here is the complete fix:
function formatRepo(item) {
var markup = "<table class='item-result'><tr>";
if (item.text !== undefined) {
markup += "<div class='item-name' data-jtext=" + item.text + " data-jid=" + item.id + ">" + item.text + "</div>";
}
markup += "</td></tr></table>"
return markup;
}
function formatRepoSelection(item) {
return item.text;
}
$('.modal-button).on('click', function (e) {
// Delete existing modals.
$('.modal').replaceWith('');
// Get modal.
$.ajax({
url: '/Ajax/GetSearchModal/',
type: "get",
cache: false,
success: function (data) {
var modal = $(data);
$('body').append(modal);
$('#SelectedDropDownID').select2({
ajax: {
url: '/Ajax/FetchResults/',
dataType: 'json',
delay: 250,
data: function (searchTerm) {
return { query: searchTerm };
},
results: function (data) {
return { results: data };
}
},
minimumInputLength: 2,
formatResult: formatRepo,
formatSelection: formatRepoSelection
});
modal.modal({
backdrop: 'static',
keyboard: false,
});
}
});
});
Upvotes: 5
Views: 7820
Reputation: 3128
It can happen when the returned HTML contains other DOM elements besides the modal div (e.g. some comments). So the correct fix would be to replace
var modal = $(data);
with
var modal = $(data).filter('.modal');
and make sure modal.length === 1
Upvotes: 0
Reputation: 61
This is an old post i came across as this issue is still there in Bootstrap, giving my inputs to help people who come after me.
Issue - single Div with class "modal-backdrop" still remains after closing the modal.
1) Add class btn-close to both the close buttons:-
<div class="modal fade" id="myModal">
<div class="modal-dialog">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h4 class="modal-title">Modal Heading</h4>
<button type="button" class="close btn-close" data-dismiss="modal">×</button>
</div>
<!-- Modal body -->
<div class="modal-body">
Modal body..
</div>
<!-- Modal footer -->
<div class="modal-footer">
<button type="button" class="btn btn-danger btn-close" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
2) Add this Jquery at the bottom of the page :-
$(document).ready(function(){
$('.btn-close').click(function(){
$(".modal-backdrop").remove();
});
});
Upvotes: 2
Reputation: 11
I faced the same issue after doing some action in the modal popup and the backdrop never closes.
Task Logic:
1. Will show a popup to let user choose an image from the list of images
2. Popup modal should close after user selected an image
Added an attribute with the tag named data-dismiss="modal"
fixed the issue on selecting the image using the button.
Upvotes: 0
Reputation: 3
Problem was solved here by placing the <div>
containg the id that will be rewritten by the javascript on the Main Page, instead of the Partial View.
In your case, the Partial View containing the Modal will look like this:
@model MVCApp.Web.Models.ModalSearchModel
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h3>
Select Something
</h3>
</div>
@using (Html.BeginForm(Model.Action, Model.Controller, FormMethod.Post))
{
<div class="modal-body">
@Html.HiddenFor(m => m.SelectedDropDownID, new { @class = "select-something-ddl", style = "width:100%", placeholder = "Search..." })
</div>
<div class="modal-footer">
<button type="submit" value="Continue">Continue</button>
<button type="button" value="Cancel" data-dismiss="modal">Cancel</button>
</div>
}
</div>
</div>
And the following div should be placed in the Main Page:
<div id="Ajax-Modal" class="modal fade" aria-hidden="true" role="dialog">
Upvotes: 0
Reputation: 8475
My two cents
For me didn't work removing the fade class
I ended doing a little hack
$(document).on("DOMNodeRemoved",".modal-backdrop",function(){
$(".modal-backdrop").remove();
});
made the trick don't know if have any consequences doing this but its working form me with class fade.
Upvotes: 1