Skip to content

Commit

Permalink
Merge pull request #146 from xfra35/issue146
Browse files Browse the repository at this point in the history
New: closeExisting property (aka "multiple instances", fix #101)
  • Loading branch information
kylefox committed Mar 17, 2016
2 parents f5dbf0e + 9bdeb0f commit 7279b21
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 47 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
<a name="0.7.0"></a>
# 0.7.0 (2016-03-17)


### NEW

* Added a demo for closeExisting ([b311bb5](https://github.com/kylefox/jquery-modal/commit/b311bb5))
* CSS tweak: removed opacity on .behind > .modal ([35db0c4](https://github.com/kylefox/jquery-modal/commit/35db0c4))
* Updated README.md ([c87c3e4](https://github.com/kylefox/jquery-modal/commit/c87c3e4))
* NEW: closeExisting property ([c6c767e](https://github.com/kylefox/jquery-modal/commit/c6c767e))

* Update index.html ([f5dbf0e](https://github.com/kylefox/jquery-modal/commit/f5dbf0e))
* important lynx ([c7af630](https://github.com/kylefox/jquery-modal/commit/c7af630))
* Update README.md ([a57aee4](https://github.com/kylefox/jquery-modal/commit/a57aee4))


<a name="0.6.1"></a>
## 0.6.1 (2016-01-20)

Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ Use `$.modal.isActive()` to check if a modal is currently being displayed.
These are the supported options and their default values:

$.modal.defaults = {
closeExisting: true, // Close existing modals. Set this to false if you need to stack multiple modal instances.
escapeClose: true, // Allows the user to close the modal by pressing `ESC`
clickClose: true, // Allows the user to close the modal by clicking the overlay
closeText: 'Close', // Text content for the close <a> tag.
Expand All @@ -188,9 +189,9 @@ The following events are triggered on the modal element at various points in the

The first and only argument passed to these event handlers is the `modal` object, which has three properties:

modal.elm; // Original jQuery object upon which modal() was invoked.
modal.$elm; // Original jQuery object upon which modal() was invoked.
modal.options; // Options passed to the modal.
modal.blocker; // The overlay element.
modal.$blocker; // The overlay element.

So, you could do something like this:

Expand Down
40 changes: 39 additions & 1 deletion examples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,17 @@ <h2>Example 5: the un-closable window</h2>

<h2>Example 6: Multiple Modals</h2>

<p>This <a href="#ex6-1" rel="modal:open">example</a> shows how only one modal can be open at a time. If you open a new modal while an existing modal is open, the existing modal is closed first. If you need to manage state (ie: for step by step wizards) you'll need to do that yourself.</p>
<p>
This <a href="#ex6-1" rel="modal:open">example</a> shows how only one modal can be open at a time. If you open a new modal while an existing modal is open, the existing modal is closed first.
If you need to stack multiple modals at the same time, just set the <code>closeExisting</code> option to <code>false</code>.
See an example <a href="#ex6-1b" rel="modal:open">here</a>.
</p>

<pre><code>
$('#sub-modal').modal({
closeExisting: false
});
</pre></code>

<div class="modal" id="ex6-1" style="display:none;">
<p>I'm the first modal. <a href="#ex6-2" rel="modal:open">Open second modal...</a></p>
Expand All @@ -206,6 +216,27 @@ <h2>Example 6: Multiple Modals</h2>
<p>I'm the third modal. You get the idea.</p>
</div>

<div class="modal" id="ex6-1b" style="display:none;">
<p>I'm the first modal. <a href="#ex6-2b">Open second modal...</a></p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>

<div class="modal" id="ex6-2b" style="display:none;">
<p>I'm the second modal. <a href="#ex6-3b">Open third modal...</a></p>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>

<div class="modal" id="ex6-3b" style="display:none;">
<p>I'm the third modal. You get the idea.</p>
</div>

<hr />

<h2>Example 7: Fade Transitions</h2>
Expand Down Expand Up @@ -349,6 +380,13 @@ <h2>Example 10: Custom Class for Close Button</h2>
});
});

$('a[href="#ex6-2b"],a[href="#ex6-3b"]').click(function(event) {
event.preventDefault();
$(this).modal({
closeExisting: false
});
});

$('a[href="#ex7"]').click(function(event) {
event.preventDefault();
$(this).modal({
Expand Down
3 changes: 3 additions & 0 deletions jquery.modal.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

98 changes: 57 additions & 41 deletions jquery.modal.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,34 @@
/*
A simple jQuery modal (http://github.com/kylefox/jquery-modal)
Version 0.6.1
Version 0.7.0
*/
(function($) {

var current = null;
var modals = [],
getCurrent = function() {
return modals.length ? modals[modals.length - 1] : null;
},
selectCurrent = function() {
var i,
selected = false;
for (i=modals.length-1; i>=0; i--) {
if (modals[i].$blocker) {
modals[i].$blocker.toggleClass('current',!selected).toggleClass('behind',selected);
selected = true;
}
}
};

$.modal = function(el, options) {
$.modal.close(); // Close any open modals.
var remove, target;
this.$body = $('body');
this.options = $.extend({}, $.modal.defaults, options);
this.options.doFade = !isNaN(parseInt(this.options.fadeDuration, 10));
this.$blocker = null;
if (this.options.closeExisting)
while ($.modal.isActive())
$.modal.close(); // Close any open modals.
modals.push(this);
if (el.is('a')) {
target = el.attr('href');
//Select element by id from href
Expand All @@ -28,15 +45,18 @@
this.showSpinner();
el.trigger($.modal.AJAX_SEND);
$.get(target).done(function(html) {
if (!current) return;
if (!$.modal.isActive()) return;
el.trigger($.modal.AJAX_SUCCESS);
var current = getCurrent();
current.$elm.empty().append(html).on($.modal.CLOSE, remove);
current.hideSpinner();
current.open();
el.trigger($.modal.AJAX_COMPLETE);
}).fail(function() {
el.trigger($.modal.AJAX_FAIL);
var current = getCurrent();
current.hideSpinner();
modals.pop(); // remove expected modal from the list
el.trigger($.modal.AJAX_COMPLETE);
});
}
Expand All @@ -52,55 +72,54 @@

open: function() {
var m = this;
this.block();
if(this.options.doFade) {
this.block();
setTimeout(function() {
m.show();
}, this.options.fadeDuration * this.options.fadeDelay);
} else {
this.block();
this.show();
}
if (this.options.escapeClose) {
$(document).on('keydown.modal', function(event) {
if (event.which == 27) $.modal.close();
});
}
if (this.options.clickClose) this.blocker.click(function(e){
if (e.target==this)
$.modal.close();
$(document).off('keydown.modal').on('keydown.modal', function(event) {
var current = getCurrent();
if (event.which == 27 && current.options.escapeClose) current.close();
});
if (this.options.clickClose)
this.$blocker.click(function(e) {
if (e.target==this)
$.modal.close();
});
},

close: function() {
modals.pop();
this.unblock();
this.hide();
$(document).off('keydown.modal');
if (!$.modal.isActive())
$(document).off('keydown.modal');
},

block: function() {
this.$elm.trigger($.modal.BEFORE_BLOCK, [this._ctx()]);
this.blocker = $('<div class="jquery-modal blocker"></div>');
this.$body.css('overflow','hidden');
this.$body.append(this.blocker);
this.$blocker = $('<div class="jquery-modal blocker current"></div>').appendTo(this.$body);
selectCurrent();
if(this.options.doFade) {
this.blocker.css('opacity',0).animate({opacity: 1}, this.options.fadeDuration);
this.$blocker.css('opacity',0).animate({opacity: 1}, this.options.fadeDuration);
}
this.$elm.trigger($.modal.BLOCK, [this._ctx()]);
},

unblock: function() {
if(this.options.doFade) {
var self=this;
this.blocker.fadeOut(this.options.fadeDuration, function() {
self.blocker.children().appendTo(self.$body);
self.blocker.remove();
self.$body.css('overflow','');
});
} else {
this.blocker.children().appendTo(this.$body);
this.blocker.remove();
this.$body.css('overflow','');
unblock: function(now) {
if (!now && this.options.doFade)
this.$blocker.fadeOut(this.options.fadeDuration, this.unblock.bind(this,true));
else {
this.$blocker.children().appendTo(this.$body);
this.$blocker.remove();
this.$blocker = null;
selectCurrent();
if (!$.modal.isActive())
this.$body.css('overflow','');
}
},

Expand All @@ -110,8 +129,7 @@
this.closeButton = $('<a href="#close-modal" rel="modal:close" class="close-modal ' + this.options.closeClass + '">' + this.options.closeText + '</a>');
this.$elm.append(this.closeButton);
}
this.$elm.addClass(this.options.modalClass + ' current');
this.$elm.appendTo(this.blocker);
this.$elm.addClass(this.options.modalClass).appendTo(this.$blocker);
if(this.options.doFade) {
this.$elm.css('opacity',0).show().animate({opacity: 1}, this.options.fadeDuration);
} else {
Expand All @@ -123,8 +141,6 @@
hide: function() {
this.$elm.trigger($.modal.BEFORE_CLOSE, [this._ctx()]);
if (this.closeButton) this.closeButton.remove();
this.$elm.removeClass('current');

var _this = this;
if(this.options.doFade) {
this.$elm.fadeOut(this.options.fadeDuration, function () {
Expand Down Expand Up @@ -152,25 +168,25 @@

//Return context for custom events
_ctx: function() {
return { elm: this.$elm, blocker: this.blocker, options: this.options };
return { elm: this.$elm, $blocker: this.$blocker, options: this.options };
}
};

$.modal.close = function(event) {
if (!current) return;
if (!$.modal.isActive()) return;
if (event) event.preventDefault();
var current = getCurrent();
current.close();
var that = current.$elm;
current = null;
return that;
return current.$elm;
};

// Returns if there currently is an active modal
$.modal.isActive = function () {
return current ? true : false;
return modals.length > 0;
}

$.modal.defaults = {
closeExisting: true,
escapeClose: true,
clickClose: true,
closeText: 'Close',
Expand Down Expand Up @@ -198,7 +214,7 @@

$.fn.modal = function(options){
if (this.length === 1) {
current = new $.modal(this, options);
new $.modal(this, options);
}
return this;
};
Expand Down
4 changes: 2 additions & 2 deletions jquery.modal.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "jquery-modal",
"version": "0.6.1",
"version": "0.7.0",
"main": "jquery.modal.js",
"style": "jquery.modal.css",
"description": "The simplest possible modal for jQuery",
Expand Down

0 comments on commit 7279b21

Please # to comment.