Skip to content

Instantly share code, notes, and snippets.

@chiplay
Created May 14, 2014 19:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chiplay/959d15e7f1a5b84a28b5 to your computer and use it in GitHub Desktop.
Save chiplay/959d15e7f1a5b84a28b5 to your computer and use it in GitHub Desktop.
Marionette 'Modal' Custom Region w/ Bootstrap
/**
* Triggers a bootstrap modal with custom view
* @requires view - custom view
*/
vent.on('app:modal:show', function (view) {
if (!app.modal.currentView) app.modal.show(view);
});
define([
'vent',
'jquery',
'marionette',
'underscore',
'bootstrap.modal',
'bootstrap.transition'
],
function(vent, $, Marionette, _) {
Marionette.Region.Modal = Marionette.Region.extend({
initialize: function() {
_.bindAll(this,'centerModal','cleanupView', 'determineModalCenter');
// Application wide event to close the alert
this.listenTo(vent, 'app:modal:close', this.closeModal);
this.listenTo(vent, 'app:modal:center', this.centerModal);
// Interface with the Alert component for spacing concerns
this.listenTo(vent, 'app:alert:show', this.shiftModal);
this.listenTo(vent, 'app:alert:closed', this.unshiftModal);
this.listenTo(vent, 'enquire', this.determineModalCenter);
},
onShow: function(){
if (!this.ensureView()) return;
var options = this.getDefaultOptions(_.result(this.currentView, 'dialog'));
// trick to get modal height before it's shown
this.currentView.$el.addClass('active');
this.currentView.$el.on('hidden.bs.modal', this.cleanupView);
this.currentView.$el.modal(options);
vent.execute('enquire:height');
},
getDefaultOptions: function(options) {
options = options || {};
return _.defaults(_.clone(options), {
show: true,
keyboard: true
});
},
closeModal: function(){
if (this.ensureView()) this.currentView.$el.modal('hide');
},
cleanupView: function(){
// Modal data is attached to the view.$el - which is removed and detroyed on close
this.close();
},
shiftModal: function(){
if (this.ensureView()) this.currentView.$el.addClass('shift');
},
unshiftModal: function(){
if (this.ensureView()) this.currentView.$el.removeClass('shift');
},
ensureView: function() {
return (this.currentView) ? true : false;
},
determineModalCenter: function(size) {
if (size == 'tall') this.centerModal();
},
centerModal: function(){
var _this = this;
_.defer(function() {
var modalOffset = _this.modalOffset(),
modalDialog = _this.modalDialog();
if (!modalDialog) return;
if (modalOffset) {
//center it if it does fit
// modalDialog.css('margin-top', modalOffset);
modalDialog.velocity({ 'margin-top': modalOffset },{ duration: 300 });
} else {
//set to overflow if no fit
// modalDialog.css({ 'margin-top': '0px', 'overflow': 'auto' });
modalDialog.velocity({ 'margin-top': 0 },{ duration: 300 });
}
});
},
modalDialog: function(){
return this.ensureView() && this.currentView.$el.find('.modal-dialog');
},
modalOffset: function(){
var modalDialog = this.modalDialog();
if (!modalDialog) return;
// Calculate the modal height and browser height
var initModalHeight = modalDialog.outerHeight(),
userScreenHeight = $(window).height();
if (initModalHeight > userScreenHeight) {
return 0;
} else {
return ((userScreenHeight / 2) - (initModalHeight/2));
}
}
});
return Marionette;
});
vent.trigger('app:modal:show', new PaymentModalView());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment