Created
February 19, 2012 22:33
-
-
Save danmillar/1866239 to your computer and use it in GitHub Desktop.
Sammy Modals (Plugin)
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
/* | |
* Sammy Modals (plugin) | |
* Version 1.0 | |
* https://gist.github.com/1866239 | |
* | |
* Copyright (c) 2012 Dan Millar (@danmillar / decode.uk.com) | |
* Dual licensed under the MIT and GPL licenses. | |
*/ | |
;(function($) { | |
Sammy = Sammy || {}; | |
// <tt>Sammy.Modals</tt> provides a quick way of using Twitter Bootstrap Modals with mustache style templates in your app. | |
// The plugin is dependant upon the following: | |
// - Sammy.Mustache at https://github.com/quirkey/sammy/blob/master/lib/plugins/sammy.mustache.js | |
// - Twitter Bootstrap Modals at http://twitter.github.com/bootstrap/ | |
// | |
// Note: As of Sammy 0.7 the Mustache lib is not included in the templates source. Please download | |
// mustache.js and include it before Sammy.Mustache. | |
// | |
// By default using Sammy.Modals in your app adds the <tt>modal()</tt> method to the EventContext prototype. | |
// The modal templates are wrapped in a div with the id of <tt>sammy-modal</tt>. You can change the id by passing | |
// a second argument through when including the plugin. | |
// | |
// A huge benefit of the plugin is how it handles switching templates within active modals. Additional hooks are also | |
// available via the 'switch' and 'switched' events which are added to the Modal. | |
// | |
// ### Example #1 | |
// | |
// The template: | |
// | |
// <script id="welcome" type="text/mustache" data-engine="mustache"> | |
// <h1>{{title}}</h1> | |
// <p>Welcome the the app, {{name}}.</p> | |
// <//script> | |
// | |
// The app: | |
// | |
// var $.app = $.sammy(function() { | |
// // include the plugin | |
// this.use('Modals'); | |
// | |
// this.get('#/welcome/:name', function() { | |
// // render the template and pass it through mustache and display as modal | |
// this.modal('#welcome', { | |
// title: 'Hello!', | |
// name: this.params.name | |
// }, { | |
// keyboard: false | |
// }); | |
// }); | |
// | |
// }); | |
// | |
// If I go to #/welcome/Dan in the browser, Sammy will display this <tt>modal</tt>: | |
// | |
// <h1>Hello!</h1> | |
// | |
// <p>Welcome the the app, Dan.</p> | |
// | |
Sammy.Modals = function(app, container_id) { | |
// This plugin is dependant upon the Mustache template for templating | |
this.use('Mustache'); | |
// Set the default id of the modal container if not manually set | |
if (!container_id) { container_id = 'sammy-modal'; } | |
// The container template is based on Twitter Bootstrap Modal templates | |
var mTemplate = '<div id="{{container_id}}" class="modal {{options.transition}}"><div id="{{id}}"></div></div>', | |
mObject, | |
init_location = this.getLocation(); | |
this.helpers({ | |
// *Helper* Uses Mustache.js to parse a template and then display as a Twitter Bootstrap Modal | |
// | |
// ### Arguments | |
// | |
// * `selector` A selector for a Mustache template or A String template. | |
// {{}} Tags are evaluated and interpolated by Mustache.js | |
// * `data` An Object containing the replacement values for the template. | |
// data is extended with the <tt>EventContext</tt> allowing you to call its methods within the template. | |
// * `partials` An Object containing one or more partials (String templates | |
// that are called from the main template). | |
// * `options` An Object containing one or more options to be set on the Modal (See Bootstrap documentation) | |
// | |
modal: function(selector, data, partials, options) { | |
var context = this, | |
id = selector.replace('#', ''), | |
container = mObject ? ('#'+container_id) : Mustache.render(mTemplate, { | |
container_id: container_id, | |
id: id, | |
options: options | |
}), | |
$container = $(container); | |
this.render($(selector), data) | |
.then(function(template) { | |
if(mObject) { | |
// Trigger 'switch' event (in line with Twitter modals 'show', 'shown', 'hide' and 'hidden' events) | |
$container.trigger('switch'); | |
// Switch modal content | |
$container.children('div').attr('id', id) | |
.html(template); | |
// Update the Twitter Modal object options | |
mObject.options = $.extend({}, $.fn.modal.defaults, typeof options == 'object' && options); | |
// Ensure the Backdrop is click is attached | |
mObject.$backdrop.click(function() { | |
if(mObject.options.backdrop !== "static") { | |
mObject.hide(); | |
} | |
}); | |
// If not shown, show. (This should never happen. Belt & Braces) | |
if(!mObject.isShown) { | |
mObject.show(); | |
} | |
// Trigger 'switched' event (in line with Twitter modals 'show', 'shown', 'hide' and 'hidden' events) | |
$container.trigger('switched'); | |
} else { | |
// Append template to modal container | |
$container.find('div').append(template); | |
// init a new Modal and add on 'hidden' event | |
$container.modal(options).on('hidden', function(e) { | |
// Set location back to initial Uri | |
context.app.setLocation(init_location); | |
// Clear any fragments | |
window.location.hash = ''; | |
// When a modal is hidden, remove it from the DOM (ensuring it transitions correctly next time) | |
$(this).remove(); | |
mObject = null; | |
}); | |
// Store the Twitter Modal object | |
mObject = $container.data('modal'); | |
} | |
}); | |
// Return the container so that event listeners can be attached | |
return $container; | |
}, | |
// Checks if there is an active modal and closes it | |
closeModal: function() { | |
if(mObject) { | |
mObject.hide(); | |
} | |
} | |
}); | |
}; | |
})(jQuery); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment