Optional Options

Common 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 plugin that provide a widget to your page, where a callback might not be needed.

Options Object for Plugin
1
2
3
4
$("#my-element").widgetLike({
firstOption: "setHigh",
secondOption: false
});

Callback Format

However, there might be times where 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
1
2
3
$("#my-element").alertWhenClickedTwice(function() {
alert("Be like the native Jquery event handler");
});

Hybrid Format

There are even times where a combination of the above two formats might be needed for some degree of customizing over a plain callback.

Callback with Options
1
2
3
4
5
6
$("#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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
;(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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<!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>

Online Demo | Offline Demo