Tag: HTML5
I had the pleasure of joining many of the Atlanta .NET community for the annual Atlanta Code Camp. If you didn't get a chance to join us, you missed a great time. The attendees were enthusiastic and friendly. Thanks to everyone who attended!
I promised the people who attended my sessions I'd post the slides and example code so here you are:
Mobile Web Development
Debugging the Web
This is another in my series about (hopefully) interesting JavaScript constructs that might surprise most C# developers. You can see others here: JavaScript for the C# Guy.
Back in the day I was doing some scripting in classic ASP sites (no, not classic ASP.NET) and we screamed and yelled about putting too much in the global scope. We wanted encapsulation and such and that is true today. In my C# work pretty much everything is in a class (static or otherwise) so I don't have to concern myself with it much. But in JavaScript I know there is an easily accessible global object...but it occurred to me that I don't see the "Global" object accessed much; even though it is used a bit (to hold other containers that have encapsulated code). "Why not?" I wondered.
In JavaScript you can certainly create things in the global space. In fact, in my Architecting JavaScript post from my Modern Web Development series, I show that using an 'app' object for your site can simplify a lot of things. But the app object needs to be in the global space (e.g. in the "Global" object) so everyone can get to it:
// app.js
(function (a, $) {
a.setStatusMessage = function (message) {
$('#status-message').text(message);
};
} (window.app = window.app || {}, jQuery));
This code is creating a function that passes in a global object called 'app'. This 'app' object is going to be a singleton that all scripts can add to so it is a canonical example of use of a global object since lots of code will interact with it. Great...but...in this case the code doesn't put the object in the global scope, but attaches it to 'window' object.
What does that imply? While reading up on it in the great book "Professional JavaScript for Web Developers", I found the answer. It seems that the JavaScript language supports a global object, but the spec that the web browsers use (ECMA-262) doesn't tell them how to allow access to the 'Global' object. It seems that the web browsers implement this by making "window' implement the access to the Global object. This means anything in the global space is accessible on the 'window' object. (The "window" object has a bunch of other responsibilities too, not just a alias for the Global object).
While this is true in our example, it also means that objects created in the global scope are also on window. For example:
// Some.js
var name = "foo";
function whatIsFoo() {
return name;
}
var result = window.whatIsFoo(); // works
In this example both 'whatIsFoo' and 'name' are both accessible from the window property. Makes sense (though an odd place for it IMO).
Have you run into this peculiarity?
So I've done it again. I survived another 30 minutes with Woody and Keith. Whew. We had a good conversation about the current state of Web Development and the future of XAML development.
I also got to discuss fried foods and make fun of Keith. Couldn't have been a better time. Go listen now:
I had the opportunity tonight to do a talk for the Atlanta XAML Meetup on Web Development for XAML Developers. I had fun explaining how XAML developers can use their existing skills with markup, design, data binding and data access on web page development. You can see the slides from the talk here:
If you’re interested in the code from the talk, you can get it here:
Source
Let me know what you thought!
This is the sixth of ten parts of this blog post. The topics will be:
The Problem
As you develop HTML apps, one of the issues you’ll face is that your application doesn’t come to the browser in one fell-swoop. A typical web page receives content from a number of sources. Below you can see the first bun of requests from a site (in this case MSNBC.com) as shown in Firebug:

While reducing this number and size of these requests is laudable, you will also want to take browser cache into account. In the image above, you can see that some of the assets (e.g. jquery-1.5.2.min.js) returned a status of “304 Not Modified”. This status implies that the browser found the latest version of this asset in it’s cache and didn’t need to download a new one (as it hasn’t change…or was “NOT MODIFIED” from it’s current version).
For me, this meant that I wanted two things from packaging of assets:
- Reduce the size and number of downloads whenever possible
- Let the browser cache do it’s job
What Do I Mean by Packaging?
Part of the work involved in building a web project is taking all those assets (JavaScript, style sheets and even images) and making it efficient for your pages to use. In the case of JavaScript and style sheets, you will want to both compress (i.e. minify) as well as batch (combine multiple files). So let’s talk about them separately.
Packaging Style Sheets
While most solutions for packaging assets take style sheets into account, for me I decided that the dynamic style sheet languages (LESS and SASS) do this adequately. (If you haven’t read my post on using dynamic style sheet languages, see it here.)
While using the @import declaration will merge style sheets, you may also want to minify the style sheets too. In the case of dotless (which I am using for delivering my LESS files), you can use the configuration to turn on minimizing of the style sheets:
<dotless minifyCss="false"
cache="true"
web="false" />
The minifyCss property can be turned on (usually in my Web.Release.Config file) to make the output of your LESS files to be minimized to decrease their size.
Packaging JavaScript
To help with the merging and minimizing of my JavaScript, I use a great library from Justin Etheredge (@JustinEtheredge) called SquishIt (though I won’t discuss the importance of the capital letters). This library uses commonly used open source projects to do the minimizing and merging but packages it so you can call it from ASP.NET code easily. To start off with SquishIt, I would suggest just adding it to your project via Nuget:

If you read the docs for SquishIt, Justin shows it used directly in your Razor code like so:
<!-- _Layout.cshtml -->
@using SquishIt.Framework
<!DOCTYPE html>
<html>
<head>
...
</head>
<body>
@RenderBody()
</body>
</html>
@Bundle.JavaScript()
.Add("~/scripts/jquery-1.7.1.min.js")
.Add("~/scripts/jquery-ui-1.8.17.min.js")
.Render("~/scripts/combined.js")
The idea of how this works is that you add individual scripts (or whole directories) into a bundle of related scripts. When Render is called, it determines whether to package up all the scripts into a single script (name combined.js in this case) or to leave them as separate scripts.
I find managing this kind of code in the markup makes it harder for me to maintain the code so I decided to do it as extension methods (of HtmlHelper):
public static class HelpHelpersExtensions
{
public static MvcHtmlString PackageLibs(this HtmlHelper htmlHelper)
{
var client = Bundle.JavaScript()
.Add("~/scripts/jquery-1.7.1.min.js")
.Add("~/scripts/jquery-ui-1.8.17.min.js")
.Render("~/scripts/combined.js");
return new MvcHtmlString(client);
}
}
To get this into my razor files, I simply just call the HtmlHelper extension method:
<!-- _Layout.cshtml -->
<!DOCTYPE html>
<html>
<head>
...
</head>
<body>
@RenderBody()
</body>
</html>
@Html.PackageLibs()
This works fine…except that I am packaging the minimized versions of the libraries in all cases. This will make debugging more difficult, so it would be better if I could do this differently in debug or release builds. Easy:
public static MvcHtmlString PackageLibs(this HtmlHelper htmlHelper)
{
var client = Bundle.JavaScript()
#if DEBUG
.Add("~/scripts/jquery-1.7.1.js")
.Add("~/scripts/jquery-ui-1.8.17.js")
#else
.Add("~/scripts/jquery-1.7.1.min.js")
.Add("~/scripts/jquery-ui-1.8.17.min.js")
#endif
.Render("~/scripts/combined.js");
return new MvcHtmlString(client);
}
This is better as we’re not using the minimized versions, but in release mode, I don’t want to use my local versions, but I want to rely on content delivery for very common scripts (mostly jQuery and jQuery UI). SquishIt let’s me do this by adding a CDN link (with the local link as a backup) using the AddRemote method:
public static MvcHtmlString PackageLibs(this HtmlHelper htmlHelper)
{
var client = Bundle.JavaScript()
#if DEBUG
.Add("~/scripts/jquery-1.7.1.js", )
.Add("~/scripts/jquery-ui-1.8.17.js")
#else
.AddRemote("~/scripts/jquery-1.7.1.min.js",
"http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js")
.AddRemote("~/scripts/jquery-ui-1.8.17.min.js",
"http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.17/jquery-ui.min.js")
#endif
.Render("~/scripts/combined.js");
return new MvcHtmlString(client);
}
Pretty clean so far. And as I use plugins, I’ll just add them here so all my plugins work. But one issue for me is that the Render method uses the debug flag in the web.config to determine whether it merges all the scripts into a single file. For my needs, I want the libraries to *always* be separate. To accomplish this the SquishIt framework allows you to call ForceDebug before Render:
public static MvcHtmlString PackageLibs(this HtmlHelper htmlHelper)
{
var client = Bundle.JavaScript()
#if DEBUG
.Add("~/scripts/jquery-1.7.1.js", )
.Add("~/scripts/jquery-ui-1.8.17.js")
#else
.AddRemote("~/scripts/jquery-1.7.1.min.js",
"http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js")
.AddRemote("~/scripts/jquery-ui-1.8.17.min.js",
"http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.17/jquery-ui.min.js")
#endif
.ForceDebug()
.Render("~/scripts/combined.js");
return new MvcHtmlString(client);
}
The way the works is crucial for me as I want to keep my library scripts (e.g. jQuery, jQuery UI and plugins) separate so I can gain the benefit of browser cache as much as possible. When I create a bundle of my own scripts, I go ahead and let it bundle it into a single file. In fact, for my own scripts, instead of adding the scripts one by one, I add all the scripts in the js directory:
public static MvcHtmlString PackageScripts(this HtmlHelper htmlHelper)
{
// Get a list of the scripts
var path = HttpContext.Current.Server.MapPath("~/js/");
var scripts = Directory.EnumerateFiles(path, "*.js", SearchOption.TopDirectoryOnly);
var scriptPaths = new List<string>();
foreach (var script in scripts)
{
var scriptName = Path.GetFileName(script);
// Only add the scripts that aren't generated
if (!scriptName.StartsWith("ModernWebDev"))
{
var filename = string.Concat("/js/", Path.GetFileName(script));
scriptPaths.Add(filename);
}
}
var client = Bundle.JavaScript()
.Add(scriptPaths.ToArray())
#if DEBUG
.ForceDebug()
#else
.WithMinifier<MsMinifier>()
.ForceRelease()
#endif
.Render("~/js/ModernWebDev_#.js");
return new MvcHtmlString(client);
}
The first section of method is just using System.IO to search through the directory to find all the JavaScript files to include. There are a couple of new wrinkles here near the bottom of the method though.
First, the WithMinifier method allows you to specify which minifier to use (I’ve had better luck with the Microsoft minimizer but you can use whatever one you want). In the Render method I’ve also included a pound sign (#) in the path to the merged JavaScript file. What this does is tell SquishIt to generate a unique number (I believe based on a hash of the current build) so that the generated file is versioned and as new builds are created, the new version is guaranteed to download instead from browser cache to prevent accidental old versions of code.
Be aware, that using the merging (e.g. ForceRelease) of the scripts will actually generate the ModernWebDev_#.js file in the file system. Because the code is building a list of scripts dynamically, we need to ensure that that file isn’t included in our list of scripts (as it would then become recursive and the same methods will be defined).
You may notice that since I am building all my scripts into one file, that means that all scripts will be loaded on the first and all subsequent pages. There isn’t a wrong and right here. I made the decision that loading all of it and keeping it in browser cache was easier and faster than segmenting it. But my site isn’t enormous and when you start working with very large applications you will find the need to break it up in to modules (e.g. multiple different merged scripts, probably along directories is how I’d do it).
What about ASP.NET 4’s Web Optimization Stuff?
As you may know, Microsoft (as of the writing of this article) has just released the Beta of ASP.NET MVC 4 and that includes a new stack for optimizing assets called System.Web.Optimization. There is an article that covers the basics (though it’s a little out of date) by Scott Guthrie:
http://shawnw.me/xuPcoo
I considered moving to this as it’s pretty slick and pluggable, but it was missing some key features for me:
- Packaging of groups of assets but not including them separately (the Libraries packaging is an example of this).
- No support for CDN delivery of libraries.
- Wasn’t a clear way to not minify in debug versus release mode or provide different versions for those modes.
Because of these issues, I am sticking with SquishIt (and to follow the adage that says “old code is good code”). I am sure it will improve (either by people writing plugins to it or MS fixing it) to address these issues. For many projects that don’t care about some of the control I needed, it is a great solution.
In Action
You can see it work in action with the latest version of this example:
http://wildermuth.com/downloads/modernwebdev_6.zip
This is the fourth of ten parts of this blog post. The topics will be:
Debugging
I’ve had Visual Studio open constantly on a laptop for the better part of ten years (and fifteen if you count Visual C++). I am used to setting breakpoints inside of the Visual Studio editor and pressing F5 to see what is happening.
This works in Visual Studio with JavaScript but I’ve only had a good experience doing this with Internet Explorer…and when things go wrong in other browsers, that doesn’t work effectively enough for me.
The other problem with Visual Studio debugging is that code isn’t all I want to debug. I also want to debug CSS and that is just plain nasty in Visual Studio (and don’t tell me to use Expression Web…really). So what’s a web dev to do?
The trick is to use the browser to debug. But which browser? All of them. The fact of the matter is that when you’re doing web development, you’re going to need to test your code with all four major browsers:
- Internet Explorer
- Firefox
- Chrome
- Safari
- Opera (ok, just kidding…)
I don’t test every page as I develop on all four, but once I get testers, I need all four browsers installed for when stuff doesn’t work right on a particular browser.
Getting Prepared for Debugging
Before you start, I suggest you go and get the Default Browser Switcher in the Extension Manager:

This extension will let you switch the default browser by just clicking on the toolbar:

As you can see above, I have this set to Firefox as I find that to be the easiest of the browsers to debug with. Honestly, most of the browsers are close in functionality now and some people really like the Chrome debugging experience (or even the IE one is passable), but I’ll focus on Firefox.
In Chrome, the tools are built-in but in Firefox I use the tried and true Firebug. To follow along you may need to install it. You can do this in the Add-ons option in the menu in Firefox:

Once you have Firebug installed, it will add a button to the top right of Firefox (or hitting F12 will make it appear):

Once you open Firebug, it attaches to the bottom of the browser (though you can move it or open it in a different window). A common approach is to keep it on one monitor and your browser on another if you’re using more than one monitor. I’m not, so it usually looks like this:

The arrows are pointing at the different tabs that will allow you to do different kinds of debugging. Let’s start with JavaScript.
Debugging JavaScript
To get started, let’s begin in the Script tab. Once you select the script tag, you can use the dropdown to pick which script to open:

For example, I can pick the Home.Index.js file and use the mouse to click on the line inside the click handler:

This should feel like it does in Visual Studio. At that point you can just click on the button and the breakpoint will stop as expected. You can see the code stop on the right line and even see and set Watches on the right side:

In addition to the Watch, Stack and Breakpoint tabs on the right, you can also go to the Console tab and run any JavaScript command you want (including jQuery if you like):

So you might be wondering, why not just do this in Visual Studio. The cool part is that if you find a problem, change it in Visual Studio and just hit F5 (to refresh the browser) and you’ll test the change. I have found that this workflow makes work really fast (for you VB6 guys, you’re all nodding your head). It’s pretty close to edit and continue ;)
Debugging CSS
While some people feel like CSS is a black art, using the browser can make this much easier. While in Firebug, go to the HTML tab. You can use the Element Chooser to help with this process (highlighted below):

