We have always been quick to build UI controls on top of new Microsoft technologies as they emerge. A little over a year ago, we started experimenting in ASP.NET MVC. After a lot of R&D we came to some interesting conclusions. This is the story of Studio for MVC Wijmo and how it came to be...

What is Studio for MVC Wijmo?

Studio for MVC Wijmo is the ultimate tool for building rich UI in MVC. The studio includes 30 new jQuery UI widgets and Wijmo-enhanced MVC Scaffolding. We poured our heart and souls into this product and I am proud to say it is the best damn Web product I've ever used. Here are some of the highlights in the studio:

  • 30 jQuery UI Widgets
  • Interactive HTML5 Charts
  • High-performance jQuery Grid
  • 6 Premium CSS3 Themes, 24 jQuery UI Themes, and Themeroller - a custom theme builder
  • Wijmo MVC 3 Project Template
  • MVC Scaffolding automatically enhanced with Wijmo
  • Wijmo-enhanced EditorTemplates like Date Picker, Numeric Input, Slider and more

Go download the CTP and start building killer apps in MVC3!

The Story Behind Studio for MVC Wijmo

It all starts with a little decision Microsoft made to adopt jQuery and focus on it in place of their own Ajax library. This was a monumental move for them and we took note. Our Web framework at the time was a mixture of both ASP.NET AJAX and jQuery. We had been wanting to reinvent our Web technology and Microsoft's announcement about jQuery was perfect timing. Since then we have been full blown jQuery developers. We embraced the jQuery UI Widget factory and began creating what is now Wijmo. Wijmo is pure client-side UI that takes simple HTML and uses jQuery to turn it into an interactive widget. Wijmo is really powerful and it is the foundation of our new Web technology. To learn more about the story of Wijmo, check out the jQuery Podcast about it or read my intro to Wijmo article.

There is no such thing as MVC Controls

After we had a killer client-side framework we started looking at extending it in ASP.NET MVC. Well, first of all, there is no Control/Component model in ASP.NET MVC. After a little research we saw that Microsoft was saying that HtmlHelpers served that purpose. So like our competition we blindly followed and started developing HtmlHelpers for all of Wijmo. The results were disturbing. When we tried to take widgets with large Object Models and turn them into HtmlHelpers they became harder to understand and use than their jQuery counterparts. HtmlHelpers are great for things like TextBoxes, Buttons, Links, and simple "field-specific" UI pieces. They become quite verbose for "model-specific" UI pieces like a Grid for example. Let's take a look at the difference between using an HtmlHelper versus HTML and jQuery.

The Good (HTML & jQuery)

$("#flyoutmenu").wijmenu();

The Bad & Ugly (HtmlHelper)

<% Html.Wijmo().WijMenu().ID("menu1") .Add(p => { p.Text("Breaking News") .Add(c => { c.Header(true).Text("header"); }) .Add(c => { c.Text("Entertainment"); }) .Add(c => { c.Text("Politics").Url("http://www.w3schools.com/tags/html5.asp"); }) .Add(c => { c.Text("A&E"); }) .Add(c => { c.Text("Sports") .Add(d => { d.Text("Baseball"); }) .Add(d => { d.Text("Basketball"); }) .Add(d => { d.Text("A really long label would wrap nicely as you can see"); }) .Add(d => { d.Text("Swimming") .Add(e => { e.Text("High School"); }) .Add(e => { e.Text("College"); }) .Add(e => { e.Text("Professional") .Add(f => { f.Text("Mens Swimming") .Add(g => { g.Text("News"); }) .Add(g => { g.Text("Events"); }) .Add(g => { g.Text("Awards"); }) .Add(g => { g.Text("Schedule"); }) .Add(g => { g.Text("Team Members"); }) .Add(g => { g.Text("Fan Site"); }); }).Add(f => { f.Text("Womens Swimming") .Add(g => { g.Text("News"); }) .Add(g => { g.Text("Events"); }) .Add(g => { g.Text("Awards"); }) .Add(g => { g.Text("Schedule"); }) .Add(g => { g.Text("Team Members"); }) .Add(g => { g.Text("Fan Site"); }); }); }).Add(e => { e.Text("Adult Recreational"); }) .Add(e => { e.Text("Youth Recreational"); }) .Add(e => { e.Text("Senior Recreational"); }); }) .Add(d => { d.Text("Tennis"); }) .Add(d => { d.Text("Ice Skating"); }) .Add(d => { d.Text("Javascript Programming"); }) .Add(d => { d.Text("Running"); }) .Add(d => { d.Text("Walking"); }); }).Add(c => { c.Text("Local"); }) .Add(c => { c.Text("Health"); }); }).Add(p => { p.Text("Entertainment") .Add(c => { c.Text("Celebrity news"); }) .Add(c => { c.Text("Gossip"); }) .Add(c => { c.Text("Movies"); }) .Add(c => { c.Text("Music") .Add(d => { d.Text("Alternative"); }) .Add(d => { d.Text("Country"); }) .Add(d => { d.Text("Dance"); }) .Add(d => { d.Text("Electronica"); }) .Add(d => { d.Text("Metal"); }) .Add(d => { d.Text("Pop"); }) .Add(d => { d.Text("Rock") .Add(e => { e.Text("Bands") .Add(f => { f.Text("Dokken"); }); }) .Add(e => { e.Text("Fan Clubs"); }) .Add(e => { e.Text("Songs"); }); }); }) .Add(c => { c.Text("Slide shows"); }) .Add(c => { c.Text("Red carpet"); }); }).Add(p => { p.Text("Finance") .Add(c => { c.Text("Personal") .Add(d => { d.Text("Loans"); }) .Add(d => { d.Text("Savings"); }) .Add(d => { d.Text("Mortgage"); }) .Add(d => { d.Text("Debt"); }); }) .Add(c => { c.Text("Business"); }); }) .Add(p => { p.Text("Food & Cooking") .Add(c => { c.Text("Breakfast"); }) .Add(c => { c.Text("Lunch"); }) .Add(c => { c.Text("Dinner"); }) .Add(c => { c.Text("Dessert") .Add(d => { d.Text("Dump Cake"); }) .Add(d => { d.Text("Doritos"); }) .Add(d => { d.Text("Both please."); }); }); }) .Add(p => { p.Text("Lifestyle"); }) .Add(p => { p.Text("News"); }) .Add(p => { p.Text("Politics"); }) .Add(p => { p.Text("Sports") .Add(c => { c.Text("Baseball"); }) .Add(c => { c.Text("Basketball"); }) .Add(c => { c.Text("Swimming") .Add(d => { d.Text("High School"); }) .Add(d => { d.Text("College"); }) .Add(d => { d.Text("Professional") .Add(e => { e.Text("Mens Swimming") .Add(f => { f.Text("News"); }) .Add(f => { f.Text("Events"); }) .Add(f => { f.Text("Awards"); }) .Add(f => { f.Text("Schedule"); }) .Add(f => { f.Text("Team Members"); }) .Add(f => { f.Text("Fan Site"); }); }) .Add(e => { e.Text("Womens Swimming") .Add(f => { f.Text("News"); }) .Add(f => { f.Text("Events"); }) .Add(f => { f.Text("Awards"); }) .Add(f => { f.Text("Schedule"); }) .Add(f => { f.Text("Team Members"); }) .Add(f => { f.Text("Fan Site"); }); }); }) .Add(d => { d.Text("Adult Recreational"); }) .Add(d => { d.Text("Youth Recreational"); }) .Add(d => { d.Text("Senior Recreational"); }); }) .Add(c => { c.Text("Tennis"); }) .Add(c => { c.Text("Ice Skating"); }) .Add(c => { c.Text("Javascript Programming"); }) .Add(c => { c.Text("Running"); }) .Add(c => { c.Text("Walking"); }); }) .Render(); %>

HtmlHelpers should only be used to help create simple HTML! They should not create really complicated HTML that can't be changed easily. They also should not be dependent on custom UI Controllers to work. The problem I see in forcing complicated "Controls" into HtmlHelpers is that they break the MVC paradigm. As a developer using such HtmlHelpers you give up control over markup and are dependent on someone else's proprietary Controller logic for things like Paging/Sorting of a Grid for example. Our belief is that MVC developers want total control over their markup and they want to see (and modify) the code in the Controllers. We offer the best of both worlds. Our tools allow you to use existing HtmlHelpers like EditorFor and ActionLink then simply enhance them with a little bit of jQuery. We even have tools that do most of the work for you.

Embrace Web Standards!

We feel that MVC is a great new framework from Microsoft that really embraces Web standards and puts developers closer to the metal. In MVC we get to work with more HTML than in WebForms. Sure, there a little helpers here and there to make creating HTML easier, but for the most part, we are building our markup in code. I for one love this power! There is nothing being rendered that I do not have full control over. What we chose to do is follow this same concept for Studio for MVC Wijmo. We are embracing the power of HTML and jQuery. HTML is the end result in the browser so why not just work directly with it. We are also embracing Progressive Enhancement using jQuery to enhance existing markup rendered in MVC.

Tools to Help with HTML and jQuery

We want everyone to be able to code in HTML and jQuery so we also made some tools to help.

The Wijmo MVC 3 Project Template

We have created an MVC 3 Project Template that already includes Wijmo and has a bunch of pre-written jQuery to enhance anything added to the project. After installing Studio for MVC Wijmo you can create a "New MVC Wijmo Application" under .NET 4.0 C# Project Types. New Wijmo MVC3 PRoject Template The MVC Wijmo Application already includes references to jQuery, jQuery UI, Wijmo and a Premium Wijmo Theme. The Web application is also "widgetized" so anything that can be turned into a Wijmo widget is automagically done. For example the navigation menu, TextBoxes, Buttons, CheckBoxes, RadioButtons and DropDownLists will be turned into widgets. Default MVC Wijmo Application

Custom MVC Scaffolding enhanced with Wijmo

If you liked the cool new MVC Scaffolding Scott Hanselman showed off at MIX you are going to love ours! In the Wijmo Project Template we include custom MVC Scaffolding. Our scaffolding derives from Microsoft's Scaffolding from the MVC Tools Update. The difference is that ours automatically enhances the generated Views with jQuery and Wijmo. Here is the sample Model that I used to generate my To Do List app in minutes.

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Security; using System.ComponentModel.DataAnnotations;

namespace TahDo.Models { public class TahDoList { [Editable(false)] public int Id { get; set; }

    [Required]
    public string Title { get; set; }

    [Display(Name = "Date Created")]
    public DateTime? CreatedAt { get; set; }

    [Range(0, 5),UIHint("IntSlider")]
    public int Priority { get; set; }

    [Range(0, 1000000)]
    public decimal Cost { get; set; }

    [DataType(DataType.MultilineText)]
    public string Summary { get; set; }

    public bool Done { get; set; }

    [Display(Name = "Date Completed")]
    public DateTime? DoneAt { get; set; }

    public ICollection<TahDoItem> TahDoItems { get; set; }

}

public class TahDoItem
{
    [Editable(false)]
    public int Id { get; set; }

    [Required]
    public string Title { get; set; }

    [Display(Name = "Date Created")]
    public DateTime? CreatedAt { get; set; }

    [Range(0, 5), UIHint("IntSlider")]
    public int Priority { get; set; }

    [DataType(DataType.MultilineText)]
    public string Note { get; set; }

    public int TahDoListId { get; set; }

    public TahDoList TahDoList { get; set; }

    public bool Done { get; set; }

    [Display(Name = "Date Completed")]
    public DateTime? DoneAt { get; set; }
}

}

Note that this is a Entity Framework Code First approach and I have added Data Annotations to my model that will define how the DB and UI layers are generated. The Wijmo MVC Scaffolding will generate a Controller for each Model include actions for List (Index), Details, Create, Edit and Delete. It will then generate Views for List (Index), Details, Create, Edit and Delete similar to how default Views would be generated only ours are automatically enhanced with Wijmo. That's right, the JavaScript for turning the UI into widgets is autoamagically generated in every View! Here is what our List View enhanced with the Wijmo Grid looks like. Scaffolding List View powered by the Wijmo Grid And here is the Create View enhanced with the Wijmo TextBox, DropDown, CheckBox, Date Input, Numeric Input and Button. Scaffolding Create View powered by Wijmo Widgets To see the entire tutorial check out the video on Wijmo MVC Scaffolding.

Wijmo-powered EditorTemplates

We also include EditorTemplates in the Wijmo Project Template that turn EditorFor helpers into rich editors based on their data type. For instance any DateTime field will be rendered as a Date Input with a pop-up Calendar. These editors make for a much richer experience than just plain TextBoxes. DateTime EditorTemplate powered by the Wijmo Date Input IntegerSlider EditorTemplate powered by the Wijmo Slider Decimal EditorTemplate powered by the Wijmo Numeric Input

Get Started with Studio for MVC Wijmo

Everything in this post from the VSIX installer to the sample app is included in the Studio for MVC Wijmo CTP. So what are you waiting for? Stop reading and start coding!