Screenshot“Kaboom!” is one of those things you stumble upon and intrigues you from the start. It probably needs more work (not to mention documentation), but certainly gives you a peak at what I believe could be the next big thing in the ASP.NET MVC world. Having just finished a CMS system where I used a very rich JQuery client, I found this a very probable next step. Already using “jquery.forms” to submit all my forms via ajax POST and using “$.getJSON” for all my GET actions, my views started to get pretty lean. I thought, what if I had a JQuery ViewModel that would handle my UI commands and handle all my communication with my controller? A quick search lead me to “Kaboom!”.

The first thing I worried about was testability. “QUnit” (http://docs.jquery.com/QUnit) seems to be a very powerful testing framework that would probably give me more coverage than what I had before! UnitTesting – Check :)

So lets look at one of the samples in the codeplex download, specifically the Asp.Net MVC sample…

We start with a “Person” Model:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

And a “PersonController” class which has a Search action:

public class PersonsController : Controller
{
    public JsonResult Search(string searchString)
    {
        List persons = new List();
        persons.Add(new Person { FirstName = "Kozin", LastName = "Osot" });
        persons.Add(new Person { FirstName = "Setesyci", LastName = "Rynaugh" });
        persons.Add(new Person { FirstName = "Atheck", LastName = "Garash" });

        return Json(persons
            .Where(p => p.FirstName.ToLower().Contains(searchString.ToLower()) ||
                p.LastName.ToLower().Contains(searchString.ToLower())).ToList());
    }
}

Then we create a “SearchViewModel” js file and put this in our “ViewModels” folder like so:

var SearchViewModel = {
    Initialize: function(args, callback) {
        Kaboom.register("Search", SearchViewModel.Search);
        SearchViewModel.SearchResults = new Array();
        callback();
    },

    Ready: function() {
        SearchViewModel.Search();
    },

    SearchString: '',
    SearchResults: null,
    Search: function() {
        $.getJSON('/Person/Search',// You can set this as a hidden field on your View with 'Url.Action(..' and simply do $('#searchSource').val()
            { searchString: SearchViewModel.SearchString },
            SearchViewModel.PopulateSearchResults);
    },

    PopulateSearchResults: function(data) {
        SearchViewModel.SearchResults = data;
        Kaboom.notify(SearchViewModel, "SearchResults");
    }
}

And our “Search” view would hook up to our view model like so…

<head runat="server">
    <title>Search</title>
    <% string version = DateTime.Now.Ticks.ToString(); %>
    <script type="text/javascript" src="../../ViewModels/Persons/SearchViewModel.js?id=<%= version %>"></script>
    <script type="text/javascript" src="Scripts/jquery-1.3.2.js?id=<%= DateTime.Now.Ticks.ToString() %>"></script>
    <script type="text/javascript" src="Scripts/json2.js?id=<%= DateTime.Now.Ticks.ToString() %>"></script>
    <script type="text/javascript" src="Scripts/kaboom.js?id=<%= DateTime.Now.Ticks.ToString() %>"></script>

</head>
<body>
    Quick start shows how to communicate with an aspMVC controller.....<br />
    <input type="hidden" id="viewmodel" viewmodel="SearchViewModel" debug="0" />
    <div id="Debug"></div>
    Search:<br />
    <input type="text" bindto="SearchString" mode="TwoWay" /><br />
    <input type="button" value="Search" command="Search" />
    <br />
    <table bindto="SearchResults">
        <thead>
            <tr>
                <th>First Name</th>
                <th>Last Name</th>
                <th>Options</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>$FirstName</td>
                <td>$LastName</td>
                <td><a href="#" onclick="alert('$FirstName')">Delete</a></td>
            </tr>
        </tbody>
    </table>
</body>

You can bind all your view actions to commands.

<input type="button" command="Save" value="Bound to Save command via jQuery(element).click()" /><br /><br />
<input type="button" command="Save" trigger="dblclick" value="Bound to Save command via jQuery(element).dblclick()" /><br /><br />
<input type="button" command="Save" trigger="blur" value="Bound to Save command via jQuery(element).blur()" /><br /><br />
<input type="button" command="Save" trigger="customaction" value="Bound to Save command via jQuery(element).customaction()" /><br /><br />

… and it has support for other controls and more complex bindings.

<select bindto="Person.Salutation"
         datatextfield="Name"
         datavaluefield="Id"
         datasourceid="Salutations"
         onbind="ProgrammaticallyBindIt" >
   <option value="0">[select]</option>
</select>

There are loads of other examples, including binding to Tables, Divs, Spans, Checkboxes etc. You can download the framework here.