How to have member variables and public methods in jQuery plugin?

I am trying to create a jQuery plugin that will create something like autoCompleteBox, but with custom functions. How to store member variables for each corresponding jQuery element?

For example, I would need to store a timerID for each. I would also like to store links to some of the DOM elements that make up the control.

I would like to make a public method that works something like this:

$("#myCtrl").autoCompleteEx.addItem("1");

But in the implementation of addItem (), how can I access the member variables for this particular object, for example, its ID timer or something else?

Below I still ...

Thanks for any help or suggestions!

(function($)
{     
    //Attach this new method to jQuery   
    $.fn.autoCompleteEx = function(options)
    {    
        //Merge Given Options W/ Defaults, But Don't Alter Either
        var opts = $.extend({}, $.fn.autoCompleteEx.defaults, options);


        //Iterate over the current set of matched elements   
        return this.each(function() 
        {
            var acx = $(this); //Get JQuery Version Of Element (Should Be Div)

            //Give Div Correct Class & Add <ul> w/ input item to it
            acx.addClass("autoCompleteEx"); 
            acx.html("<ul><li class=\"input\"><input type=\"text\"/></li></ul>");

            //Grab Input As JQ Object
            var input = $("input", acx);

            //Wireup Div
            acx.click(function()
            {
                input.focus().val( input.val() );
            });


            //Wireup Input
            input.keydown(function(e)
            {
                var kc = e.keyCode;
                if(kc == 13)   //Enter
                {

                }
                else if(kc == 27)  //Esc
                {

                }
                else
                {
                    //Resize TextArea To Input
                    var width = 50 + (_txtArea.val().length*10);
                    _txtArea.css("width", width+"px");    
                }
            });

        });   //End Each JQ Element

    }; //End autoCompleteEx()

    //Private Functions
    function junk()
    {

    };

    //Public Functions
    $.fn.autoCompleteEx.addItem = function(id,txt)
    {
        var x = this;
        var y = 0;
    };

    //Default Settings
    $.fn.autoCompleteEx.defaults =
    {
        minChars:  2,
        delay:     300,
        maxItems:  1
    };

    //End Of Closure
})(jQuery); 
+5
source share
6 answers

, jQuery , , . :

$('#elem').autoCompleteEx('addItem', '1');

'this' , - :

function addItem() {
  // this should be == jquery object when this get called
}

$.fn.autoCompleteEx = function(options) {
   if (options === 'addItem') {
     return addItem.apply(this, Array.prototype.splice.call(arguments, 1));
   }
};
+7

, :

(function($){

  // configuration, private helper functions and variables
  var _defaultConfig = {
        /* ... config ... */
      },
      _version = 1;


  // the main controller constructor
  $.myplugin = function ( elm, config ) {

    // if this contructor wasn't newed, then new it...
    if ( this === window ) { return new $.myplugin( elm, config || {} ); }

    // store the basics
    this.item = $( elm );
    this.config = new $.myplugin.config( config );

    // don't rerun the plugin if it is already present
    if ( this.item.data( 'myplugin' ) ) { return; }

    // register this controlset with the element
    this.item.data( 'myplugin', this );

    // ... more init ...

  };
  $.myplugin.version = _version;
  $.myplugin.config = function ( c ) { $.extend( this, $.myplugin.config, c ); };
  $.myplugin.config.prototype = _defaultConfig;
  $.myplugin.prototype = {

    /* ... "public" methods ... */

  };

  // expose as a selector plugin
  $.fn.myplugin = function ( config ) {
    return this.each(function(){
      new $.myplugin( this, config );
    });
  };

})(jQuery);

, , , . .

"myplugin" , "controller" $ $.fn. , $.fn , .

- , . , "" $.myplugin.config $.myplugin.config.prototype. allways $.extend . , , .: -)

jQuery data() , ( ).

:

// init:
$( 'div#myid' ).myplugin();

// call extraMethod on the controller:
$( 'div#myid' ).data('myplugin').extraMethod();

, "this" . jQuery, .

, ( ) :

(function($){

  // configuration, private helper functions and variables
  var _defaultConfig = {
        openOnHover: true,
        closeButton: '<a href="#">Close</a>',
        popup: '<div class="wrapper"></div>'
      },
      _version = 1;

  // the main controller constructor
  $.myplugin = function ( elm, config ) {

    // if this contructor wasn't newed, then new it...
    if ( this === window ) { return new $.myplugin( elm, config || {} ); }
    this.item = $( elm );
    this.config = new $.myplugin.config( config );
    if ( this.item.data( 'myplugin' ) ) { return; }
    this.item.data( 'myplugin', this );

    // register some events
    var ev = 'click' + ( this.config.openOnHover ) ? ' hover' : '';
    this.item.bind(ev, function (e) {
      $( this ).data( 'myplugin' ).openPopup();
    });

  };
  $.myplugin.version = _version;
  $.myplugin.config = function ( c ) { $.extend( this, $.myplugin.config, c ); };
  $.myplugin.config.prototype = _defaultConfig;
  $.myplugin.prototype = {

    openPopup: function () {
      var C = this.config;
      this.pop = $( C.popup ).insertAfter( this.item );
      this.pop.text( 'This says nothing' );
      var self = this;
      $( C.closeButton )
          .appendTo( pop )
          .bind('click', function () {
            self.closePopup();  // closure keeps context
            return false;
          });
      return this;  // chaining
    },

    closePopup: function () {
      this.pop.remove();
      this.pop = null;
      return this;  // chaining
    }

  };

  // expose as a selector plugin
  $.fn.myplugin = function ( config ) {
    return this.each(function(){
      new $.myplugin( this, config );
    });
  };

})(jQuery);
+4

jQuery .data. / .

+1

- :

acx.data("acx-somename", datavalue);

:

var datavalue = acx.data("acx-somename");
+1

:

, . node jQuery data(). , .

(function($)
{     
// This is used to create AutoComplete object that are attatched to each element that is matched
// when the plugin is invoked
var AutoCompleteEx = function(options, acx) {

  // PRIVATE VARIABLES
  var timerID;
  var input;

  //Give Div Correct Class & Add <ul> w/ input item to it
  acx.addClass("autoCompleteEx"); 
  acx.html("<ul><li class=\"input\"><input type=\"text\"/></li></ul>");

  //Grab Input As JQ Object
  input = $("input", acx);

  //Wireup Div
  acx.click(function()
  {
      input.focus().val( input.val() );
  });


  //Wireup Input
  input.keydown(function(e)
  {
      var kc = e.keyCode;
      if(kc == 13)   //Enter
      {

      }
      else if(kc == 27)  //Esc
      {

      }
      else
      {
          //Resize TextArea To Input
          var width = 50 + (_txtArea.val().length*10);
          _txtArea.css("width", width+"px");    
      }
  });

  // PUBLIC METHODS

  this.setTimerID = function(id) {
    timerID = id;
  };

  this.getTimerID = function() {
    return timerID;
  };

};


//Attach this new method to jQuery   
$.fn.autoCompleteEx = function(options)
{    
    //Merge Given Options W/ Defaults, But Don't Alter Either
    var opts = $.extend({}, $.fn.autoCompleteEx.defaults, options);

    //Iterate over the current set of matched elements   
    return this.each(function() 
    {
        var acx = $(this); //Get JQuery Version Of Element (Should Be Div)

        // creating a new AutoCompleteEx object and attach to the element data, if not already attached
        if (!acx.data('autoCompleteEx')) {
          acx.data('autoCompleteEx', new AutoCompleteEx(options, acx));
        }

    });   //End Each JQ Element

}; //End autoCompleteEx()

//Default Settings
$.fn.autoCompleteEx.defaults =
{
    minChars:  2,
    delay:     300,
    maxItems:  1
};

//End Of Closure
})(jQuery);

:

$("div#someDiv").autoCompleteEx();
$("div#someDiv").data('autoCompleteEx').setTimerID(123);
var timerId = $("div").data('autoCompleteEx').getTimerID();
console.log(timerId); // outputs '123'

:

$("div.someDiv").autoCompleteEx();
$("div.someDiv").eq(0).data('autoCompleteEx').setTimerID(123);
$("div.someDiv").eq(1).data('autoCompleteEx').setTimerID(124);
var firstTimerId = $("div").eq(0).data('autoCompleteEx').getTimerID();
var secondTimerId = $("div").eq(1).data('autoCompleteEx').getTimerID();
console.log(firstTimerId); // outputs '123'
console.log(secondTimerId); // outputs '124'
+1

! , ? , . , . (, ), . , , jquery, jQuery , . , , , , → , :

var instanceAccessor = {};
var pluginOptions = {'accessor':instanceAccessor}
$('div').myPlugin(pluginOptions);

, 'accessor' . :

if (pluginOptions.accessor != null && typeof(pluginOptions.accessor) === 'object') {
   pluginOptions.accessor.exposedMethod = function (someParam) {
     // call some private function here and access private data here
   };
}

Then the consumer of this plugin can call the instance method or methods at any time at runtime, as it was before, before jquery made it strange:

instanceAccessor.exposedMethod('somevalue');

You can search for "dull crossfade" in the jquery plugin search to find my dumb plugin and see the code for yourself.

0
source

All Articles