Optional Options
09/12/2013, ThuCommon Object Format
Most JQuery plugins will use the common format of customizing by providing a plain object to the plugin handler. This is well suited for plugins that provide a widget to your page where a callback might not be needed.
// Options Object for Plugin
$("#my-element").widgetLike({
firstOption: "setHigh",
secondOption: false,
});
Callback Format
However, there might be times when the plugin does not need options, or a callback is desired when a certain event happens. This format of plugin is very similar to the native JQuery event handlers.
// Callback for the Plugin
$("#my-element").alertWhenClickedTwice(function () {
alert("Be like the native Jquery event handler");
});
Hybrid Format
There are even occasions where a combination of the above two formats might be needed for some degree of customizing over a plain callback.
// Callback with Options
$("#my-element").optionsWithCallback(
{
firstOption: "setHigh",
secondOption: false,
},
function () {
alert("Be like the native Jquery event handler");
}
);
Below is a modified version of the JQuery Boilerplate.
In order for the callback function to work, the event must be triggered within the plugin itself. Look inside Plugin.prototype.init() for details.
// Boilerplate - Optional Option
(function ($, window, document, undefined) {
var pluginName = "optionsAreOptional",
defaults;
var PluginWrapper = function (element, pluginInfo) {
var Plugin = function () {
function checkArgs(index) {
switch (pluginInfo[index]) {
case "object":
// Overwrite defaults if the args item is an object
Plugin.options = $.extend({}, defaults, pluginInfo.args[index]);
break;
case "function":
// Store the index of where the function location in args
pluginInfo.functionIndex = index;
break;
}
}
// Check what type of arguments are supplied to
// the first and second parameters
switch (pluginInfo.argsLen) {
case 1:
checkArgs(0);
break;
case 2:
checkArgs(0);
checkArgs(1);
// Should not have the same parameter types
if (pluginInfo[0] === pluginInfo[1]) {
throw [
"Can not have the first two parameters of the same type of ",
'"',
pluginInfo[0],
'"',
].join("");
}
break;
}
};
Plugin.prototype = {
init: function (pluginInfo) {
// Do Stuff
this.stuff();
var $el = $(element);
// Attaching event listener
$el.on("optionsAreOptional", function (evt) {
// Make sure a function exists before executing one
if (typeof pluginInfo.functionIndex !== "undefined") {
// Preserve the event and context
pluginInfo.args[pluginInfo.functionIndex].call(this, evt);
}
});
// Testing out the event listener
// Use this upon a certain condition being met
$el.trigger("optionsAreOptional");
// Do more stuff here
this.doMoreStuff();
},
stuff: function () {
// Stuff to be done
},
doMoreStuff: function () {
// Even more stuff to be done
},
// Add more functions here
};
// Initialize plugin
Plugin();
Plugin.prototype.init(pluginInfo);
};
$.fn[pluginName] = function () {
var args = Array.prototype.slice.call(arguments),
argsLen = args.length,
pluginInfo = {};
pluginInfo.argsLen = argsLen;
pluginInfo.args = args;
function checkArgs(theItem, index) {
try {
// Determine if item is a plain object
if ($.isPlainObject(theItem)) {
pluginInfo[index] = "object";
}
} catch (error) {
throw "Not a proper object";
}
try {
if ($.isFunction(theItem)) {
// Determine if item is a function
pluginInfo[index] = "function";
}
} catch (error) {
throw "Not a proper function.";
}
}
return this.each(function () {
if (!$.data(this, "plugin_" + pluginName)) {
// Check for the number of arguments for plugin
for (var i = 0; i < pluginInfo.argsLen; i++) {
checkArgs(pluginInfo.args[i], i);
}
$.data(
this,
"plugin_" + pluginName,
new PluginWrapper(this, pluginInfo)
);
}
});
};
})(jQuery, window, document);
<!-- Accompanying Html -->
<!DOCTYPE html>
<html>
<head>
<title>Optional Options</title>
<meta charset="UTF-8" />
<script src="jquery-1.10.2.min.js"></script>
<script src="JqueryBoilerPlateOptionalOptions.js"></script>
</head>
<body>
<script>
$(document).ready(function () {
// 1) Options Only
// Only options provided to the plugin
// This is what most JQuery plugin out there uses
$("#only-options").optionsAreOptional({
stuff: "myThings",
});
// 2) Function Only
// This format is similar to the native JQuery event handler
// Use this if your plugin needs not to have any configuration options
// In order for this to work, trigger the name of the plugin
// ex. $('#only-function').trigger("optionsAreOptional")
// inside your plugin to activate the event handler
$("#only-function").optionsAreOptional(function () {
console.log("Only a function");
});
// 3) Options and Function
// Both option and function are provided for this one
// Use this if a little configuration is needed over the
// second option
$("#options-function").optionsAreOptional(
{
moreStuff: "moreOfMyThings",
},
function () {
console.log("My callback.");
}
);
});
</script>
<h1>The following headers have attached event listeners:</h1>
<h2 id="only-options">Only options provided for this header.</h2>
<h2 id="only-function">A function attached to this header.</h2>
<h2 id="options-function">This header has options and a function.</h2>
</body>
</html>