I've seen a lot of different jQuery plugin boilerplates, and read many different jQuery plugin authoring articles, including the official one. However, I seem to still be missing something, fundamentally!
I'm using a mix of code I've seen elsewhere and jQuery's official authoring guidelines.
As you can see from the code, I'm doing everything inside of return this.each(function() { });
. This includes my private functions. I assumed that this meant that for each .pluginName();
called, the code would be run and tied to that instance. For example, I'm adding a randID
to the end of each of the element IDs, so that if multiple instances are created, the instance can refer to the correct element.
My problem is that when I have two instances on the same page, the second instance's functions (like displayAvailableItems()
) are using the first instances randID
s.
I'm assuming 2 things wrong right off the bat: the functions are in the wrong place, and the randID is a bad method of identifying the elements. If I move displayAvailableItems()
to just above the retun this.each(function() { });
, then availableItem
variable is no longer available to it.
Here is the abbreviated version of my code: (pastebin) http://tny.cz/6d3d52a8
$.pluginName = {
id: 'PluginName'
,version: '1.0'
,defaults: { // default settings
foo: 'bar'
}
};
(function($) {
//Attach this new method to jQuery
$.fn.extend({
pluginName: function(params) {
//Merge default and user parameters
var params = $.extend($.pluginName.defaults, params)
,otherGeneralVars = 'example'
;
return this.each(function() {
var $t = $(this);
//Generate a random ID to attach to the elements, so we can have endless (up to 50k) quantities of the plugin on the page
var randID = 1 + Math.floor(Math.random() * 50000);
//Make sure the randID hasn't been previously used
while ($.inArray(randID, usedRandIDs) > -1)
{
randID = 1 + Math.floor(Math.random() * 50000);
}
usedRandIDs.push(randID);
randID = '_PluginName' + randID;
/*
RUN INITIALIZATION SETTINGS
*/
var availableItemsContainerID = 'availableItemsContainer' + randID
,tagSearchContainerID = 'tagSearchContainer' + randID
,tagSearchID = 'tagSearch' + randID
,availableItemsID = 'availableItems' + randID
,selectedItemsContainerID = 'selectedItemsContainer' + randID
,selectedItemsID = 'selectedItems' + randID
,selectedValuesID = 'selectedValuesInputName' + randID
;
//Build element structure
$t.append('<div id="' + availableItemsContainerID + '">' +
'<div id="' + tagSearchContainerID + '">' +
'<input id="' + tagSearchID + '" value="' + params.searchDefaultText + '" />' +
'</div>' +
'<div id="' + availableItemsID + '"></div>' +
'</div>' +
'<div id="' + selectedItemsContainerID + '">' +
'<div id="' + selectedValuesID + '"></div>' +
'<div id="' + selectedItemsID + '"></div>' +
'</div>');
//Show the list of available items
displayAvailableItems();
$('#' + availableItemsContainerID).css({
'width': params.availableItemsContainerWidth + params.unitOfMeasurement,
'height': params.availableItemsContainerHeight + params.unitOfMeasurement
});
$('#' + selectedItemsContainerID + ', #' + selectedItemsID).css({
'width': params.selectedItemsContainerWidth + params.unitOfMeasurement,
'height': params.selectedItemsContainerHeight + params.unitOfMeasurement
});
function displayAvailableItems() {
//Clear out the available items
$("#" + availableItemsID).html('');
//Do other stuff
}
});
}
})
})(jQuery);
First, you need to move var params
into your this.each, however you will then have a variable hoisting (not absolutely sure if that's actually what is happening, but that's what it appears to be) problem due to using the argument name as a variable name causing params to be undefined. To solve that, just rename params inside of this.each to something else. Example:
$.fn.extend({
pluginName: function (params) {
//Merge default and user parameters
var otherGeneralVars = 'example';
return this.each(function () {
var $t = $(this), opts = $.extend({},$.pluginName.defaults, params);
$t.text(opts.foo + uniqueId);
});
}
})
http://jsfiddle.net/M99EY/1/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With