For the past eight(8) years Schalk Neethling has been working as a freelance developer under the pseudo of Volume4 and is now the president of Overt Strategy Consulting. During this period he has completed over 300 projects ranging from full web application development to complete branding. As president and lead developer of Overt Strategy Consulting, Schalk Neethling and his team has released a 100% Java standards based content management system called AlliedBridge and business document exchange and review system, called Doc-Central. Schalk Neethling is also actively involved on a daily basis in the open source, web standards and accessibility areas and is a current active member of the Web Standards Group. Schalk is also the co-founder and president of the non-profit The South Web Standards and Accessibility Group, which aims to actively educate and raise awareness of web standards and accessibility to both the developer society as well as business large and small. Schalk also has a long relationship with DZone and is currently zone leader for both the web builder, css.dzone.com, as well as the .NET zone, dotnet.dzone.com, and you can find a lot of his writing there as well as on his blog located at schalkneethling.alliedbridge.com. Schalk is constantly expanding on his knowledge of various aspects of technology and loves to stay in touch with the latest happenings. For Schalk web development and the internet is not just a job, it is a love, a passion and a life style. Schalk has posted 173 posts at DZone. View Full User Profile

jQuery Goodness and ASP.NET AJAX - Take II

07.10.2008
| 6973 views |
  • submit to reddit

So clearly I am obsessing about getting jQuery features into my WebForm applications.  I would seriously love to see the following added ...

  • A more powerful selector.  Finding elements by ID (ala $get) in an ASP.NET page is usually pretty awkward because the ID values isn't known until runtime.  This alone causes many people problems.  Unless I am mistaken the next version of ASP.NET AJAX will include a selector to find items by class name as well, but I have not heard anything for supporting more advanced stuff like ...
//  good ...
var alternatingRows = $select('TABLE TR.alt');

// better ...
var alternatingRows = $select('TABLE TR:odd');

// best!
var alternatingRows = $select('TABLE TR:nth-child(odd)');
  • A more fluent programming model. jQuery seriously embraces the 'find some elements and do something with them' mantra. And they make it really simple to do - if you want a zebra striped table that also supports the row hover effects, all you need to do is the following ...
//  add the row hover highlighting
$("TABLE TR")

.mouseover(function() {$(this).addClass("highlight");})
.mouseout(function() {$(this).removeClass("highlight");});

// add the zebra striping
$("TABLE TR:odd").addClass("odd");
$("TABLE TR:even").addClass("even");
  • JavaScript only plug-ins. There is something like 6.5 Bazillion jQuery plugins. Seven new ones have already been created since you last checked your email. I have to believe that part of the reason there are so many of these floating around is because they are so darn easy to create and distribute. Plus if you crack some of them open it is almost sickening how simple they are. As a matter fact you could create a zebraStripedPlusRowHighlighting plug-in from the above code snippet and then just do the following to apply it to all of your TABLE elements
//  add zebra striping and highlighing to all my TABLE's
$('TABLE').zebraStripedPlusRowHighlighting({'hoverClass':'highlight', 'oddClass':'odd', 'evenClass','even'});

So by this point you might think I get a kick-back or something from jQuery for pushing this stuff so hard, but truly I am not.  Its just that I get a little jealous browsing the jQuery plug-in page and seeing all of the cool stuff that I can't use.

And so I laid out my approach to bridge this gap between ASP.NET AJAX and jQuery.  My first thought was to simply port some of the most useful jQuery features over into some sort of JavaScript shim.  But after thinking about this I am not sure if it this is so great either.  Play this forward: say I was able to get a large number of the jQuery features into the shim - what does this really get me?  I still can't use any of the jQuery plug-ins without porting them over too.  And I would think it would be practically impossible to ever get to a point where there is feature parity between my shim module and jQuery.  And suppose I could reach that point - this new extension library would be most likely just as big as jQuery is in the first place.  Which was one of the reasons I stated previously for not using jQuery - I didn't want the bloat of 3 JavaScript libraries {ASP.NET AJAX, AjaxControlToolkit, jQuery}.

So I think I need to do some more work here thinking this through. 

  • I am sort of ashamed to say this, but I never really looked into what kind of overlap there is between the 3 libraries.  I assume there is quite a bit between XmlHttpRequest, Animation, DOM manipulation, Browser detection, selectors, data types, helper functions, etc ...  But I have not actually looked into seeing what exactly this overlap is and if there would be a way to minimize some of it.  Say if I could get jQuery selector without any of the other stuff ...  jQuery lite?

All this being said, I did take a look at some of the jQuery programming model fundamentals just because I was curious.  And I learned more than a few things so I thought I would pass them along*.

* disclaimer: I am pretty new to jQuery so none of this stuff is gospel and correct me if you see something I missed.

The Wrapped Set

A core piece of the jQuery programming model is what is referred to as the wrapped set.  This wrapped set is the collection of DOM elements that you wish to execute some operation (I believe jQuery refers to these as commands) on.  jQuery's powerful selector returns a wrapped set that contains all of the DOM elements that match the provided selector.  Once you have a reference to a wrapped set, you can execute some operation upon all elements within the set.  So you can easily do stuff like this ...

//  add the grid css class to all TABLE elements
$('TABLE').addClass('grid');

// show the id of the INPUT element when it is clicked
$('INPUT').click(function(){ alert($(this).id); });

Chaining

The wrapped set contains a ton of useful methods.  And most of them return the same value - the reference to the wrapped set.  This allows you to chain commands together keeping the code very concise yet still very readable.  The following example of adding highlighting to a TABLE uses this chaining.

//  example that shows how calls are chained together
$('TABLE TR')

.mouseover(function(){ $(this).addClass('highlight');})
.mouseout(function(){ $(this).removeClass('highlight'); })

Updating my Shim

So, to continue my experiment of trying to get some of this stuff into my WebForms apps, I made the following changes to plug-ins I discussed in my previous post:

  • I created a JavaScript class that is a stripped down version of jQuery's.  It contains a collection of DOM elements and contains methods like ..
    • add, get, remove, clear, each -> basic collection operations
    • addClass, removeClass -> basic DOM operations
    • blur, focus, mousedown, mouseup, etc...  -> shortcuts for adding event handlers
  • After I created the wrapped set class, I updated the $select function to return an instance of this wrapped set that contains all of the elements that matched the selector.  I also renamed $select to $majax.  So now you can do things like this ...
//  attach all of the textbox elements and 
// and apply the focus class when the textbox
// obtains the focus

$majax('textbox')
.focus(function(){ $majax(this).addClass('focus'); })
.blur(function(){ $majax(this).removeClass('focus'); });

Which would turn the background of all of the DOM elements that have the textbox css class to yellow (via the focus css class) when they have focus.  It would look something like this ...

  • And finally, I changed the plug-ins to use my wrapped set prototype to add their commands to instead of the Sys.UI.Control class.  This made a nice difference in how I was able to apply my plug-ins to a collection of DOM elements.  Checkout the OLD and NEW syntax examples below.
// OLD:
$select('#roundedPanel1, #roundedPanel2').each(function(e){

// add the rounded corners (6 pixel radius) to the panels
e.round(6);

});

// NEW:
$majax('#roundedPanel1, #roundedPanel2').round(6);

And here is how the new RoundedCorners plugin is defined. The main changes are round function is attached to the elementSet prototype (this is the wrapped set class), the _round function operates on all elements in the current set and the _round function returns a reference to the wrapped set - allowing chaining.

Type.registerNamespace("majax");

majax.RoundedCorners = function() {
majax.RoundedCorners.initializeBase(this);
}

majax.RoundedCorners.prototype = {

initialize : function() {
majax.RoundedCorners.callBaseMethod(this, 'initialize');

// attach the plugin to the elementSet class
majax.elementSet.prototype.round = this._round;
},

dispose : function() {
majax.RoundedCorners.callBaseMethod(this, 'dispose');
},

_round : function(radius) {

// create rounded corners for each of the elements
// in the collection
this.each(function(){
$create(AjaxControlToolkit.RoundedCornersBehavior, {"Radius":radius}, null, null, this);
});

// for chaining

return this;
}

}

// register the class
majax.RoundedCorners.registerClass('majax.RoundedCorners', Sys.Component);

// create the singleton
$create(majax.RoundedCorners, null, null, null);

// Since this script is not loaded by System.Web.Handlers.ScriptResourceHandler
// invoke Sys.Application.notifyScriptLoaded to notify ScriptManager
// that this is the end of the script.
if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
Where to Next?

Good question.  So far the small jQuery-ish shim I created seems useful.  Its 200 LOC right now its pretty small, but if I continue down this path it will no doubt grow quickly.  So I am not really sure where I am going next - but I don't feel like giving up either.

How About You?

What about you?  Are you a WebForms developer that is crushing over jQuery too?  Do you have a problem using 3 JavaScript libraries - ASP.NET AJAX, the Toolkit and jQuery?  How do you think this problem (if there is one) should be solved?

Original Author

Original article written by Matt Berseth

References
Published at DZone with permission of its author, Schalk Neethling. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)