JDL
JDL

Reputation: 231

jQuery plugin using reveal prototype pattern

I'm developing a jQuery plugin using the reveal prototype pattern, I'm having some trouble to instantiate my object. Below, the code of the plugin :

(function($) {

var GammadiaCalendar = function(elem, options) {
    this.elem = elem;
    this.$elem = $(elem);
    this.options = options;
};

GammadiaCalendar.prototype = function() {

    var defaults = {
        message: 'Hello world!'
    },

    init = function() {

        this.config = $.extend({}, this.defaults, this.options);

        this.displayMessage();

        return this;
    },

    displayMessage = function() {
        alert(this.config.message);
    };

    return {
        displayMessage : displayMessage
    };


};

GammadiaCalendar.defaults = GammadiaCalendar.prototype.defaults;

$.fn.GammadiaCalendar = function(options) {
    return this.each(function() {
        new GammadiaCalendar(this, options).init();
    });
};

})(jQuery)

I'm getting GammadiaCalendar is not defined when instantiating:

var gc = new GammadiaCalendar('id');

Upvotes: 0

Views: 795

Answers (2)

Esailija
Esailija

Reputation: 140220

I don't see any point in that pattern, you could just do this:

(function($) { //Because of this, everything here is "private" unless exposed anyway

    var defaults = {
            message: 'Hello world!'
    };

    function init() {
        this.config = $.extend({}, defaults, this.options);

        this.displayMessage();

        return this;
    }

    var GammadiaCalendar = function(elem, options) {
        this.elem = elem;
        this.$elem = $(elem);
        this.options = options;
    };

    GammadiaCalendar.prototype = {

        displayMessage: function() {
            alert(this.config.message);
        },

        constructor: GammadiaCalendar
    };


    GammadiaCalendar.defaults = defaults;

    $.fn.GammadiaCalendar = function(options) {
        return this.each(function() {
            var instance = new GammadiaCalendar(this, options);
            init.call(instance);
        });
    };

})(jQuery);

Note that you can't do var gc = new GammadiaCalendar('id'); outside of the containing function because it is not exposed

Upvotes: 0

krisk
krisk

Reputation: 7117

The problem is that you've set up the prototype as a function expression, and not as an immediately invoked function expression. You need to change it:

GammadiaCalendar.prototype = (function() {
   // your code here
})(); // Execute it

Furthermore, this line would never work:

GammadiaCalendar.defaults = GammadiaCalendar.prototype.defaults;

because defaults is never returned to the prototype.

Your whole structure of the revealing prototype pattern is incorrect. The init function, which is used by new GammadiaCalendar(this, options).init(), is private, and thus inaccessible. Therefore, the prototype needs to change to something like this:

GammadiaCalendar.prototype = (function() {
  var defaults = {
     message: 'Hello world!'
  },
  init = function() {
    this.config = $.extend({}, this.defaults, this.options);
    this.displayMessage();
    return this;
  },
  displayMessage = function() {
    alert(this.config.message);
  };

  return {
    defaults: defaults,
    init: init,
    displayMessage : displayMessage
  };

})(); 

(but of course, by doing it this way you haven't really gained anything with this pattern, since there are no real private functions inside anymore).

Upvotes: 1

Related Questions