I've been writing a lot of jQuery plugins for internal use that use an
OO and prototypal approach.  I have a basic class that i use for all
plugins that provides some basic methods (like storing the instance in
the .data() of the element and fires the internal methods of the
subclass, and then i attach a basic jQuery plugin functionality to
start it all up.  I've found it rather enjoyable to work with for
creating and working with objects with a lot of methods...and it keeps
the jQuery namespace clean

        app.Toolbox = function(tool)  {
                function Toolbox() {}
                Toolbox.prototype = $.extend({
                        flag:function() {
                                app.flags[tool.name] = true;
                        },
                        unflag:function() {
                                delete app.flags[tool.name];
                        },
                        initTool:function() {
                                if (tool.flags) {
                                        if (app.flags[tool.name]) {
                                                alert("You can only launch one 
"+tool.description+" at a
time.");
                                                return false;
                                        } else {
                                                this.flag();
                                        }
                                }
                                tool.$el.data(tool.name,this);
                                return this.init();
                        },
                        takeDown:function() {
                                tool.destroy.call(this);
                                tool.$el.removeData(tool.name);
                                tool.flags && this.unflag();
                        }
                },tool);
                return new Toolbox().initTool();
        };

        jQuery.fn.columnMasterEditor = function() {
                return this.each(function() {
                        var $a = $("<a href='#' class='masterEditLink' 
title='Update entire
column...'/>");
                        $a
                        .tooltip(app.defaults.tooltip)
                        .prependTo(this)
                        .bind("click.columnMasterEditor",function(e) {
                                new app.Toolbox.ColumnMasterEditor($a,e);
                                return false;
                        });
                });
        };

this is just a pattern i have developed for myself but if anyone has
feedback on it please do share...


--adam



On Nov 26, 3:41 pm, Balazs Endresz <[EMAIL PROTECTED]> wrote:
> I personally use the same approach in the Translate plugin (maybe I
> should have told you that before :), but with that you don't need the
> 'new' keyword: $.translate() returns a new object (it's a bit similar
> to $.ajax or jQuery itself, you don't need 'new' there 
> either).http://code.google.com/p/jquery-translate/
>
> With Translate you can only control the behaviour through the options
> when using the jQuery method (though the object is available in
> callback functions), but  in your case I think you can still consider
> letting the first variable call a method:
>
> $.fn.alerter = function(a){
>  if(typeof a!="string") {
>   var alerter = new $.Alerter(this, a);
>   $(this).data("alerter", alerter); //store the instance
>  } else {
>   var instance = $(this).data("alerter"); //get the instance
>   instance[a].apply(instance, $.makeArray(arguments).slice(1) ); //
> call method
>  }
>  return this;
>
> }
>
> I don't want to push this but it's really not a lot of code for a
> shorthand, as you don't need to deal with the instances in your code
> beacause they're handled by the plugin and you can call methods
> without breaking a chain, but it really depends on what you want the
> plugin to do.
>
> Some other discussions related to this topic if you're 
> interested:http://groups.google.com/group/jquery-en/browse_thread/thread/9dc9be1...http://groups.google.com/group/jquery-dev/browse_thread/thread/48400f...http://groups.google.com/group/jquery-dev/browse_thread/thread/b2f784...http://groups.google.com/group/jquery-dev/browse_thread/thread/6c02b9...
>
> On Nov 26, 7:16 pm, "Hector Virgen" <[EMAIL PROTECTED]> wrote:
>
> > I've been thinking about this over the weekend and came up with a way to
> > write class-based plugins while still following the jQuery convention. Maybe
> > someone else has done this before but I couldn't find any documentation on
> > this subject.
> > The idea is to extend the base jQuery object with the javascript class, and
> > then extend jQuery.fn with a simple method that does nothing but instantiate
> > the class and return "this".
>
> > The nice thing about this approach is that you can still make chainable
> > plugins without polluting the jQuery.fn namespace with a ton of methods.
>
> > $('#mydiv').myplugin().show();
>
> > But if you need access to the object, you can use the "new" construct.
>
> > var myplugin = new $.MyPlugin($('#mydiv'));
> > myplugin.doSomething();
>
> > Here is an example plugin that just alerts some text when the selected
> > elements are clicked. But, if you create the plugin object manually with the
> > "new" construct, you can change the message or invoke the alert without the
> > click:
>
> > (function($){
> > var Alerter = function(selector, options)
> > {
> > var obj = this;
> >  this.settings = {
> > message: 'no message'};
>
> >  $.extend(this.settings, options);
> >  selector.click(function()
> > {
> > obj.alert.call(obj);});
> > }
>
> >  Alerter.prototype.alert = function()
> > {
> > alert('Alerter said: ' + this.settings.message);}
>
> >  Alerter.prototype.message = function(message)
> > {
> > this.settings.message = message;
> > return this;}
>
> >  $.extend({
> > Alerter: Alerter});
>
> >  $.fn.extend({
> > alerter: function(options)
> > {
> > var alerter = new $.Alerter(this, options);
> > return this;
>
> > }
> > });
> > })(jQuery);
>
> > // Usage as jQuery plugin
> > $('#mydiv').alerter({
> > message: 'foo'
>
> > });
>
> > // Usage as object
> > var alerter = new $.Alerter($('#anotherdiv'), {
> > message: 'bar'
>
> > });
>
> > // As an object, you can call methods on it easily
> > alerter.message('new message');
> > alerter.alert(); // alerts "Alerter said: new message"
>
> > Any thoughts on this approach?
>
> > -Hector
>
> > On Sun, Nov 23, 2008 at 5:15 AM, Scott González <[EMAIL PROTECTED]>wrote:
>
> > > Providing the method name as the first parameter is a bit awkward,
> > > perhaps looking at the alternatives would help:
>
> > > Add namespaces to jQuery.  This isn't very jQuery-like.  Example: $
> > > (el).tabs.add(url, label).show();
>
> > > Add a new jQuery method for every plugin instance method.  This
> > > pollutes the jQuery namespace, so this should only be done when it
> > > really makes sense.  Example: $(el).addTab(url, label);
>
> > > Use events.  You can bind custom events in a namespace and then have
> > > users interact with your plugin by triggering those events.  Example: $
> > > (el).trigger('add.tabs', url, label);
>
> > > There may be other approaches as well.
>
> > > The jQuery UI approach allows plugins to expose as many methods as
> > > they want while only using one method in the jQuery namespace.

Reply via email to