Created
April 14, 2014 18:17
-
-
Save rachelbaker/10671070 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* --------------------------------------------------------------------- | |
Modal Base JavaScript | |
Target Browsers: All | |
Author: Rachel Baker | |
------------------------------------------------------------------------ */ | |
// Namespace Object | |
var APP = APP || {}; | |
// Pass reference to jQuery and Namespace | |
(function($, APP) { | |
"use strict"; | |
// DOM Ready Function | |
$(function() { | |
APP.TheModal = new APP.Modal(); | |
APP.TheModal.init(); | |
}); | |
/* --------------------------------------------------------------------- | |
Modal Base | |
Author: Rachel Baker | |
------------------------------------------------------------------------ */ | |
APP.Modal = (function() { | |
var Modal = function() { | |
this.$modalOverlay = null; | |
this.$modalWrapper = null; | |
this.$modalContent = null; | |
this.$modalClose = null; | |
this.$body = null; | |
this.modalOffset = {}; | |
this.$currentContent = null; | |
}; | |
Modal.MODAL_OVERLAY_ID = 'js-modalOverlay'; | |
Modal.MODAL_WRAPPER_ID = 'js-modalWrapper'; | |
Modal.MODAL_CONTENT_ID = 'js-modalContent'; | |
Modal.MODAL_CLOSE_ID = 'js-modalClose'; | |
Modal.prototype.init = function() { | |
this.$body = $('body'); | |
this.ensureModalExistance(); | |
this.setOffsets(); | |
}; | |
Modal.prototype.enableClose = function() { | |
var self = this; | |
this.$modalClose.on('click', function(e) { | |
e.preventDefault(); | |
self.closeModal(); | |
}); | |
this.$modalOverlay.on('click', function(e) { | |
e.preventDefault(); | |
self.closeModal(); | |
}); | |
$(document).on('keyup', function(e) { | |
if (e.keyCode == 27) { | |
self.closeModal(); | |
} | |
}); | |
}; | |
Modal.prototype.disableClose = function() { | |
this.$modalClose.off('click'); | |
this.$modalOverlay.off('click'); | |
$(document).off('keyup'); | |
}; | |
Modal.prototype.ensureModalExistance = function() { | |
// add modal overlay | |
if (!this.$modalOverlay) { | |
// see if it's in the DOM | |
var $modalOverlay = $('#' + Modal.MODAL_OVERLAY_ID); | |
// if so, set instance variable for $modalOverlay | |
if ($modalOverlay.length) { | |
this.$modalOverlay = $modalOverlay; | |
// or add the markup to the DOM and set $modalOverlay | |
} else { | |
var modalOverlayMarkup = this.getModalOverlayMarkup(); | |
$modalOverlay = $(modalOverlayMarkup); | |
this.$body.append($modalOverlay); | |
this.$modalOverlay = $modalOverlay; | |
} | |
} | |
// add modal wrapper | |
if (!this.$modalWrapper) { | |
// see if it's in the DOM | |
var $modalWrapper = $('#' + Modal.MODAL_WRAPPER_ID); | |
// if so, set instance variable for $modalWrapper | |
if ($modalWrapper.length) { | |
this.$modalWrapper = $modalWrapper; | |
// or add the markup to the DOM and set $modalWrapper | |
} else { | |
var modalWrapperMarkup = this.getModalWrapperMarkup(); | |
$modalWrapper = $(modalWrapperMarkup); | |
this.$body.append($modalWrapper); | |
this.$modalWrapper = $modalWrapper; | |
} | |
} | |
// ensure modal content is set | |
if (!this.$modalContent) { | |
// at this point, it has to be in the DOM | |
this.$modalContent = $('#' + Modal.MODAL_CONTENT_ID); | |
} | |
// ensure modal close is set | |
if (!this.$modalClose) { | |
// at this point, it has to be in the DOM | |
this.$modalClose = $('#' + Modal.MODAL_CLOSE_ID); | |
} | |
}; | |
Modal.prototype.getModalOverlayMarkup = function() { | |
var markup = '<div class="modalOverlay" id="' + Modal.MODAL_OVERLAY_ID + '" style="display: none;"></div>'; | |
return markup; | |
}; | |
Modal.prototype.getModalWrapperMarkup = function() { | |
var markup = '<div class="modalWrapper" id="' + Modal.MODAL_WRAPPER_ID + '" style="display: none;">'; | |
markup += '<a href="#" class="modalClose" id="' + Modal.MODAL_CLOSE_ID + '">Close</a>'; | |
markup += '<div class="modalContent" id="' + Modal.MODAL_CONTENT_ID + '"></div>'; | |
markup += '</div>'; // END: .modalWrapper | |
return markup; | |
}; | |
Modal.prototype.getModalContentMarkup = function() { | |
var markup = ''; | |
return markup; | |
}; | |
Modal.prototype.getModalCloseMarkup = function() { | |
var markup = '<a href="#" class="icon icon_close">Close</a>'; | |
return markup; | |
}; | |
Modal.prototype.setOffsets = function() { | |
var $modalWrapper = this.$modalWrapper; | |
// set top offset from vertical padding | |
var paddingTop = parseInt($modalWrapper.css('padding-top'), 10); | |
var paddingBottom = parseInt($modalWrapper.css('padding-Bottom'), 10); | |
this.modalOffset.top = (paddingTop + paddingBottom) / 2; | |
// set left offset from horizontal padding | |
var paddingRight = parseInt($modalWrapper.css('padding-right'), 10); | |
var paddingLeft = parseInt($modalWrapper.css('padding-left'), 10); | |
this.modalOffset.left = (paddingRight + paddingLeft) / 2; | |
}; | |
Modal.prototype.showModal = function($content) { | |
var dfd = new $.Deferred(); | |
var self = this; | |
self.$currentContent = $content; | |
// add content to modal | |
this.$modalContent.html($content); | |
// make sure height and width are reset to zero | |
// and margins are set based off of padding | |
this.$modalWrapper.css({ | |
'width': 0, | |
'height': 0, | |
'margin-left': -self.modalOffset.left, | |
'margin-top': -self.modalOffset.top | |
}); | |
// fade in overlay | |
this.$modalOverlay.fadeIn('500', function() { | |
// hide content | |
self.$modalContent.fadeTo(0, 0); | |
self.$modalWrapper.fadeIn('250', function() { | |
self.enableClose(); | |
self.$modalContent.fadeTo(250, 1); | |
self.resize(function () { | |
dfd.resolve(); | |
}); | |
// set content height to 100% so that it scales as the modal resizes | |
$content.height('100%'); | |
}); | |
}); | |
return dfd.promise(); | |
}; | |
Modal.prototype.resize = function(onComplete) { | |
var $content = this.$currentContent; | |
var content = $content.get(0); | |
// reset height so we can get accurate measurements | |
$content.height(''); | |
// measure height | |
var height = Math.min(content.scrollHeight, $(window).height() - this.modalOffset.top - 200); | |
// constrain if it is too tall so we can measure the width properly | |
$content.height(height); | |
// measure width | |
var width = content.scrollWidth; | |
// half values to position the modal | |
var halfWidth = Math.ceil(width / 2); | |
var halfHeight = Math.ceil(height / 2); | |
// throw it in the oven | |
this.$modalWrapper.animate( | |
{ | |
'width': width, | |
'height': height, | |
'margin-left': -(halfWidth + this.modalOffset.left), | |
'margin-top': -(halfHeight + this.modalOffset.top) | |
}, | |
500, | |
onComplete | |
); | |
}; | |
Modal.prototype.closeModal = function() { | |
var self = this; | |
this.$modalWrapper.fadeOut('250', function() { | |
self.$currentContent.detach(); | |
self.$currentContent = null; | |
self.$modalOverlay.fadeOut('500', function() { | |
self.disableClose(); | |
}); | |
}); | |
}; | |
Modal.prototype.renderModal = function() { | |
}; | |
return Modal; | |
}()); | |
}(jQuery, APP)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment