Search code examples
javascriptjqueryjquery-widgets

Why can't my jQuery.Widgets namespace be accessed?


I've been reading alot about the advantages of using the jQuery.Widget Factory for my plugins. One of the capabilities touted is how the jQuery.widget creates a namespeace for your widget. This is attractive, as I can maintain my current namespacing (naturally) within the jQuery context.

THE PROBLEM:
I keep getting "$(".myWidget").namespace.newWay is not a function" error.

For the following element...

<div class="myWidget"></div>

THIS EXAMPLES CODE WORKS:
While nice...this is NOT what I am trying to achieve...as I still want my namespace to be honored.

var workingVersion = {
            _init: function () { /* Do Something*/ }
        };
$.widget("ui.workingVersion", workingVersion);

$(document).ready(function () {
     $('.myWidget').workingVersion();
});

HOWEVER, MY CODE FAILS:

var namespace = namespace || { };
;namespace.newWay = (function ($, window, document, undefined) {

     return function (options) {

          var self = this;

          this._create = function () {
               // Do something
          },
          this._init = function() {
               // Do something
          },
          this.publicFunction = function () {
               // Do something
          };
     };
})(jQuery, window, document);

$(document).ready(function () {
     $.widget("ui.namespace.newWay", namespace.newWay); //<-- Namespace does get appended
     $('.myWidget').namespace.newWay({ type: 'testing' }); //<-- But still fails here
});

MY QUESTION IS:
Why does it fail?

RELATED READING:


Solution

  • This answer comes a bit late, maybe, but I was struggling with the same thing and had to do some reading.

    $() in General

    The $() instance is a no-namespace shortcut list to different functions spread out over different namespaces. You can add more functions to this shortcut list by writing:

    $.fn.myFunction = function() {
        ...
    };
    

    Which then will be accessed by calling

    $("...").myFunction(); 
    

    If you add two functions by the same name the latter one will overwrite the first one.

    Widgets

    When you create a widget with a namespace it's created with it's namespace, as you would expect, but to $() it's added without it's namespace, as a simplified shortcut to your real widget-with-shortcut. This is done using $.widget.bridge(). You can therefore create your own namespaced link to $() by writing like this:

    $.widget.bridge("namespace_myFunction", $.namespace.myFunction );
    

    And then access your widget like this:

    $("#myDiv").namespace_myFunction();
    

    To use a widget directly with it's original namespace you can instead invoke it like this:

    $.namespace.myWidget(
      {
        option1: "",
        option2: ""
      },
      $("#div")
    );
    

    Hope this will clarify a little...