The element chooser let’s you hover over your page and it will select the element in the HTML window for you. That will navigate to the part of the DOM that is under the cursor. This makes is relatively easy to find elements in the DOM. With the element chosen, you can see the style to the right of the window. This will show you not only the properties that the styles set for the element, but it will show you where they came from. For example, if I select the main section, I can see full style inheritance:

Most of the style comes from the #main-section rule in the Home.Index.css file, but then it uses the display property from the section rule in the Site.css, etc. This will show you where the properties are really coming from. When you see that some properties struck out, that means that further cascaded styles have overridden the value.
The really cool thing about this pane is that you can actually just edit the values and see them change in the browser. This means that I can manipulate the style in real-time. This is how I tweak most of my CSS. I change the CSS here and then just copy it into the CSS file when it’s what I want. You can select the values and change them by typing or using the arrow keys to change the values. In addition, you can add new values or disable values as you play with the values. You can see it work here:
Debugging Networking
The last common use for Firebug has been to debug what networking is happening in the browser. If you click on the “Net” tab, you can see all the requests (the page, images and network/ajax calls):

For example, on the Contact page, when I submit the form, I can see the “POST” at the top of the list. Notice the + sign. When you open it you can interrogate the Headers, post, response and cache:

You can even resend the network call if you need to quickly test a scenario (useful if the request requires a lot of steps to achieve):

Remember that since this is just a browser app, you can make changes to the code, recompile and just hit resend to test your code change. This is much easier than breakpoints in Visual Studio in my opinion.
Wrapping It Up
I know for some of you that debugging outside of Visual Studio is going to feel weird and perhaps like cheating, but once you get comfortable with it, you’ll see that the development process is going to be faster and perhaps even more enjoyable!
What do you think?
This is the third of ten parts of this blog post. The topics will be:
What’s Wrong with CSS?
If you’re going to do web development, you’ll need to learn how cascading style sheets (CSS) work. It’s a fine system for defining the look and feel of your designs but as a developer I find them more painful than necessary. Let’s discuss some of those pains.
So let’s assume I was writing a simple contact page form. So I’ll have a number of rules for the different parts of the form (I would probably not have rules specifically for the contact form, but have a common set of rules, but for this example it’s good enough):

It’s plain enough, so let’s make it pretty with some CSS:
/* home-contact.css */
h2
{
font-style: italic;
color: #222;
}
.big-form input[type=text]
{
width: 300px;
height: 25px;
padding: 5px;
border-radius: 5px;
border: 1px black solid;
background-color: #EEE;
color: #222;
margin: 2px 0;
font-size: 18px;
}
.big-form label
{
color: #222;
font-size: 14px;
}
This works, but there are some common problems with this including repeating of values, repeating of selector syntax, no good way to handle shims or polyfills as well as no way to calculate values. In this way, CSS is purely content and presents maintenance issues.
A Better CSS?
To the rescue are dynamic stylesheet languages. Among these are:
- Less: Client-side or server-side supported language for solving stylesheet problems.
- Sass: Command-line or server-side supported language for solving stylesheet problems.
Both of these languages are similar in scope as they support features like:
- Nested Styles
- Variables
- Mixins
They are both great languages the key importance here is that you should stop writing plain old CSS and use a dynamic stylesheet language.
While Sass is a bit more powerful, I decided on Less as I found it easier to integrate with ASP.NET MVC. There are a number of ways to do this, but for me the least amount of friction came with a simple package I could install to my web project called dotless. This project can be installed via Nuget:

Dotless installs a http handler so that if you refer to .less files in your stylesheet declarations, it returns the generated CSS. Some might prefer to compile to .css at compile time, but since the .js can be changed at runtime too, I though this was the best mix of the two solutions. So let’s see how LESS can fix this for us.
Getting Less Working in ASP.NET MVC
One of the basic concepts around these dynamic stylesheet languages is that CSS is completely valid. So if I change my .css file to .less (and change the link to point to the .less file instead):
@* Contact.cshmtl *@
@model ModernWebDev.Models.SomeFormModel
@{
ViewBag.Title = "Contact Us!";
}
@section Stylesheets
{
<link rel="stylesheet" href="@Url.Content("~/Content/Home.Contact.less")" />
}
<h2>
Contact</h2>
...
At this point the page still works because the new .less stylesheet is returned as the CSS it contains. Let’s refactor the CSS to use some of our new found power.
Refactoring the CSS with Less
The first change I want to make is to centralize the text color so that if I change it, I don’t have to search and replace. Less has the concept of variables. These variables start with the ‘@’ symbol like so:
@variable_name: value;
This means it can add a variable to hold our color at the top of our less file and use it everywhere:
/* home-contact.less */
@text-color: #222;
h2
{
font-style: italic;
color: @text-color;
}
.big-form input[type=text]
{
width: 300px;
height: 25px;
padding: 5px;
border-radius: 5px;
border: 1px black solid;
background-color: #EEE;
color: @text-color;
margin: 2px 0;
font-size: 18px;
}
.big-form label
{
color: @text-color;
font-size: 14px;
}
While the variables tend to be constants, you can perform operations on them too. For example, I could use another variable to store the base size of my font then use operations to change the value as necessary:
/* home-contact.less */
@text-color: #222;
@base-font-size: 14px;
h2
{
font-style: italic;
color: @text-color;
}
.big-form input[type=text]
{
width: 300px;
height: 25px;
padding: 5px;
border-radius: 5px;
border: 1px black solid;
background-color: #EEE;
color: @text-color;
margin: 2px 0;
font-size: @base-font-size + 4;
}
.big-form label
{
color: @text-color;
font-size: @base-font-size;
}
Line 21 is the magical line here. Notice that we’re saying that the size of the textbox text is going to be 4 larger than the base font, whatever that ends up being. Less can infer many types of operations and data types. For example, all of these work fine:
@aColor: Blue;
@aDarkerColor: @aColor + 80%;
@font-size: 14px;
@large-font-size: @font-size + 4;
@huge-font-size: @font-size + 8px;
Next thing is nested rules. Instead of repeating the name of the class (.big-form), less can nest it so that the nested styles will include the class name like so:
/* home-contact.less */
@text-color: #222;
@base-font-size: 14px;
h2
{
font-style: italic;
color: @text-color;
}
.big-form
{
input[type=text]
{
width: 300px;
height: 25px;
padding: 5px;
border-radius: 5px;
border: 1px black solid;
background-color: #EEE;
color: @text-color;
margin: 2px 0;
font-size: @base-font-size + 4;
}
label
{
color: @text-color;
font-size: @base-font-size;
}
}
While this is a whole lot more readable, it generates the right CSS to do the job that is implied. The CSS will include the duplication but this will be much easier to read and maintain.
We can also support mixins. The idea of mixins is to allow function-like syntax to add one or more properties. Mixins are defined with a ‘.’ to start then a name and parameter list. A simple mixin could be:
.solid-border()
{
border: 1px black solid;
}
This allows us to use it in a rule and everything inside it is dumped in the rule:
.big-form
{
input[type=text]
{
.solid-border();
//...
}
// ...
}
This results in the border line being added to the input. A great reason to use mixins is to handle cross-browser css like border-radius:
.rounded-corners-all(@size) {
border-radius: @size;
-webkit-border-radius: @size;
-moz-border-radius: @size;
}
Notice that the @size variable is in the parameter list then used in the mixin. It can be used to leave size information in the rule like so:
.big-form
{
input[type=text]
{
.rounded-corners-all(5px);
.solid-border();
//...
}
}
This will result in all three values being put in the rule with a size of 5px. But what’s interesting is that if the value passed in is multi-values, it can still accept it as a single value for example:
.big-form
{
input[type=text]
{
.rounded-corners-all(5px 10px 5px 15px);
//...
}
}
This works fine because the language knows that without any commas it should be treated as one value.
We’re getting close to a good solution, but we have all this information in one less file and it hurts its reuse. So we should refactor into several files moving the colors and mixins into their own files. Less has an interesting concept of import. If we move the colors and mixins to their own files, we can then use @import to pull in these other files:
/* home-contact.less */
@import "colors"; // will find .less if it exists
@import "mixins"; // otherwise will drop to css
@import "site.css"; // importing css is fine too
By specifying the import without the extension, it will try and find a .less file or fallback to a .css file. This way as you refactor into .less you don’t have to go fix up names as you need less features (pun intended).
This import will bring in complete .css files as well. The import here doesn’t just refer to the imported files but actually merges them into the file for you. So the resulting .less file contains all of the imported files. This means that you can build your CSS modularly without having to worry about the number of stylesheets that the browser can handle.
Debugging Less
Finally, sometimes you just need to see what is happening after processing. The easiest way to see this is to just browse to the .less file:

You can see this all working the working progress of the source code:
What do you think?

I am excited to announce that I’ve refactored (and renamed) my web-centric training course. The old “ASP.NET MVC/HTML/CSS Workshop” was just too long. It’s now called “The Web Workshop”.
This course is concentrating on client-development for the browser. The course will cover client-side development for HTML/JavaScript/CSS development including browser-based sites and mobile browser development. While the course will cover using ASP.NET MVC 3 for doing the server-side code, the focus of the course will be in the client development. This means most of the course will cover the new skills that web developers need including:
- Learning JavaScript
- Using jQuery (and associated plugins)
- Design with HTML5 and CSS3
- How to build pages for mobile browsers
- Working with REST/JSON data
On the server, the course covers the crucial server-side skills:
- Building Controllers and Views
- Unit Testing in ASP.NET MVC
- Exposing Data to JavaScript via ASP.NET MVC
We are holding the first class in Atlanta (GA) February 27-29th if you’re ready to learn how to build create HTML-based clients. There is an early-bird discount of $300 off the course if you sign up by January 30th.
NOTE: While the course could help you build Windows 8 Metro-style apps with JavaScript – it is not specifically covered in the course. We will have a Windows 8 Metro-style courses after the beta!
This is the second of ten parts. The topics will be:
Architecting JavaScript
Working with JavaScript can be daunting. In the past, I’ve seen some projects with just a handful of huge files that become difficult to manage. So in architecting what I needed to build, I wanted to adhere to the idea that there was common code and there was view-specific code. There are two different classes of JavaScript that I care about: libraries (i.e. not my code) and site code (i.e. my code).
For now, let’s segregate these two types of code into separate directories as shown below:

The scheme of these directories doesn’t matter, but I decided on keeping the Scripts directory since Nuget packages like to update to the Scripts folder. You’ll see in a later post when I talk about packaging why I separate these. Most of the time I am ignoring “not my code” and opening “my code” quite a lot.
One strategy I’m using is to load all the scripts on every page. Our total size of my scripts is not enormous and I expect that the initial hit of caching the script(s) on the first page will mean that subsequent pages will be faster. I’ll talk about how we are going to package the scripts in a later part of this series, but for now I can just include all the scripts of our project in the ‘master page’ (i.e. _Layout view):
<!-- _Layout.cshtml -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>@ViewBag.Title</title>
<link href="@Url.Content("~/Content/Site.css")"
rel="stylesheet"
type="text/css" />
@RenderSection("StyleSheets", required: false)
</head>
<body>
@RenderBody()
</body>
</html>
<!-- We'll use a packager later, don't freak out guys -->
<script src="@Url.Content("~/Scripts/jquery-1.7.1.min.js")"
type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/modernizr-2.0.6-development-only.js")"
type="text/javascript"></script>
<script src="@Url.Content("~/js/mwd.js")"
type="text/javascript"></script>
<script src="@Url.Content("~/js/Home.Index.js")"
type="text/javascript"></script>
This means that each page doesn’t need to add their own scripts (in fact, when I package them, I’ll just include all the scripts in the /js/ directory). This should result in less friction at the cost of an initial page load of a larger script which I am not worried about for desktop use (for mobile, I’ll change this strategy as you’ll see in a later part of the series).
Originally I had planned on having a script per page (if necessary) then just including it on the pages required but that meant I needed to be aware of code collisions and inclusion on each page. To combat this a JavaScript namespace can help segment all of my code in it’s own object so I don’t pollute the global namespace. This is just like in .NET where you will create namespaces for your classes. Though JavaScript doesn’t have a namespace as such so a named object is good enough to do the trick:
// mwd.js
(function (m, $) {
m.setStatusMessage = function (message) {
$('#status-message').text(message);
}
} (window.mwd = window.mwd || {}, jQuery));
This works because of line 7 (highlighted). It executes this anonymous function creating the “mwd” object if it doesn’t exist. It passes in this object (as the m variable) so I can add any global data/functions to the object. The first script to run will not find the ‘window.mwd’ object so it will create a brand new object. Subsequent scripts (which will also have this function wrapper around it) will find the ‘mwd’ object and just pass it in. This way every script that uses this convention will add to the namespace object with our code and data. This simplifies the problem of script loading ordering problems and prevent name collision with objects in the global namespace. You can see that in the above that the mwd object is having a new function added to it. Since it’s an object on the window object, we can access this function from any script but only exposing a single global object.
For page specific code, the function wrapper is still used:
// home.index.js
(function (m, $, undefined) {
m.initHomeIndex = function () {
$("#main-section button").on("click", function () {
m.setStatusMessage("clicked");
// This works too
//mwd.setStatusMessage("clicked");
});
};
} (window.mwd = window.mwd || {}, jQuery));
This approach of using an initialization function works as this script just registers the startup function for this page but doesn’t call it. This allows me to call the script on my individual page. This is especially helpful if I need to send in some state to the initialization (i.e. some data from the controller).
You can see the highlighted line is calling a common function that is defined in a different .js file (the mwd.js) and this just works as this code isn’t executed until after all the extensions to the mwd object are already added by all the scripts.
My method for calling the initialization function is to use an optional section on the Layout view that wraps whatever the individual page uses for an initialization (though not all pages will need initialization functions):
<!-- _Layout.cshtml -->
...
<!-- I'll use a packager later, don't freak out guys -->
<script src="@Url.Content("~/Scripts/jquery-1.7.1.min.js")"
type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/modernizr-2.0.6-development-only.js")"
type="text/javascript"></script>
<script src="@Url.Content("~/js/mwd.js")"
type="text/javascript"></script>
<script src="@Url.Content("~/js/Home.Index.js")"
type="text/javascript"></script>
@if (IsSectionDefined("Init"))
{
<script type="text/javascript">
$(document).ready(function() {
@RenderSection("Init", required: false)
});
</script>
}
This way if the Init section is defined on a view, I wrap the init code in a jQuery ready call so that it gets called once the page has loaded. The individual view looks like so:
@{
ViewBag.Title = "Index";
}
@section Stylesheets
{
<link rel="stylesheet" href="@Url.Content("~/Content/Home.Index.css")" />
}
@section Init
{
mwd.initHomeIndex();
}
<h2>
Index</h2>
<section id="main-section">
<div>
This is a client-side example!</div>
<button>
Show Message</button>
</section>
<footer>
<div id="status-message"></div>
</footer>
If this were a strongly typed view I could have send date into the initHomeIndex function by JSON serializing onto the page. This allows me to efficiently have my view code added to every view but only call it on the particular views I need it. This is not just for calls that are necessary per view, but could be any shared code as well.
There are other strategies for doing this (as Dave Ward (@encosia) explained using a class on a body tag with the controller and view name) but for our needs this was the most straightforward since we needed initialization data on a number of different views.
This is a pretty universal way of handling this that worked well for me. One thing I ran into was that our Layout view wanted to have some code/markup that was only to be used during release builds (i.e. Google Analytics), I was surprised that Razor didn’t allow me to test for #DEBUG builds. To fix this, I added an extension method to the HtmlHelper class:
using System.Web.Mvc;
namespace ModernWebDev.Helpers
{
public static class HelpHelpersExtensions
{
public static bool IsDebug(this HtmlHelper htmlHelper)
{
#if DEBUG
return true;
#else
return false;
#endif
}
}
}
As this HtmlHelpersExtensions class would probably be a placeholder for a number of extensions for our use, I changed the web.config in the Views directory (not the site-wide one) to include my Helpers namespace on every view:
<?xml version="1.0"?>
<configuration>
...
<system.web.webPages.razor>
<host factoryType="..." />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="ModernWebDev.Helpers" />
</namespaces>
</pages>
</system.web.webPages.razor>
...
</configuration>
This in a convenience and not necessary, but knowing you can add namespaces to every razor view is a great help so you don’t have to annotate a number of @using statements at the top of every view.
I could then use the new extension method to have conditional code in our Layout view:
<!-- _Layout.cshtml -->
...
@if (!Html.IsDebug())
{
<div>Placeholder for Google Analytics</div>
}
What I’ve shown you so far may have some of you scratching your head because the separation of these JavaScript files means that you’re probably not getting any intellisense. I made a decision to just forgo it. If Intellisense is crucial to you, there are some options (none of these were worth my trouble):
- Adding a comment on top of every .js file to the Visual Studio intellisense file to get jQuery intellisense but it didn’t help with overall intellisense.
- Using a 3rd party plugin (i.e. R#) to add the intellisense.
- Use a non-Visual Studio editor (i.e. WebStorm or other editors)
All of these are adequate solutions, but they all seemed to slow down my development and I am an old guy who can get by without it. YMMV.
Much of the process of writing the JavaScript can’t be adequately summarized until we get to the debugging process I used in this project which I will cover in the next part of this series. Good hunting!
Here’s a link to the version of the source code so far:
This is the first of ten parts of this blog post. The topics will be:
In the past year I’ve had a side project. FirstInked’s Beta recently shipped and I wanted to share with you what I’ve learned. To start out, I want to specifically thank two people who were really great in helping me formulate the strategies I’ll talk about. They are:
- Dave Ward (@encosia) answered every twitter pleading with great advice.
- Chris Rauber (@chrisrauber) was instrumental in doing the initial groundwork on the web project.
Where I Came From
I am not new to website development, but with most of my work taking me into the RIA space five years ago, a lot had changed in the interim. Back 10 years ago, much of the web code I saw and wrote looked a lot like this (and no, my blog code doesn’t look like this):
<html>
<head>
<script type="text/javascript">
function onInit() {
var obj = document.getElementById("foo");
foo.display = "block";
}
</script>
<head>
<body onload="onInit()">
<div id="foo" style="display: none" height="100px">
<font size="3" color="red">Hello World</font>
</div>
</body>
The mixing of the code, markup and styling was the de facto style back then but that doesn’t mean it was a good idea. It was easier with ASP.NET (classic) to do things this way. I relied a lot more on post-backs than client-side code which wasn’t the best experience for users. Something had to give.
What Has Changed?
While I’ve dabbled in Routing and MVC for the server-side code, I hadn’t gotten knee deep into the client-side richness now possible with the likes of jQuery and CSS3. ASP.NET MVC 3 has a lot to offer the web developer, but for this article series I am going to focus in on the client-side story since that is where most of the big changes are (at least in my eyes). I found that in building FirstInked that I spent about 20% of my time on the server code and the other 80% on the client code. This number is undoubtedly skewed by the fact that I am super comfortable with the server code and was learning the client code. But I think those numbers indicate a larger sense of what is happening. If your site isn’t about just displaying information (e.g. just information like a news site or blog) that you will be creating a lot more client-code than back in the first generation of web applications.
An Example
To set some context, let’s take a quick example and build a simple home page using the tools I’ll be talking about.
To start out, I create a new ASP.NET MVC 3 Project. This opens the “New ASP.NET MVC 3 Project” template page:

For any new development I do, I start with an empty project (though the Internet Application can be used if you want authentication and some basic start pages). I will be using Razor and HTML5 so I want to pick both the View Engine and make sure I click the “Use HTML5 semantic markup” checkbox. You can create a unit test project if you like (and you should) but I am going to skip that part for this series.
I start with a simple ASP.NET MVC 3 Empty project (for simplicity). The empty project has no controllers or views yet (though it has a _Layout…e.g. master page using HTML5). I want to clean up the project to be ready for what I want to build.
First, I look in the Scripts folder to see what scripts were added to the project by default. As I won’t be using any of the Microsoft AJAX stuff, I delete them:

I am relying completely on the jQuery stack for my development so the Microsoft scripts aren’t needed.
The next thing I do is upgrade the version of jQuery. The stock ASP.NET MVC 3 ships with the 1.5.1 version of jQuery but using the package manager (assuming you’re using Nuget, which if you aren’t you should be) you can just upgrade both jQuery and jQuery UI which I will use extensively. When you open the “Manage NuGet Packages” dialog, you will want to click on “Updates” to update some of the built-in packages:

I always update the JQuery UI library (since that will update the jQuery library too). You may want to update all the packages, but these are the two that are key to what we’ll talk about. Now that we’ve updated the packages, we’ll need to update the versions on the layout page:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>@ViewBag.Title</title>
<link href="@Url.Content("~/Content/Site.css")"
rel="stylesheet"
type="text/css" />
<script src="@Url.Content("~/Scripts/jquery-1.7.1.min.js")"
type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/modernizr-2.0.6-development.min.js")"
type="text/javascript"></script>
</head>
<body>
@RenderBody()
</body>
</html>
Now that I have the project ready, I want to add a new controller so I right-click the controller folder and add a new Controller:

For my needs I want an empty controller (as the scaffolding of a model doesn’t make sense for this simple example):

This results in a new controller file with a single result for “Index”. To create the view I need to right-click the Index method and pick AddView:

This will bring up the Add View Dialog:

I am leaving the view name so that the controller will find this view when I navigate to it. Again, I am only using Razor for my code so I leave that too. If I were using a model class, I’d use a strongly-typed view but for my needs, no model class. Finally, I want to use MVC 3’s Layout class so I leave the master page empty. This leaves us with a very simple home view razor file:
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
I am going to focus on the client-side so I won’t put much razor syntax in this file. I have found that keeping a per-view .js and .css file for each page that requires it (not every page will require specialized styling or code, but for this example, I’ll use both). So my new razor file is:
@{
ViewBag.Title = "Index";
}
<link rel="stylesheet"
href="@Url.Content("~/Content/Home.Index.css")" />
<h2>
Index</h2>
<section id="main-section">
<div>
This is a client-side example!</div>
<button>
Click me to add some elements!</button>
</section>
<script type="text/javascript"
src="@Url.Content("~/Scripts/Home.Index.js")"></script>
(For you MVC veterans, you are already thinking ahead, be patient and stop trying to fix problems…we’re going to get to it.)
This is a big part of what I want to show is that separating the concerns into structure, look and code (e.g. Markup, CSS and JavaScript).
Since I am using jQuery, my JavaScript will just add some event handlers via jQuery in the document ready handler:
$(document).ready(function () {
$("#main-section button").on("click", function () {
$("#main-section").append("<div>New Div</div>");
});
});
(Again, if you’re a jQuery veteran…wait for the bigger picture in upcoming posts…promise!)
Finally, I will style the page with some CSS:
#main-section
{
font-size: 85%;
border: black 1px solid;
background-color: #ddd;
width: 85%;
margin-left: auto;
margin-right: auto;
}
Putting this all together, we get a page that handles the mouse click and some basic styling:

You’ll notice that I named the JavaScript and the CSS based on the view and that’s mostly for discoverability while I am doing development. These scripts/stylesheets will be in addition to site-wide scripts and we’ll see later a better way of architecting this. But the general idea to take from this first part is that each view/partialview will consist of mostly these three parts:
- Markup (HTML/Razor)
- Design (CSS)
- Code (JavaScript)
My goal is to finish this series in the next couple of weeks so keep an eye on a part every 2-3 days. You can get the source for what we have so far here: