Bootstrapping Mvc - Say No to Checkboxes

We’re diving deeper today and getting to some of the good stuff, in particular, we’re going to start muxing the best of Bootstrap (the jQuery plugins) with some of the framework features Mvc has to offer.  Again, I’m working through the CSS and JavaScript library called “Bootstrap” from Twitter, and munging it in with Asp.Net’s Mvc Framework using Visual Studio 2012 RC.

The default display templates for boolean property values can be quite different – nullables are rendered as drop downs, non-nullable bools are checkboxes – but we have the ability to override the Framework and change the way these are rendered.  This video walks you through, and of course, you can download the code from GitHub on this project’s page. You can also keep up with this entire series from the intro page, where I’m listing all of the posts related to these posts.

Here’s today’s entry:

The video is in HD, so make sure you full-screen-a-size-it to see the code.  Speaking of code…

The Code That Makes it Tick

What I did for this post was override the default templates in MVC that are used to render boolean properties. If you use DisplayFor and EditorFor explicitly in your views, or if you use the scaffolders that are part of the MVC tooling, then you may be familiar with the controls that are rendered. They are fine, but they just don’t look like the rest of our site when we’re using Bootstrap.

For our DisplayTemplate, I’m using Bootstrap’s label classes on spans. You can’t edit the properties when you’re in ‘display’ mode anyways, so let’s try to pretty it up a bit.  Put this code in a partial view called Boolean.cshtml under Views/Shared/DisplayTemplates:

@model bool?

@if (Model.HasValue)
    if (Model.Value)
        { <span class="label label-success">Yes</span> }
        { <span class="label label-important">No</span> }
    { <span class="label label-inverse">Not Set</span> }


And for the editor, in EditorTemplates, you’ll need a Boolean.cshtml partial view as well. Here, we’re setting up some vars that will allow us to make use of the new nullable class attributes in MVC4.  Then, we render yes/no buttons and conditionally render the “do not set” button based on the field’s metadata.

    @model bool?

        // make use of MVC4 nullable class attribute values
        var yesSelected = Model.HasValue && Model.Value ? "active" : null ;
        var noSelected = Model.HasValue && !Model.Value ? "active" : null;
        var noSelection = !Model.HasValue ? "active" : null;   

        // get the name of the ID - this is to support multiple fields     
        var htmlField = ViewData.TemplateInfo.HtmlFieldPrefix;

    @Html.HiddenFor(model => model)

    <div class="btn-group" data-toggle="buttons-radio">
        <button type="button" class="btn btn-info @yesSelected bool-@htmlField" onclick="javascript:$('#@htmlField').val(true);" >Yes</button>
        <button type="button" class="btn btn-info @noSelected bool-@htmlField" onclick="javascript:$('#@htmlField').val(false);" >No</button>

        @if (ViewData.ModelMetadata.IsNullableValueType)
            { <button type="button" class="btn btn-info @noSelection bool-@htmlField" onclick="javascript:$('#@htmlField').val('');" >Do Not Set</button> }


Wrapping Up

Again, the project is on GitHub for you to follow along or experiment, but it’s very easy to File –> New Project and follow along with the video.  We’re going to keep working through the jQuery plugins and find uses – contrived if we have to! – for each one.

If you don’t already have a copy of Visual Studio 2012, get it here.  Happy coding!