OO JQuery and classes - javascript

I'm working on a site and using JQuery for essentially the first time. I've mostly used MooTools for previous projects, and I have a few widget classes I've written using the MooTools Class structure. I'd like to port them over to JQuery, but it looks to me like there is nothing similar to the MooTools functionality when it comes to object classes.
I've searched around a bit, and haven't found much on it. Digg appears to have rolled their own, but I'm not sure if this is something I should be using. Is there a better way? How object-oriented do people normally get with JQuery? What's the usual method of encapsulating a UI widget (or any functional class structure)?
I'll post a fake example of a possible MooTools widget class:
var ZombatWidget = new Class({
Extends: BaseWidget,
widgetPropertyX = 'prop1',
widgetPropertyY = 'prop2',
attach = function(el) {
var f = function() {
//do something widgety
};
el.addEvent('dblclick',f);
el.addClass('widgetized');
}
});
var z = new ZombatWidget();
z.attach($('widgetDiv'));
What I've got is a lot bigger than that, but you get the idea. Do I need to convert this to the prototype method of class/inheritance structuring? How would you write this kind of object class using JQuery?

You might find this approach useful to the task at stake: building an object-oriented jquery plugin.
And this article on Ajaxian "a real OO class system with jquery".

Hm... interesting. We have jQuery which imho is a great tool to interact with the DOM. It's a selection tool where you can write your own code (plugins) to modify selected items. You can interact here with your own (object oriented) code in a plugin to do something really cool.
So why would you need extra OO capabilities in jQuery unless you want to be able to inherit from other jQuery plugins?
Because you might have a plugin that allows you to do the following:
$(".spiffyness").yourSpiffyficationPlugin1();
And, while doing some really cool awesomeness already, you need more spiffyness on top of this.
Therefore you want to inherit from your first plugin which results in:
$(".spiffyness").yourSpiffyficationPlugin2(); //plugin inherited from 1
But... wouldn't you get there too by doing this:
$(".spiffyness").yourSpiffyficationPlugin1().yourSpiffyficationPlugin2();
Where the second plugin just does this tiny (but awesome ;)) thing extra on top of the first one?
In other words: is what you want, worth the effort for the sake of OO purism? Or is the jQuery pipe mechanism good enough and maybe everything you need?
I would say that separation of responsibilities and/or your mootools mindset might be the real issue here. Let jQuery do what it is good at, use it's powerfull pipe mechanism, pipe your own plugins (which may contain tons of fancy OO stuff)... and you can have great results while your code is still clean.
If you do think I am thinking too simple here, a good example of the essence of your point would be welcome! :-)
And to be ahead of that, if you are doing something really advanced and you do not get away with simply doing something on top of something else, you're plugin could also delegate to one of your OO classes. E.g. like:
$.fn.totalAwesomeness = function(options) {
var defaults = {
mode: 1,
title: 'Awesome'
};
var opts = $.extend(defaults, options);
return this.each(function() {
var $this = $(this);
var handler = null;
if(defaults.mode == 1)
handler = new com.myStuff.class1($this);
else if(defaults.mode == 2)
handler = new com.myStuff.class2($this); //class2 inherits from class1
handler.doMagic();
});
};

You can always also use moo4q - http://moo4q.com/ . It adds MooTools class support to jQuery.

I wrote an article some time ago about jQuery object oriented plugins, hope it will be helpful
http://ajax911.com/jquery-object-oriented-plugins/

There are third party javascript class implementations that provide very powerful introspection capabilites. I would like to particularly highlight JS.Class and Joose.
While JS.Class is modeled after Ruby, Joose is modeled after Moose.
I am not a mootools user so I can not comment on their advantages/disadvantages with respect to mootools. But I would summarize their key features.
JS.Class has a strong focus on simulating the Object oriented features of Ruby and does a pretty good job at that. It provides a powerful library modeled after the standard library of Ruby and also comes with a well integrated package management and testing framework.
Joose, while provides no testing framework/package management facilites, excels in terms of
advanced attribute management facilities, filters and better introspection facilities.
Both of them have really good documentation and can be used in browser as well as server.

