Skip to content

Instantly share code, notes, and snippets.

@orioltf
Created December 5, 2012 16:14
Show Gist options
  • Save orioltf/4217030 to your computer and use it in GitHub Desktop.
Save orioltf/4217030 to your computer and use it in GitHub Desktop.
#JQUERY #SUBLIME: my jQuery plugin boilerplate as sublime snippet
<snippet>
<content><![CDATA[
/*
* Project : ${1}
* Description : ${2}
* Author : ${3:Oriol Torrent Florensa @ Unic AG}
* License : ${4:All rights reserved} ${5:Client Name}
*/
// the semi-colon before function invocation is a safety net against concatenated
// scripts and/or other plugins which may not be closed properly.
;(function(\$, window, document, undefined) \{
"use strict";
// undefined is used here as the undefined global variable in ECMAScript 3 is
// mutable (ie. it can be changed by someone else). undefined isn't really being
// passed in so we can ensure the value of it is truly undefined. In ES5, undefined
// can no longer be modified.
// window and document are passed through as local variable rather than global
// as this (slightly) quickens the resolution process and can be more efficiently
// minified (especially when both are regularly referenced in your plugin).
// Create the defaults once
var pluginName = "${6:defaultPluginName}",
defaults = \{
propertyName: "value"
\};
// The actual plugin constructor
function ${7:Plugin}(element, options) \{
var meta;
this.\$element = \$(element);
// Grab plugin options provided via data properties in the html element. Ex:
// <div class="${6:defaultPluginName} js-${6:defaultPluginName}" data-${6:defaultPluginName}-opts="\{'optionA':'someCoolOptionString'\}">
meta = this.\$element.data(pluginName+'-opts');
// jQuery has an extend method which merges the contents of two or
// more objects, storing the result in the first object. The first object
// is generally empty as we don't want to alter the default options for
// future instances of the plugin
this.options = \$.extend(\{\}, defaults, options, meta);
// Grab here common structural elements if needed
this.\$header = this.\$element.find('.js-header');
this.\$body = this.\$element.find('.js-body');
this._defaults = defaults;
this._name = pluginName;
this.init();
\}
${7:Plugin}.prototype = \{
init: function() \{
// Place initialization logic here
// There's access to
// - the DOM element: this.\$element
// - the options this.options
// add more functions like the one below and
// call them like so: this.yourOtherFunction(this.\$element, this.options).
var self = this;
this.\$header.on('click.' + pluginName, '.js-header-subele', function(e) \{
e.preventDefault();
self.editSubElement();
\});
this.\$header.on('change.' + pluginName, '.js-header-subel-select', function(e) \{
e.preventDefault();
self.saveSubElement();
\});
\},
editSubElement: function() \{
this.\$header.addClass('editing');
\},
saveSubElement: function() \{
var val = this.\$header.find('.title').val();
// save val to database
this.\$header.removeClass('editing');
\},
yourOtherFunction: function(el, options) \{
// some logic
\},
// Remove the plugin without removing the DOM element
// If pluginName = js-calendar then
// remove the plugin like: \$('.js-calendar').data('js-calendar').destroy();
destroy: function() \{
this.\$element.off('.' + pluginName);
this.\$element.find('*').off('.' + pluginName);
this.\$element.removeData(pluginName);
this.\$element = null;
\}
\};
// A really lightweight plugin wrapper around the constructor,
// preventing against multiple instantiations and allowing any
// public function (ie. a function whose name doesn't start
// with an underscore) to be called via the jQuery plugin,
// e.g. \$(element).${6:defaultPluginName}('functionName', arg1, arg2)
\$.fn[pluginName] = function(options) \{
var args = arguments;
if (options === undefined || typeof options === 'object') \{
return this.each(function() \{
if (!\$.data(this, 'plugin_' + pluginName)) \{
\$.data(this, 'plugin_' + pluginName, new ${7:Plugin}(this, options));
\}
\});
\} else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') \{
return this.each(function() \{
var instance = \$.data(this, 'plugin_' + pluginName);
if (instance instanceof ${7:Plugin} && typeof instance[options] === 'function') \{
instance[options].apply(instance, Array.prototype.slice.call(args, 1));
\}
\});
\}
\};
// PubSub (publish/subscribe) to automatically invoke the plugin if the plugin needs to be
// initialized after its DOM elements have been loaded via AJAX
\$(document).on('dom_loaded ajax_loaded', function(e, nodes) \{
var \$nodes = \$(nodes);
var \$elements = \$nodes.find('.' + pluginName);
\$elements = \$elements.add(\$nodes.filter('.' + pluginName));
\$elements.${6:defaultPluginName}();
\});
\})(jQuery, window, document);
// Plugin usage
\$(function() \{
// PubSub (publish/subscribe) to automatically invoke the plugin if the plugin needs to be
// initialized after its DOM elements have been loaded via AJAX
var \$document = \$(document);
\$document.trigger('domloaded', \$document);
\$('.someselector').load('/my/url', function(nodes) \{
\$document.trigger('ajax_loaded', nodes);
\});
// Instantiate the plugin on the given DOM elements
\$('${8:#elem, .js-elems}').${6:defaultPluginName}(/*\{optionA: 'a', optionB: 'b'\}*/);
\});
]]></content>
<!-- Optional: Set a tabTrigger to define how to trigger the snippet -->
<tabTrigger>jqplugin</tabTrigger>
<!-- Optional: Set a scope to limit where the snippet will trigger -->
<!-- <scope>source.js</scope> -->
</snippet>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment