Tutorial :JQuery - Widget Public Methods



Question:

If I create a JQuery widget (code example below), and then define a "public" method, is there any other way to call the method other than using the following form?

$("#list").list("publicMethod");   

I would like to create a series of widgets that all define the same methods (basically implementing the same interface), and be able to call the method without knowing anything about which widget I currently am invoking the method on. In the current form, I need to know that I am executing the method on the "list" widget.


Below is an example of creating a widget with the "public" method.

 (function($) {      var items = [];      var itemFocusIdx = 0;        $.widget("ui.list", {          // Standard stuff          options : { ... },          _create : function() { ... },          destroy : function() { ... },            // My Public Methods          publicMethod : function() { ... }          ...      });  }(jQuery));  


Solution:1

jQuery UI widgets use jQuery's $.data(...) method to indirectly associate the widget class with the DOM element. The preferred way to call a method on the widget is exactly what was described by Max...

$('#list').list('publicMethod');  

...but if you want to field a return value, you'll have better luck calling it this way, via the data method:

$('#list').data('list').publicMethod();  

However, using the second way side-steps the whole jQuery UI widget pattern, and should probably be avoided if possible.


Solution:2

Slightly off-topic, I know, but you may want to look at jquery Entwine.

This provides a form of inheritance and polymorphism which allows some clever behaviour with simple code. It sounds like this would do what you are trying to do.


Solution:3

lets say you have list, list2, and superList... let's call "publicMethod" on for each of them:

$.fn.callWidgetMethod = function(method) {    var $this = this,        args = Array.prototype.slice.call(arguments, 1);      // loop though the data and check each piece of data to    // see if it has the method    $.each(this.data(), function(key, val) {      if ($.isFunction(val[method])) {        $this[key].apply($this, args);          // break out of the loop        return false;      }    });  }    $("#some-element").list();  $("#another-element").list2();  $("#hydrogen").superList();    $("#some-element").callWidgetMethod("publicMethod");  $("#another-element").callWidgetMethod("publicMethod");  $("#hydrogen").callWidgetMethod("publicMethod");  


Solution:4

This solution is inspired by @Jiaaro's solution, but I needed a return value and implemented as a JavaScript function rather than extending jQuery:

var invokeWidgetMethod = function(methodName, widgetElem)      {          var $widgetElem = $(widgetElem),              widgetData = $widgetElem.data(),              dataName,              dataObject;            for(dataName in widgetData)          {              dataObject = widgetData[dataName];              if ($.isFunction(dataObject[methodName])) {                  return dataObject[methodName]();              }          }      }  


Solution:5

Try this:

$("#list").list("publicMethod");  


Solution:6

How about this one:

$("#list").list.publicMethod  

As you are extending ui.list with your key:value pair set


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »