Posted by: lluppes | September 29, 2012

Creating a ResponsAdaptive WebSite

a.k.a. How to Use Bootstrap and jQuery.Mobile with MVC4 

I’ve been hearing a lot of buzz about Bootstrap and wanted to experiment with it on my website, but I still wanted to keep the mobile look and feel that I currently had as I have documented in my book “Delivering Mobile-friendly Websites with MVC4“. My goal was to create a nice responsive site for the desktop while maintaining the jQuery.Mobile version for mobile devices, and I think I have succeeded in that. As part of that process, I created two NuGet packages that you can use to easily add these features to your own MVC4 sites.

Making it Responsive

To make things easier for future self (and for you!), I created a NuGet package with all of the pieces that you need for running Bootstrap in your MVC4 website. Create a new MVC4 project, then install the package LCI.Bootstrap.MVC4.  You could just install the Twitter.Bootstrap package, but that doesn’t give you an MVC Layout page, so this one does both with just one command.

PM> install-package LCI.Bootstrap.MVC4
Attempting to resolve dependency 'Twitter.Bootstrap (? 2.1.1)'.
Successfully installed 'Twitter.Bootstrap 2.1.1'.
Successfully installed 'LCI.Bootstrap.MVC4 1.0.0'.
Successfully added 'Twitter.Bootstrap 2.1.1' to MvcApplication1.
Successfully added 'LCI.Bootstrap.MVC4 1.0.0' to MvcApplication1.

This NuGet package will get Twitter.Bootstrap for you automatically, then create the Layout file that you need to make it work right with MVC4. It also adds a few images and a CSS file in the content folder, and a sample page with Tabs. It will automatically pop up a ReadMe file for the package walks you through the next few critical steps.

The NuGet package creates a Views\Shared\_Layout_Bootstrap.cshtml. By default, all of your pages reference the _Layout.cshtml file, so if you want your whole site to use the new layout, just rename (or delete) the existing _Layout.cshtml file and then rename the _Layout_Bootstrap.cshtml to _Layout.cshtml.

Since we are using MVC4, we need to take advantage of the new bundling feature, so I created some new bundles for the Bootstrap files. (These bundles are referenced in the _Layout file you just renamed in the previous step.)  Add the following code to your BundleConfig.cs file:  (I can’t add code to your existing files because I haven’t figured out how to make NuGet do that non-destructively yet…!)

public class BundleConfig
{
  // existing bundle code goes here...
  bundles.Add(new ScriptBundle("~/bundles/bootstrapjs").Include(
    "~/Scripts/bootstrap.js"));
  bundles.Add(new StyleBundle("~/Content/bootstrapcss").Include(
    "~/Content/bootstrap.css",
    "~/Content/SiteBootstrap.css"));
}

Bootstrap.css came with the Bootstrap package, and I added my own SiteBootstrap.css for changes and additions that I wanted to use to the styles. For example, if you want to change the color of the header, that’s defined in SiteBootstrap.css file and is simple to change.

The NuGet package also installs an example tabbed page that shows you how you can easily use features like tabs that are built into Bootstrap. I didn’t want to mess with your existing Home controller, so you will have to manually add the following lines to your HomeController.cs file:

public ActionResult Tabs()
{
  return View();
}

That’s it! Compile and run and you should see a site that looks something like this:

Bootstrap Example

Another nice sample that I’ve set up in this layout file is that it has a revolving carousel in the header so that you can have animated ads.  You can swap out “Page 1/Page 2/Page 3” for whatever pages you want to use very easily.

The Tabs Example page shows how you can easily add tabbed content with just these few lines of code:

<ul id="myTab" class="nav nav-tabs">
  <li class="active">
    <a href="#Tab1" data-toggle="tab">About the Book</a>
  </li>
  <li>
    <a href="#Tab2" data-toggle="tab">More Info</a>
  </li>
</ul>
<div id="myTabContent" class="tab-content">
  <div class="tab-pane active" id="Tab1">
    <h2>About the Book!<h2>
    ... content here ...
  </div>
  <div class="tab-pane" id="Tab2">
    <h2>More Info</h2>
    ... content here ...
  </div>
</div>

That simple code produces a tabbed page that looks like this:

Bootstrap Tabs

Making it Adaptive

Once I had the responsive part of the project in place, I wanted to make it adaptive so it returned mobile views to mobile devices. To make this a bit simpler, I created another NuGet package called LCI.jQueryMobile.MVC4 that pulls in jQuery.Mobile and creates some default mobile Layout pages for you. The ReadMe file for the package walks you through a few critical steps.

I’m taking advantage of the DisplayModeProvider technology built into MVC4, so I’ve added a new configuration file (DisplayModeConfig.cs) in the App_Start folder. You’ll need to update the Global.asax.cs file to reference function that, adding the following line:

protected void Application_Start()
{
  // existing code goes here
  DisplayModeConfig.RegisterDisplayModes();
}

The code in the DisplayModeConfig.cs file creates new display modes by looking at the UserAgent that is passed in by the web browser, then deciding which DisplayMode should be used for the current request.  Here’s an excerpt from that file that shows how it does that:

DisplayModeProvider.Instance.Modes.Insert(0,
new DefaultDisplayMode("Phone")
{
  ContextCondition = (context => ((context.GetOverriddenUserAgent() != null) &&
    (
      (context.GetOverriddenUserAgent().IndexOf("iPhone",
        StringComparison.OrdinalIgnoreCase) >= 0) ||
      (context.GetOverriddenUserAgent().IndexOf("iPod",
        StringComparison.OrdinalIgnoreCase) >= 0) ||
      (context.GetOverriddenUserAgent().IndexOf("Droid",
        StringComparison.OrdinalIgnoreCase) >= 0) ||
      (context.GetOverriddenUserAgent().IndexOf("Blackberry",
        StringComparison.OrdinalIgnoreCase) >= 0) ||
      (context.GetOverriddenUserAgent().StartsWith("Blackberry",
        StringComparison.OrdinalIgnoreCase))
    )
  ))
});

(For more information on how that works, go watch my presentation online at https://blog.luppes.com/2012/09/30/mdc201/ or check out my book!)

Just like before, we want to take advantage of the new bundling feature, so I created some new bundles for jQuery.Mobile that you will need to add to the BundleConfig.cs file:

public class BundleConfig
{
  // existing bundle code goes here...
  bundles.Add(new ScriptBundle("~/bundles/MobileJS").Include(
    "~/Scripts/jquery.mobile-{version}.js",
    "~/Scripts/jquery-{version}.js"));
  bundles.Add(new StyleBundle("~/Content/MobileCSS").Include(
    "~/Content/jquery.mobile.structure-{version}.min.css",
    "~/Content/jquery.mobile-{version}.css"));
}

Now if you browse to this site with a tablet or phone, you’ll get a page that looks like this:

jQueryMobile Example

The Result: A ResponsAdaptive WebSite

Voila! Works like a champ! There are a lot of other topics we could get in to, like using partial views to avoid replicating content, but that’s a subject for another day.  You should be able to use these two NuGet package to create your own ReponsAdaptive website in no time!

Resources

If you want to download the project I created for this post, you can get it here.

MVC4 Bootstrap NuGet Package LCI.Bootstrap.MVC4

MVC4 jQuery.Mobile NuGet Package  LCI.jQueryMobile.MVC4

If you want to learn how to make your own NuGet packages, go check out Scott Hanselman’s excellent post.

Lyle

Written by .

Advertisements

What do you think?

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: