Sunday, June 2, 2024
 Popular · Latest · Hot · Upcoming
158
rated 0 times [  162] [ 4]  / answers: 1 / hits: 39746  / 10 Years ago, thu, august 7, 2014, 12:00:00

I've been using jQueryUI for a long time now but have recently made the switch to Bootstrap for aesthetic reasons. I am now struggling with what I would expect to be a simple issue and wondered if it's something that others more familiar with Bootstrap can help me with.



I have a generic function for creating dialogs on-the-fly and there are occasions where I show a dialog with no buttons (when processing something), and then swap it to a dialog that does have buttons (process complete - click OK, for example). I'm not trying to define a set process here so I'm basically saying I want to be able to close one dialog and open another whenever needed. This is where the problem comes in.



With Bootstrap the dialogs animate in and out, and I like that and want to keep it. I don't want to do it when swapping dialogs though. I can do this by removing the class fade from the first dialog when it shows, and from the second dialog before it shows, and that works great. I then add the class to the second dialog so that it will animate out. However, the animation goes wrong when I do this and there's an ugly flash where the background div should fade out gently.



I've put together a jsfiddle to demonstrate the issue. You can click the close button on the first dialog to see what the fade out animation should look like.



Any help would be appreciated before I start digging into the Bootstrap source files.



http://jsfiddle.net/ArchersFiddle/0302gLav/1/



tl;dr



Look at the jsfiddle - click show dialog 2 - click ok. I want to get rid of the black flash at the end.



CSS



@import url(//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css);
.modal {
display: none;
}


HTML



<div id=dialog1 class=modal fade>
<div class=modal-dialog>
<div class=modal-content>
<div class=modal-header>
<h4 class=modal-title>Modal Dialog 1</h4>
</div>
<div class=modal-body>This is the first modal dialog</div>
<div class=modal-footer>
<button type=button id=dialog-ok class=btn btn-default>Show dialog 2</button>
<button type=button id=dialog-close class=btn btn-default data-dismiss=modal>Close</button>
</div>
</div>
</div>
</div>

<div id=dialog2 class=modal>
<div class=modal-dialog>
<div class=modal-content>
<div class=modal-header>
<h4 class=modal-title>Modal Dialog 2</h4>
</div>
<div class=modal-body>This is the second modal dialog</div>
<div class=modal-footer>
<button type=button class=btn btn-default data-dismiss=modal>OK</button>
</div>
</div>
</div>
</div>


JavaScript



function showDialog2() {
$(#dialog1).removeClass(fade).modal(hide);
$(#dialog2).modal(show).addClass(fade);
}

$(#dialog1).modal(show);

$(#dialog-ok).on(click, function() {
showDialog2();
});

More From » jquery

 Answers
32

Okay, I don't like to answer my own question, but I've got a solution that is 100% foolproof (as far as I can tell). I've ended up going for a solution that checks for an existing dialog and modifies that, rather than hiding it and showing a new one.



Here's a working jsfiddle (using echo in the ajax call where it normally loads a html template)...



http://jsfiddle.net/ArchersFiddle/0302gLav/9/



The code is part of a larger library I'm working on, but I'll post it here anyway as it may well prove useful to others.



JavaScript Library



(function () {

var _defaultOptions = {
backdrop: static,
close: true,
keyboard: true
};

window.bootstrap = {
modal: {
show: function (options) {

options = $.extend(_defaultOptions, options);

var buttonText = ;

for (var key in options.buttons) {

options.buttons[key].id = button_ + key.split( ).join();

var button = options.buttons[key];

buttonText += <button type=button +
id= + button.id + +
class=btn +
(typeof (button.class) == undefined ? btn-default : button.class) + +
(typeof (button.dismiss) == undefined ? : data-dismiss=modal ) + > +
key + </button>;
}

$.ajax({
url: templates/bootstrap-modal.html
})
.done(function (data) {
data = data
.replace({:Title}, options.title)
.replace({:Body}, options.body)
.replace({:Buttons}, buttonText);

var $modal = $(#bootstrap-modal);
var existing = $modal.length;

if (existing) {
$modal.html($(data).find(.modal-dialog));
}
else {
$modal = $(data).appendTo(body);
}

for (var key in options.buttons) {
var button = options.buttons[key];
if (typeof (button.callback) !== undefined) {
$(# + button.id).on(click, button.callback);
}
}

$modal.off(shown.bs.modal).on(shown.bs.modal, function(e) {
if (typeof(options.onshow) === function) {
options.onshow(e);
}
});

if (!existing) {
$modal.modal(options);
}

if (options.large === true) {
$modal.find(.modal-dialog).addClass(modal-lg);
}

if (options.close === false) {
$modal.find(button.close).remove();
}
});
},
hide: function (callback) {
var $modal = $(#bootstrap-modal);

if (!$modal.length) return;

$modal.on(hidden.bs.modal, function(e) {
$modal.remove();
if (typeof(callback) === function) {
callback(e);
}
});

$modal.modal(hide);
}
}
};
})();


Template HTML



<div id=bootstrap-modal class=modal fade>
<div class=modal-dialog>
<div class=modal-content>
<div class=modal-header>
<button type=button class=close data-dismiss=modal><span aria-hidden=true>&times;</span><span class=sr-only>Close</span></button>
<h4 class=modal-title>{:Title}</h4>
</div>
<div class=modal-body>{:Body}</div>
<div class=modal-footer>
{:Buttons}
</div>
</div>
</div>
</div>


Example usage:



bootstrap.modal.show({
title: Dialog Title,
body: <p>This is the dialog body and can contain any old html rubbish.</p>,
buttons: {
Close: {
dismiss: true
}
}
});


Further options explained



bootstrap.modal.show({
backdrop: true, // show the backdrop
close: true, // show the close button
keyboard: true, // allow the keyboard to close the dialog
title: Dialog Title,
body: <p>This is the dialog body and can contain any old html rubbish.</p>,
buttons: {
Button1: {
class: btn-primary, // any class you want to add to the button
dismiss: false, // does this button close the dialog?
callback: function() { // button click handler
// the button was clicked - do something here
}
},
Button2: {
// options as defined as above. You can have as many buttons as you want
}
},
onshow: function(e) {
// this will trigger when the dialog has completed the show animation
}
});


and



bootstrap.modal.hide(function(e) {
// this will trigger when the dialog has completed the hide animation
});


All the options in the show() method are optional, but obviously you'll want a title and a body.


[#69871] Tuesday, August 5, 2014, 10 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
johnnaj

Total Points: 490
Total Questions: 109
Total Answers: 104

Location: Zambia
Member since Thu, Jun 25, 2020
4 Years ago
johnnaj questions
Wed, May 4, 22, 00:00, 2 Years ago
Wed, Sep 22, 21, 00:00, 3 Years ago
Thu, May 20, 21, 00:00, 3 Years ago
Thu, Oct 8, 20, 00:00, 4 Years ago
;