As I continue to work with the new MVC bits with respect to SubSonic, I keep smacking my forehead (and there's a lot to smack) at how much simpler things can be if I stop overthinking them. Getting to know toolsets like jQuery and SubSonic can offer many of these moments. Bundle that with the new MVC stuff and your forehead will be burning...
Last week I wrote a post about how I had to relearn some concepts as I sat noodling over a rather simple problem:
How do I auto-postback an HTML select box and refresh some bits on my page based on the selection?
It's pretty easy with WebForms and takes all of 10 minutes - but I don't have PostBack with MVC and I love a challenge :). I started to get sort of frustrated at first - slignin javascript around - but then it occurred to me that while I've been relying on WebForms to do this kind of thing for me over the last few years, the "other guys" out there have kept on truckin with javascript and HTML and dernit if those kids haven't come up with some very neat stuff! jQuery, as they say, is the bees knees...
Put things like .NET 3.5, jQuery, SubSonic, and the new MVC framework together, and you have something really, really Super Groovy to look forward to.
Extension Methods
This is part of the fun of .NET 3.5. These methods allow you to "add functionality" to a class when needed - sort of like Ruby's mixins but you don't declare these extensions on the class - you simply have to have a "using" statement that declares the extension namespace - thus "attaching them" at the hip during design-time (see Scott's writeup).
So, the first part of my solution was to create an extension method for a Dictionary<string,string> that creates some HTML. These extension methods (or versions of them, after Eric has his way with my coding) will be part of SubSonic in the future:

As you can see, this method will take any Dictionary<string, string> and add a method to it called "ToHtmlSelect()".
At first I was a little hesitant about this. I don't like UI properties and methods hanging off objects - it's muddy. But then as I thought about it - these are extenders! They live separately from the object anyway, and are only present when I "slap them on"- so I think this kind of thing is OK.
Secondly I wasn't too happy seeing HTML in code. It sort of triggers a gag reflex. But as Jon Galloway put it to me:
Dude, HTML's not going to change the way you write select boxes for a long time. I think you're OK here. And you're my hero...
Well he might not have said that last part... but I know he thinks it...
The thing to note here is the third argument in the method: "object attributes". This is ScottGu magic at work and something he shows in his MVC demos. This little bad boy allows you to pass in an anonymous type to declare any extra attributes you might want this select box to have - like "title" or "class" - simply by using new{title="This is my title", _class="MyCSSClass"}.
These attributes are then turned into an Attribute list (a simple hash) by, yep, another Extension method that hangs off the object class (you can see it there in the last line of the method).
I also created another method called "ToHtmlRadioList()" which is an extension of List<string>:
It does the same thing as the first method, above, but this time outputs a bunch of HTML Radio buttons.
Here's the whole Controller method:
A key thing to remember about these methods is that they live in an assembly that's completely reusable at any time and are not part of the class, base class, or interface - so in effect you've bottled up your UI logic far, far away from your view and are "tacking it on" when you need it. This is a good thing, and we've just removed a mess of noodles from the boiling pot.
Notice the last line? Response.Write? Keep that in mind...
Putting It Together
So now that we have these things, I can put the bits together using jQuery and the new MVC bits. The first thing I want to do is create a controller method to serve up some HTML. I can create an view page if I want, but all I need is the radio list so I'm going to go with less code and files, and just serve up the HTML. I can use JSON here - but to keep this example concise I'm going straight for the gut...
On my main view (called "Index"), I create 3 things: my select box, a button to fire the refresh, and a div to hold the results. Notice the simple one-liner for the select box? ViewData is handed off from the controller to the View page, and "Providers" is simply a Dictionary<string,string> property that's been populated in the request. I can now pop this into HTML using the Extension methods above:
Finally, hooking this up is trivial with jQuery. I'll admit I haven't used the library long enough to claim that I'm an expert - or even close. But this took all of 5 minutes to read up on and I was off doing something else!
What I want to do now is hook up my "providerSelect" button to fire a request back to the server, sending it the value in the select box above it (called "providerList"). This is easy with jQuery:
At first glance, jQuery "syntax" can be a bit scarey cause it doesn't look much like the javascript that I remember. But a quick read on the docs and you're off:
- $document.ready... is a "sugary" notation that basically means "when the document is done loading, do this stuff"
- Anything with "$(" in front of it is a jQuery "shorthand" method call. The first line after document.ready is telling jQuery to wire up my button's click event to a new function, which is declared inline
- The 4 lines that follow grab the value from the current select box, pass it to a URL which in this case is my controller method, "home/FetchTableList". The hash notation after that appends the selection to the URL
- The "load()" method is the fun part - it grabs the HTML from a request and simple pops it into the specified control. In this case it's my "tableList" div. If you recall, the controller method here is the same as above, that does a Response.Write of a radio button list :). So in this case, "load()" is simply pumping a radio button list into the div.
- The rest of the stuff is just visual sugar that makes things slide and look "Web 2.0-y".
Final Thoughts
I like this example because the view is light and nimble, and has ZERO logic in it - not one "if" anywhere and no variables. The UI is handled from a central UI class, which in this case is my Extension methods class in SubSonic.
You may be thinking to yourself
"dude, that's a lot of code for something that would take me ummmmm 5 lines using WebForms"
and that's true. But consider that
- the extension methods - which you DON'T have to write are most of the code and these don't count cause they're part of SubSonic ;).
- you would need to write the data access code anyway
- I was more verbose than I needed to be with jQuery, and everything I needed to do could be done in one line
- The HTML to support this is at least HALF of what you'd need to write for a DropDownList/RadioButtonList combo.
I, for one, can't wait until this stuff hit's CTP and I can see what these guys have been up to. Don't get me wrong, this MVC demo code is really solid - but the real stuff, I am sure, will be very fun indeed!
What other kind of SubSonic-y/MVC stuff do you want to see?
