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.