Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at cf.Objective() 2013 (Bloomington, MN) with: Elliott Sprehn and Chris Phillips and Nathan Strutz and Anant Pradhan and Dave DeVol and Byron Raines

CorMVC - My jQuery-Powered Model-View-Controller (MVC) Framework

By Ben Nadel on

A while back, I gave a presentation entitled, Building Single-Page Applications Using jQuery And ColdFusion (Video Presentation). For this presentation, I created a very small, jQuery-powered model-view-controller (MVC) framework to aide in the development of my demo application. I built this framework from scratch because I felt, at the time, that the existing jQuery frameworks were either way too complicated for me to understand or, required technologies (ie. Ruby on Rails) that I did not have on my server. I liked where my framework was going and I decided that I needed to break it out into its own project space in order for me to be able to continue thinking about it effectively.

 
 
 
 
 
 
corMVC - jQuery-powered Model-View-Controller Framework. 
 
 
 

And so, this weekend, I extracted my jQuery MVC framework from my previous presentation, dubbed it "corMVC", gave it its own project page, and built a little sample web application to demonstrate its use. CorMVC stands for, "Client-Only-Required Model-View-Controller," and is designed to be an extract-and-run learning tool for those who want to start building more complex applications. It does not presuppose any server-side technology and requires no more than a web browser to experiment with. If you want to see it in action, check out the online demo application, or watch the following video:

 
 
 
 
 
 
Video Demo Of corMVC - My jQuery-Powered Model-View-Controller Framework. 
 
 
 

Building frameworks in jQuery (or any other language for that matter) is very new to me; I don't claim to be any good at it. In fact, when I started looking into jQuery-based frameworks, I had no intention of creating my own. As I stated above, when I started to do my research, however, I quickly encountered two major problems with what was available:

  1. Most examples were so small that I could not see how they might be applied to the kind of software I build.
  2. Most frameworks were enormous and required command line utilities and some additional server-side technology (like Ruby On Rails) just to experiment with.

I didn't even know how to begin learning. So, rather than wade through what was available, I decided to try and create something from scratch. What I came up with is corMVC. The philosophies that I put into the corMVC framework are those that were hopefully a remedy to the problems I encountered above:

  • A large sample application. The whole demo site (including the contacts section) runs off of corMVC as a single-page application.
  • No server required. The demo application does not require any additional server-side technologies. If you have a web browser, you can download and run this application immediately.
  • No building required. This framework does not require you to build the application using scaffolding or any other command-line executables. You just download it and open it up in a browser.
  • Small Framework. This framework is very small (and excessively commented). It doesn't do anything more than it is supposed to.

While I want to keep the corMVC framework as small as possible, I am sure that as I begin to more fully understand the various needs of single-page applications, the framework will have to evolve as necessary. In the end though, I want the corMVC framework to be an aide and not a constraint - affording the programmer the freedom to pile their own jQuery magic on top of this foundation.




Reader Comments

@Elijah,

MVC as a concept, I completely get. MVC as a practice, I'm definitely new to. And, even more so when it comes to client-MVC practice. This project is, more than anything, a way to force *myself* to start thinking in that way.

Reply to this Comment

Thanks Ben.

This is awesome!

This holiday break will give me a perfect time to play around with it.

Don't stop doing what you do.

Reply to this Comment

@Raymond,

Any feedback would be great. Right now, this is all just theory for me as I have never had to build a single-page app in production :)

@Adam, @Shaun,

Thanks guys.

Reply to this Comment

Well done on the framework, I really like how things are structured. I actually picked it up from your presentation and use a modified version on a small project. In my case, I didn't really felt it necessary to use models and views on the client side, I preferred to just use my server model and spit out HTML via ajax, so I only kept the controller part, which to me was nice enough to justify using the framework. I may try models and views on future projects should I see the need though.

One thing I was iffy about was the way the location manager work. Your solution for allowing navigation via the url fragment is different from all the others I've seen. While I thought the use of an interval function was clever and seems to make things very simple, I wonder how efficient it is to have a function running every 150 milliseconds (or however many, don't remember for sure) and if it could become a problem at some point. Like, if you have a more processor intensive function to run and this thing is running at the same time, I wonder if it could cause some slowdown issues. Haven't run into anything myself, but wonder if you had any thoughts on that?

Reply to this Comment

@Thomas,

You're right - not all browsers would require that. Some browsers have an implicit event for hash change (or is it locationchange). What I should really do is allow browsers that can use that to use that and then only use the interval approach for browsers (IE) that don't support it.

Reply to this Comment

@Thomas
I started at the other end, only using the view structure at first and find it a great way to separate things out. From there I retrofitted the service layer into my application. The controller would be great but there's too much code already in the app to start migrating what I am working on completely. But I definitely recommend the view usage with the independant services and beans.

I haven't tried it but potentially since the contact bean is independant of the application it could also be used within server-side validation using cfgroovy2, so only define validation once which would be a nice time saver.

@Ben
Have you thought about making the application a jQuery plugin? Then you could store data using jQuery's data storage functions and also access the application/model/view/services from any jQuery function. Potentially also wrapping up some view templating functions so it could all be handled inside jQuery chains.

Reply to this Comment

Nice work. I'm very interested to play with this some and see how it works out. I'm always down for people solving their own itches and making it better for what they need.

Reply to this Comment

@Marcel,

I am not sure I understand what you mean about building the application as a plugin? Or using plugins? Because it is a jQuery-powered framework, you can certainly use the data() method to store data with given elements. But, at the application framework level, I am not sure the framework could / should not anything about that.

Reply to this Comment

@Ben
I'm just suggesting perhaps instead of:

window.application.addController((function( $, application ){
Controller.prototype = new application.Controller();

Being for jQuery users, the following would feel more natural:

jQuery.addController((function($){
Controller.prototype = $.newController()

You could then chain more like:

jQuery
.showView(...)
.getModel( "ContactService" )
.deleteContact(
id,
function(){
jQuery.getApplication().relocateTo( "contacts" );
}
)
.showView(...)

So just a semantic observation, then you could also put the whole framework on the jQuery plugins site which would provide greater exposure.

Reply to this Comment

You know who does something along these lines? lala.com Their whole site is basically a "single page" once you get there. It allows your music to keep playing while you browse the site.

Nice work on the framework, Ben.

Reply to this Comment

@Marcel,

I see what you're saying. That's an interesting idea; my concern would be that this will quickly get unwieldy with more complex business logic... I'll put my thinking cap on.

@Brandon,

Music sites seem to be the big adopters of AJAX-based architectures (and FaceBook) for this very reason - it allows music to be played non-stop. Good point.

Reply to this Comment

Hello, Ben.

This project is brilliant, I'm starting to adapt it to my own needs.

I have noticed a typo in the model "contact_service_mock", you mistyped "respsonse.errors" on lines 98, 125, 152.

Otherwise, so far so good.

Thank you for sharing this MVC!

Reply to this Comment

@Enorog,

Thanks for catching that! I'll have to make some updates to it. I kind of just put this out there; but now I need to follow up with it :)

Reply to this Comment

Ben, thanks for sharing this.

I agree with Marcel, it should be better if your framework can simply be accessed as a jQuery template, and probably this will help to spread, and improve, your work to a wider audience.

Best regards,

//Davide

Reply to this Comment

@Davide,

I'll put my thinking cap on. This was just a version one; I am sure there are many improvements that I can make.

Reply to this Comment

Ben,

Very cool and impressive. Some of your hash-routing is very similar to what Aaron Quint did with Sammy http://code.quirkey.com/sammy/

It is actually quite elegant, although some better includes to ease the including of models/views/controllers inside the SPA html file would be good.

Big question (no, not documentation, although that would be very helpful): licensing. I want to play around with it, but I don't know if your stuff is MIT, Apache, GPL, public-domain, what have you. Can you please officially release a license?

Kudos to you for this.

Reply to this Comment

@Avi,

I actually went to one of Aaron's presentations at the jQuery Conference up in Boston last year. A lot of what he said really inspired me. The one thing that I wasn't crazy about was how he separated out GET vs. POST routing; to me, that felt more naturally to leave up to the Controller objects.

All my code I put out there "as is" for anyone to use. This was just all in fun experimentation - I am not sure if you'd want to actually use it in anything significant.

I'm actually really interesting in playing around with this more, especially in the context of something like jQTouch for HTML5 mobile apps. The mobile space is so hot right now!

Reply to this Comment

@Ben
Awesome work here. This looks like a real lifesaver. How would you recommend implementing a login for an administrative area. I have an existing site that I would like to make a back end for. Do I simply create the default route "/" to be the login view if not logged in else show them the main admin dashboard? Any help with where to start would be much appreciated as I'd love to use this framework for a project I'm working on.

Also if I already have a site and would like to make the framework extend the application.cfc on the root level but only utilize corMVC on the admin section. Do I need to make the application names the same in both App.cfc's in addition to extending the component or do I simply need to incorporate any necessary vars that exist in my current onRequestStart() into your Application.cfc and then correct any framework paths.

Any help with where to start in tackling these issues would be much appreciated as I'd love to use this framework for a project I'm working on.

Tim

Reply to this Comment

@Tim,

First off, I just want to say that I build corMVC more as an experiment than anything else; I haven't had much time to really flesh it out and refine the way it works. As such, take what I say here with a grain of salt.

Handling login stuff is an interesting thing indeed! Typically, in a traditional application, we allow the page request/response life cycle to sort of handle the permissions for us. In a thick-client app, that definitely becomes a little bit more tricky as you sort of need to track it locally and remotely.

What you'll need to do is track your AJAX requests for something like a 401 Unauthorized response; and, if you get that, you need to re-route the user to some sort of a login.

How is that done? Hmm, I don't have great advice on that at this time.

Maybe what I can do is try to carve out some time to make a small sample app with this framework that does incorporate login behavior. In fact, I'd really like to do that in the context of a mobile app - something I've really been wanting to do lately.

Anyway, I know this hasn't been terribly useful; sorry I don't have anything more constructive to add at this time.

Reply to this Comment

I'm a big fan of the approach you've taken with CorMVC. I really think this is the direction that web apps are moving. There seems to be a growing desire for the dynamism of Flash but using only JavaScript, CSS, and HTML technologies.

Quick question: in the Application.prototype.getClass method, when you handle the case of returning a new instance of a cached constructor, what use-case are you handling by doing the following?

var newInstance = new (target.classes[ className ])();
target.classes[ className ].apply(newInstance, initArguments);
return newInstance;

Why not just do this?

return new (target.classes[ className ])(initArguments);

I imagine you're handling some case where you think the 'this' of the class will get messed up, but I'm not able to see what that case is.

Again, I'm really digging CorMVC. Good job.

Reply to this Comment

Palm-to-forehead!

I now see that you're just handling being able to pass initArgs to the constructor (since it's an array you have to use apply()!) and have it initialize the instance.

Reply to this Comment

@Norm,

Yeah, I believe you are correct - I needed to go apply() in order to pass along the array of arguments. Some of this is probably needlessly separated out; I think I could probably join the instances and the classes into a single collection. I think I was just feeling my way out.

I agree that the direction of the web is definitely headed in this direction. Just look at all the great stuff Google is doing.

This was my attempt to start to get my feet wet in that department; I have a LOOOOONG way to go :)

Reply to this Comment

Hi Ben,

I see this is the place to leave comments about CorMVC (ignore my contact email). I'm in the middle of pulling apart CorMVC and putting it back together. Looks nice and lightweight - only issue I have at the moment is the somewhat loose HTML in the main page - I see the non-standard use of the rel attribute is essential to the routing and navigation but I wonder if there is something similar but more standard way of doing things.

C

Reply to this Comment

Ben really great job with this I'm still wrapping my head around this, but I just had a thought. You are talking about mobile application could use this and I'd like to explore how this can be used when the webpage is saved to a mobile device like on the iPhone. Normally only a single page is saved and any links open up in safari mobile. But because this is a single page application it could be possible that it would work without the same problem. Something like using JSONP requests for data might even be doable. Think something like this is a possibility?

Anyone with iOS experience know if what I'm thinking even possible?

Reply to this Comment

@Pat,

After looking at Ben's project, I came very close to selecting it and making the changes I would need to build a mobile application. Not long after posting my comment on 11/23/2010 I opted for Backbone.js and have since published production projects using it.

You may want to explore Backbone.js.

-Aaron Greenlee

Reply to this Comment

Hi Ben, Thanks to share, it's awesome! great job dude :)
-----------------------------------
Purwokerto Web Designer & Front End Developer

Reply to this Comment

Post A Comment

You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.