title: Multiple instances of jQuery plugin on same page?
body: <p>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!</p>
  
  <p>I'm using a mix of code I've seen elsewhere and <a href="http://docs.jquery.com/Plugins/Authoring" rel="nofollow">jQuery's official authoring guidelines</a>.</p>
  
  <p>As you can see from the code, I'm doing everything inside of <code>return this.each(function() { });</code>. This includes my private functions. I assumed that this meant that for each <code>.pluginName();</code> called, the code would be run and tied to that instance. For example, I'm adding a <code>randID</code> to the end of each of the element IDs, so that if multiple instances are created, the instance can refer to the correct element.</p>
  
  <p><strong>My problem is that when I have two instances on the same page, the second instance's functions (like <code>displayAvailableItems()</code>) are using the first instances <code>randID</code>s.</strong></p>
  
  <p>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 <code>displayAvailableItems()</code> to just above the <code>retun this.each(function() { });</code>, then <code>availableItem</code> variable is no longer available to it.</p>
  
  <p>Here is the abbreviated version of my code: (pastebin) <a href="http://tny.cz/6d3d52a8" rel="nofollow">http://tny.cz/6d3d52a8</a></p>
  
  <pre><code>$.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) &gt; -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('&lt;div id="' + availableItemsContainerID + '"&gt;' +
                                                              '&lt;div id="' + tagSearchContainerID + '"&gt;' +
                                                                      '&lt;input id="' + tagSearchID + '" value="' + params.searchDefaultText + '" /&gt;' +
                                                              '&lt;/div&gt;' +
                                                              '&lt;div id="' + availableItemsID + '"&gt;&lt;/div&gt;' +
                                                      '&lt;/div&gt;' +
                                                      '&lt;div id="' + selectedItemsContainerID + '"&gt;' +
                                                              '&lt;div id="' + selectedValuesID + '"&gt;&lt;/div&gt;' + 
                                                              '&lt;div id="' + selectedItemsID + '"&gt;&lt;/div&gt;' +
                                                      '&lt;/div&gt;');      
  
              //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);
  </code></pre>