I've just finished a very first release of my mini project: https://github.com/op1ekun/plOOgins. It's all about writing OOP code to be used as Jquery plugins. It's not rocket science just a little something that we wanted to use at my workplace. Maybe it will help You a bit. Good luck!

Plugins sometimes do the trick.
Of course, you could use just enough of mootools to get it's class/inheritance model. With the implementation of document.id "compatibility mode" in 1.2.3 you can have your cake and eat it too (I think--haven't done it myself.)

The question is... Why are you moving away from MooTools is it fits your needs? Seems to me like MooTools was working fine, and there is nothing jQuery does that MooTools can't do. (The opposite isn't true).
Unfortunately, jQuery is not built to support classical OOP as MooTools is so you will need to write your Classes as jQuery plugins.

Related

OOP Solution for Javascript?

Is there any super set or language similar to javascript that provides a more classical c++/java/c#-like OO System. But can be used with HTML-5 and DOM and has a cross-platform implementation?
You could give CoffeeScript a try.
It compiles to JavaScript so it's indeed cross-platform.
As far as scripting is concerned, it is also compatible with using HTML5 tags but it's not really an issue: HTML is the markup language, JavaScript (or CoffeeScript) is the scripting language. So you can still select or edit (HTML5) elements using CoffeeScript; the script will be compiled to JavaScript and it'll still work.
Yes, it's called JavaScript. There are some good articles about OOP around
var Parent = {
method: function () {
...
}
}
var Child = Object.create(Parent, {
childMethod: { value: function () {
...
} }
})
Any attempt to emulate a class system in JavaScript is a waste of time and ends up writing bloated / unreadable / unmaintainable code.
If the above is too ugly, consider using an extend function
In addition to the suggestion to learn CoffeeScript above, you could try out a couple of javascript patterns.
I was recently watching a pluralsight screencast (structuring javascript code) and I was made aware of a couple of javascript patterns but i really like the "Revealing Prototype Pattern".
Very concise and simple, you get some of the benefits of OOP including encapsulation et al.
Pluralsight offers a free 10 days trial period so i guess you can easily get up to speed with it.
There are a few options. The ones that spring to my mind are:
Simple JavaScript Inheritance
YUI extend

JavaScript inheritance JQuery vs Prototype DOM Extension

