My Feedback: ASP.NET AJAX Roadmap

Posted on July 17, 2008 by matt@mattberseth.com.
Categories: ASP.NET, Contributors.

Dave Ward had another great post this past week. He took the time to not only read the ASP.NET Ajax Road Map document, but he also wrote up a post outlining what he thought about it. So I thought I would join Dave's efforts and throw in my 2 cents as well. Of course, most of this post will not make too much sense if you aren't familiar with the Road Map document. So if that's you, here is what I recommend reading (in order) ...

My Comments ...

My goal is to be direct without being rude, lets see if I can do it.

$query

  • Any plans on providing an extensible selector engine? If you have to go through all of the work to implement CSS 2.1 and 3.0, it would be cool to let developers hook into this engine and extend it.
  • Do you have any idea on what operations will be available on the collection returned from $query? From the example provided, I can see addHandler, setStyle and create will be there, but I would really love to what else is available. Also …
    • I would like to see helper functions for each events. I find it more readable to replace addHandler with $query(‘input’).click(function(){ //do something }); I know this might seem nitpicky, but I think it is this type of thing that makes the jQuery API so easy to work with.
    1. //    I like this ...
    2. $query('input').click(function(){
    3.     // do something
    4. });
    5.  
    6. //    better than this
    7. $query('input').addHandler('click', function(){
    8.     // do something
    9. });
    • I like the terseness of the jQuery API. You don’t see stuff like setStyle(). It would just be style() and all of the following would be possible. Again, probably trivial, but IMO the stuff that keeps the JS files nice and small and the API a breeze to work with
      1. //     get the width of the first matched input element
      2. var width = $query('input').style('width');
      3.  
      4. //     set the width to zero
      5. $query('input').style('width', 0);               
      6.  
      7. //     set the width and height
      8. $query('input').style({width:0, height:0});
      9.  
      10. //     set  the width and height
      11. $query('input').width(0).height(0);

$listen

  • Can we get the same stuff for attaching behaviors to elements? For example, any TEXTAREA that gets added to the DOM with a class of ‘rich’ should always get the RichTextBox behavior applied to it. Or do I have to manage this stuff myself? I would like to attach these behaviors the first time the page loads on the client and then not have to worry about it again.
  • I like how there is a single entry point to the jQuery features -> $. Any chance $listen could hang off of the wrapped set? So I could do something like this …
    1. //    again, I would prefer this
    2. $query('input').listen('hover', function(){
    3.     // do something
    4. });
    5.  
    6. //    over this
    7. $listen('hover', 'input', function(){
    8.     //    do something
    9. });
  • Is the parameter order for $listen correct? Seems like $listen(query, event, fx) would be more consistent

Templates and Client Data Sources

  • The templates look interesting. And the complex template example really does look complex ;) But I found it hard to provide any real meaningful feedback here because of the complexity of the features. This stuff seems really promising, any idea when we would be able to see examples of how a sample GridView/ListView could be replaced with a client side template/data source (sorting, paging, editing, etc...).
  • Will client side templates be able to fire server side events? Could an input button contained in a client side template trigger a server side event handler?
  • Will the 2 way databinding require the bound JS objects to implement the INotifyPropertyChanged stuff?

Animation

  • Will we have access to the animation queue?
  • This still seems too verbose ....
    1. // isn't this better ...
    2. $query('.sprite')
    3.     .fadeIn(300)
    4.     .animate({backgroundColor:'ff0000', fontSize:'2em'}, 500)
    5.     .fadeOut(300);
    6.  
    7. // than this?
    8. $query('.sprite')
    9.     .animate([
    10.         new Sys.Animation.FadeIn(300),
    11.         {'style.backgroundColor':'#ff0000', 'style.fontSize':'2em'), duration: 500 },
    12.         new Sys.Animation.FadeOut(300)
    13.     ]));

Other Stuff …

  • In my opinion, the thing jQuery has over ASP.NET AJAX and the Toolkit is its programming model. It so simple that newcomers can get up and running and author there first plug-ins in nearly no time. But, the interfaces provide the ultimate in flexibility (hooks for extending the selection engine, access to the animation queue, etc...) for the more experienced developers. It truly is elegant, simple AND powerful. Now compare this to the tutorial for creating an ASP.NET AJAX extender control. This tutorial has me writing server side code, a JavaScript behavior that is nearly 100 LOC, plus all of the plumbing that glues the two together. That's just too complex ...
  • I think the TargetControlID could use some rethinking. Again, the extender control tutorial provides a sample for adding highlighting to a control that has focus. Here is how you can tie the behavior to the TextBox ...

    1. <asp:TextBox ID="TextBox1" runat="server" />
    2. <sample:FocusBehavior runat="server"
    3.     ID="FocusBehavior1"
    4.     HighlightCssClass="MyHighLight"
    5.     NoHighlightCssClass="MyLowLight"
    6.     TargetControlID="TextBox1" />

I know I can now access the HighlighCssClass and NoHighlightCssClass properties from the codebehind, but this just isn't something I find myself doing very often. Plus, I often wanted to apply an extender to multiple elements. Imagine a form where I have 7 textboxes and I want every one to get this highlighting. Binding the extender control to a class or tag based selector would have been useful. I would have traded the server side access for that without giving it a second thought.

Also, I prefer to use the DataControlFields of the GridView and DetailsViews. It would be pretty cool if I could have attached the extender controls to these fields too ... Seems like class/tag based selection would help here too.

  • I really think the ASP.NET AJAX needs a plug-in programming model. A good part of the JavaScript code I write does not require a full blown Sys.UI.Behavior. I just want to run a bit of code when some DOM event occurs.
    • I know this is just meant as an example, but a good illustration of this is the FocusBehavior you can find in the asp.net ajax documentation. Here is the source for this behavior ...
      1. // Register the namespace for the control.
      2. Type.registerNamespace('Samples');
      3.  
      4. //
      5. // Define the behavior properties.
      6. //
      7. Samples.FocusBehavior = function(element) {
      8.     Samples.FocusBehavior.initializeBase(this, [element]);
      9.  
      10.     this._highlightCssClass = null;
      11.     this._nohighlightCssClass = null;
      12. }
      13.  
      14. //
      15. // Create the prototype for the behavior.
      16. //
      17.  
      18. Samples.FocusBehavior.prototype = {
      19.  
      20.     initialize : function() {
      21.         Samples.FocusBehavior.callBaseMethod(this, 'initialize');
      22.        
      23.         $addHandlers(this.get_element(),
      24.                      { 'focus' : this._onFocus,
      25.                        'blur' : this._onBlur },
      26.                      this);
      27.        
      28.         this.get_element().className = this._nohighlightCssClass;
      29.     },
      30.    
      31.     dispose : function() {
      32.         $clearHandlers(this.get_element());
      33.        
      34.         Samples.FocusBehavior.callBaseMethod(this, 'dispose');
      35.     },
      36.  
      37.     //
      38.     // Event delegates
      39.     //
      40.    
      41.     _onFocus : function(e) {
      42.         if (this.get_element() && !this.get_element().disabled) {
      43.             this.get_element().className = this._highlightCssClass;         
      44.         }
      45.     },
      46.    
      47.     _onBlur : function(e) {
      48.         if (this.get_element() && !this.get_element().disabled) {
      49.             this.get_element().className = this._nohighlightCssClass;         
      50.         }
      51.     },
      52.  
      53.  
      54.     //
      55.     // Behavior properties
      56.     //
      57.    
      58.     get_highlightCssClass : function() {
      59.         return this._highlightCssClass;
      60.     },
      61.  
      62.     set_highlightCssClass : function(value) {
      63.         if (this._highlightCssClass !== value) {
      64.             this._highlightCssClass = value;
      65.             this.raisePropertyChanged('highlightCssClass');
      66.         }
      67.     },
      68.    
      69.     get_nohighlightCssClass : function() {
      70.         return this._nohighlightCssClass;
      71.     },
      72.  
      73.     set_nohighlightCssClass : function(value) {
      74.         if (this._nohighlightCssClass !== value) {
      75.             this._nohighlightCssClass = value;
      76.             this.raisePropertyChanged('nohighlightCssClass');
      77.         }
      78.     }
      79. }
      80.  
      81. // Optional descriptor for JSON serialization.
      82. Samples.FocusBehavior.descriptor = {
      83.     properties: [   {name: 'highlightCssClass', type: String},
      84.                     {name: 'nohighlightCssClass', type: String} ]
      85. }
      86.  
      87. // Register the class as a type that inherits from Sys.UI.Control.
      88. Samples.FocusBehavior.registerClass('Samples.FocusBehavior', Sys.UI.Behavior);
      89.  
      90. if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

And the same functionality can easily be written as a jQuery plug-in in a fraction of the lines.

      1. (function($) {
      2.   $.fn.focus = function(options) {
      3.     // build main options before element iteration
      4.     var opts = $.extend({}, $.fn.focus.defaults, options);
      5.    
      6.     return this.each(function() {
      7.        
      8.         //    add/remove the class as the element comes into and out of focus
      9.         $(this).focus(function(){
      10.             if(!this.disabled){
      11.                 $(this).addClass(opts.highlight);
      12.             }
      13.         }).blur(function(){
      14.             if(!this.disabled){
      15.                 $(this).removeClass(opts.highlight);
      16.             }       
      17.         });
      18.     });
      19.   };
      20.  
      21.   $.fn.focus.defaults = {
      22.     highlight: 'highlight'
      23.   };
      24.  
      25. })(jQuery);

The example above really just ties a very small bit of JavaScript to a couple of event handlers. It would be great to have plug-in plumbing in the next rev to make doing stuff like this easier.

  • On sort of a related note, I think the existing existing ASP.NET AJAX and Toolkit components are too verbose and too OO (yes it feels weird saying that). Some of the things that bother me are ...
    • The uber long namespaces. Stuff like Sys.UI.DomElement.containsCssClass is just too long. Is requiring so many namespaces to organize the library a sign that it has become too large?
    • Having multiple entry points. I like how everything in jQuery starts with $(). Its simple.
    • All of the code required for the property getters and setters. Where am I seeing the value from calling raisePropertyChanged?

And I just have to wonder if having such a rigid and verbose programming model is the right choice for a client side AJAX library.

  • I don’t want to pay for features I don’t plan on using
    • I have never use the RoundedCorners and DropShadow features of the ModalPopup control, but there is no way (that I know of) for me not to pull these scripts down to the client. I like how jQuery is progressive. If the metadata plug-in is available, it will go ahead and use it. But if you decide not to pull it down, nothing will break and the widget/plugin is still usable. And for animations, just the real low-level plumbing and most often used parts of animation components are bundled in with jQuery's core. If you choose to animate colors, you can add the color animation extensions.
    • I like how jQuery doesn't pull down any extensions to the String/Number/Date prototypes.
  • The Toolkit got stale. It seemed like developing new controls was too difficult for the community to do, but the ASP.NET team was moving on to other things (possibly ASP.NET MVC and Silverlight?). So it seemed like nothing was really happening. jQuery plug-ins on the other hand are spreading like wildfire. They are simple to write AND distribute (its just a text file). The toolkit is the opposite. The controls are challenging to write and you end up distributing a DLL which may or may not correspond to the version of .Net the consumer is running with in production (I know that first hand because I received plenty of emails about people wanting to use the 3.5 version of the toolkit control with .Net 2.0).
  • I am curious if the ASP.NET AJAX team has written an application using jQuery. And I do not mean this as an insult or anything, I am really serious. In my mind that is the bar ASP.NET AJAX vNext needs to get to. I have no idea when ASP.NET AJAX vNext is coming out, but from now until then I am using jQuery. And it will be tough to persuade me to go back to ASP.NET AJAX if it is missing some of the stuff I mentioned here.

Conclusion

Well, I tried to be blunt without being rude - I truly hope that I succeeded. I hope I don't come off as angry or anything, I just have spent a lot of time with ASP.NET AJAX and the Toolkit and think that these are the things that I would want changed for vNext. And just like Dave said, I am not an MVP, or an Insider, I am just a regular dev that really wants Microsoft to nail the next version of ASP.NET AJAX. Good luck guys!

That's it. Enjoy!

SHOPNOTES: Sanding Table

Posted on by (author unknown).
Categories: Contributors.
You can do a lot more with pegboard than just organize your tools on a wall. Here's a quick pegboard project that can make sanding tasks a lot less dusty. To build one yourself, just click the following link: Continue reading "SHOPNOTES: Sanding Table"

Five Best File Syncing Tools [Hive Five]

Posted on by Adam Pash.
Categories: Contributors.


If you work and play on multiple computers in the course of a week, keeping your important files in sync can be difficult. The day may come when you've got access to all of your files and data straight from the cloud, but until that day, a solid file syncing application is just what the doctor ordered. On Tuesday you shared your favorite file syncing tools, and now we're back with the five most popular answers. Read on for a closer look at the five best file syncing tools, then cast your vote for the app you like best.

Dropbox (Windows/Mac)

Dropbox is a free, cross-platform syncing app that boasts quick, instantaneous syncs and file versioning through your desktop and their web-based interface. Currently Dropbox is in a private beta (we handed out invites a few weeks ago), during which the application is free and offers 2GB of storage space. Once Dropbox leaves beta, premium accounts will be available if you need more space than the free 2GB default. Currently Dropbox's biggest drawback is that you can't define sync folders, so you have to move everything you want to sync to the main Dropbox folder. Read more about Dropbox>>


Syncplicity (Windows)



Syncplicity is a free and premium, Windows-only tool for seamless, instantaneous file syncs. Like Dropbox, Syncplicity offers 2GB of free space and helpful icons to help keep track of the sync status of your files. Unlike Dropbox, Syncplicity can add any folder to your Syncplicity syncs, it has more advanced sharing features, and it already has pricing in place for premium accounts if you need more than 2GB (40GB for $10 per month or $100 per year). It's also available now, so if you've been waiting on a Dropbox invite, you might want to skip it and head over to Syncplicity. The biggest drawback to Syncplicity right now is its lack of a Mac client, but one is in the works and slated for September.


Windows Live FolderShare (Windows/Mac)



Windows Live FolderShare offers 2GB of free file sync between the FolderShare web site and Mac and Windows computers. Unfortunately the Mac version is ancient and reportedly has bugs with case-sensitive volumes, but either way it's a strong utility for both Windows and Mac syncing. In fact, it's what I used to sync Firefox extensions across Mac and Windows computers. Read more about setting up and using FolderShare>>


SyncToy 2.0 (Windows)



SyncToy 2.0 is the go-to application for many a Windows user looking to keep files in sync locally—either over your home network or with a USB thumb drive. The new SyncToy boasts several impressive features, most notably a smart drive letter detection that recognizes your thumb drive even if it's assigned a different letter each time. What's more, SyncToy is the tool I use to sync my iTunes library between PCs. SyncToy is freeware, Windows only. Read more about setting up and using SyncToy>>


SyncBack (Windows)



The only cross-over from our Hive Five Windows Backup Tools, both the freeware and shareware versions of SyncBack offer options for synchronizing files between computers on a local network. Like many of the others, this backup favorite is Windows only, but it's more than up for the task if you need to copy and synchronize files between computers. Read more about setting up SyncBack for automated backups>>

Now that you've seen the best, it's votin' time.

Which Is the Best File Syncing Tool?
( surveys)


Big ups to this week's honorable mentions: Microsoft's hyped Live Mesh and the venerable command line classic, rsync. Did your favorite make the list? Let's hear more about it in the comments.