I am not trying to ask another JQuery vs. Prototype vs... topic as I have already read 5+ of those on these forums and have been able to gain a lot of knowledge from them. My question is more directly related to wanting the ability to use inheritance for basic classes and not actually sure what would be a good choice.
To be brief, I have the requirement to be able to control theoretical objects in javascript and manipulate them based on user input then display them.
I have used JQuery and enjoy how easy it is to modify the DOM (which appears to be it's main goal). However from all the readings I have done, it seems that JQuery has no intention of assisting you in dealing with classes, inheritance etc. If I have already chosen JQuery to display and manipulate the data what would be a good choice to assist me with the inheritance issue.
My first thought was Mootools or Prototype, however prototype DOM Extension seems to be a very bad approach and would rather wait for Prototype 2.0 unless this isn't an issue on commonly supported browsers now.
I had also read about Base2, Joose, and JS.Class, but don't know if they will do what I am hoping for either.
Any suggestions based on the above information would be great, again, I am not trying to figure out the pro's and con's of the commonly used JS frameworks.
Why emulate classical inheritance?
What's wrong with functions and .prototype?
var SomeObject = function(data) {
this.data = data;
}
SomeObject.prototype.doStuff = function() {
return this.data;
}
Do it the old fashioned way.
If you want to use anything besides jQuery I would recommend underscore for it's syntactic sugar.
If you must emulate classical OO, I would recommend oorja as it's the lesser of evils.

Design Patterns used in the jQuery library

jQuery is highly focused on the DOM and provides a nice abstraction around it. In doing so, it makes use of various well known design patterns which just hit me yesterday. One obvious example would be the Decorator pattern. The jQuery object provides new and additional functionality around a regular DOM object.
For example, the DOM has a native insertBefore method but there is no corresponding insertAfter method. There are various implementations available to fill this gap, and jQuery is one such library that provides this functionality:
$(selector).after(..)
$(selector).insertAfter(..)
There are many other examples of the Decorator pattern being heavily used in jQuery.
What other examples, big or small, of design patterns have you noticed that are part of the library itself? Also, please provide an example of the usage of the pattern.
Making this a community wiki as I believe that various things people love about jQuery can be traced back to well known design patterns, just that they are not commonly referred to by the pattern's name. There is no one answer to this question, but cataloging these patterns will provide a useful insight into the library itself.
Lazy Initialization:
$(document).ready(function(){
$('div.app').myPlugin();
});
Adapter or wrapper
$('div').css({
opacity: .1 // opacity in modern browsers, filter in IE.
});
Facade
// higher level interfaces (facades) for $.ajax();
$.getJSON();
$.get();
$.getScript();
$.post();
Observer
// jQuery utilizes it's own event system implementation on top of DOM events.
$('div').click(function(){})
$('div').trigger('click', function(){})
Iterator
$.each(function(){});
$('div').each(function(){});
Strategy
$('div').toggle(function(){}, function(){});
Proxy
$.proxy(function(){}, obj); // =oP
Builder
$('<div class="hello">world</div>');
Prototype
// this feels like cheating...
$.fn.plugin = function(){}
$('div').plugin();
Flyweight
// CONFIG is shared
$.fn.plugin = function(CONFIG){
CONFIG = $.extend({
content: 'Hello world!'
}, CONFIG);
this.html(CONFIG.content);
}
The Composite pattern is also very commonly used in jQuery. Having worked with other libraries, I can see how this pattern is not so obvious as it looks at first sight. The pattern basically says that,
a group of objects are to be treated in the same way as a single instance of an object.
For example, when dealing with a single DOM element or a group of DOM elements, both can be treated in a uniform manner.
$('#someDiv').addClass('green'); // a single DOM element
$('div').addClass('green'); // a collection of DOM elements
How about the Singleton/Module pattern, as discussed in this article about YUI: http://yuiblog.com/blog/2007/06/12/module-pattern/
I believe jQuery uses this pattern in its core, as well as encouraging plug-in developers to use the pattern. Using this pattern is a handy and efficient way of keeping the global namespace clear of clutter, which is further useful by assisting developers in writing clean, encapsulated code.
In the eyes of functional programming, jQuery is a Monad. A Monad is a structure that passes an object to an action, returns the modified object and passes it on to the next action. Like an assembly line.
The Wikipedia article covers the definition very well.

Prototype or jQuery for DOM manipulation (client-side dynamic content)

I need to know which of these two JavaScript frameworks is better for client-side dynamic content modification for known DOM elements (by id), in terms of performance, memory usage, etc.:
Prototype's $('id').update(content)
jQuery's jQuery('#id').html(content)
EDIT: My real concerns are clarified at the end of the question.
BTW, both libraries coexist with no conflict in my app, because I'm using RichFaces for JSF development, that's why I can use "jQuery" instead of "$".
I have at least 20 updatable areas in my page, and for each one I prepare content (tables, option lists, etc.), based on some user-defined client-side criteria filtering or some AJAX event, etc., like this:
var html = [];
int idx = 0;
...
html[idx++] = '<tr><td class="cell"><span class="link" title="View" onclick="myFunction(';
html[idx++] = param;
html[idx++] = ')"></span>';
html[idx++] = someText;
html[idx++] = '</td></tr>';
...
So here comes the question, which is better to use:
// Prototype's
$('myId').update(html.join(''));
// or jQuery's
jQuery('#myId').html(html.join(''));
Other needed functions are hide() and show(), which are present in both frameworks. Which is better? Also I'm needing to enable/disable form controls, and to read/set their values.
Note that I know my updatable area's id (I don't need CSS selectors at this point). And I must tell that I'm saving these queried objects in some data structure for later use, so they are requested just once when the page is rendered, like this:
MyData = {div1:jQuery('#id1'), div2:$('id2'), ...};
...
div1.update('content 1');
div2.html('content 2');
So, which is the best practice?
EDIT: Clarifying, I'm mostly concerned about:
Memory usage by these saved objects (it seems to me that jQuery objects add too much overhead), while OTOH my DOM elements are already modified by Prototype's extensions (loaded by default by Richfaces).
Performance (time) and memory leakage (garbage collection for replaced elements?) when updating the DOM. From the source code, I could see that Prototype replaces the innerHTML and does something with inline scripts. jQuery seems to free memory when calling "empty()" before replacing content.
Please correct me if needed...
You're better off going with jQuery. Both frameworks are great (and I use them both), but in your case jQuery is probably the winner.
In my opinion prototype provides a more natural syntax for javascript development. It does this at the cost of adding methods to some of the core classes, but it's also motivated by ruby where this is the norm.
jQuery on the other hand is far superior at dom manipulation and event observation. Your code will be more concise and manageable in these cases and will benefit from great performance features like event delegation. jQuery also has a much larger community and way more plugins and code samples.
If you're only interested in the three basic methods "update", "hide" and "show" then jQuery is better suited. It is aimed more at DOM manipulation which is exactly what you need. Then again you could do each of those things in a couple of lines of code, saving the 26KB needed to transfer the jQuery library.
Since your worry is in memory usage look at the jQuery file, it is 77KB uncompressed, how much work do you suppose that is for the browser to execute? Probably much more than that freed by calling empty() on a typical DIV.
And you mention Prototype is already in use on the site in which case you shouldn't be adding another library. jQuery's abilities are a subset of Prototype's.
This question is nearly a year old so you've probably made your decision by now. For anyone else reading the answer is simple; If something's not broken don't fix it, you already have one capable library installed so use that.
I would go for jQuery. Prototype used to modify default JS objects, which is fine but it means you have to be careful. I believe this is no longer the case though. JQuery also has a large plugin repository and the jquery UI extension for widgets. Btw. With JQuery you can use the familiar dollar sign as well.

Question about some wild javascript syntax and contraints

So I know javascript pretty well, but I'm not sure about this one.
Tough to explain so I'll just show it:
var view = new View();
view.rating = 4.5;
Is there anyway to have view.rating be called as a function to manipulate the DOM a bit and set that rating to five?
So in View:
View.prototype = {
rating : function() {
$('div.stars').width(4.5);
}
}
I know there are workarounds, using something other than "view.rating = 5". I'm not interested in those. I'm wondering if there is a way to set this up maintaining view.rating = 5. This is coming JS is coming straight from PHP essentially and I don't want to bog the PHP down with anonymous functions.. like view.rating = function() {...};
Thanks!
Matt Mueller
No. (Edit: not on all implementations of common browsers at least)
There isn't anything in Javascript equivalent to "overloading the = operator".
Edit:
I'm not sure if this is clear to you. If you make rating a function (either via the prototype or not), you should call it like view.rating(5), and it can update the DOM (or do anything).
Most implementations of JavaScript don't support creating getter/setter properties so it wouldn't be super useful on the web. However there are some implementations that do. Here's an example in Mozilla's implementation:
https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Creating_New_Objects/Defining_Getters_and_Setters
EDIT: Let me just clarify, writing getters/setters is syntactic sugar over the use of a getFoo()/setFoo(foo) style property. It is for the developer's benefit. IMO, for a web app (due primarily to IE's lack of support) it isn't quite realistic just yet. While IE market share is dropping, depending upon your demographics in a widely public app, a lot of your visitors at this point still won't have support for them.
Some more links of interest for you:
http://www.robertnyman.com/javascript/#javascript-getters-setters-object-defineproperty-compatibility
http://ejohn.org/blog/javascript-getters-and-setters/
http://blogs.msdn.com/ie/archive/2009/01/13/responding-to-change-updated-getter-setter-syntax-in-ie8-rc-1.aspx

Categories