<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://weblogs.asp.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Dan Wahlin's WebLog : HTML5</title><link>http://weblogs.asp.net/dwahlin/archive/tags/HTML5/default.aspx</link><description>Tags: HTML5</description><dc:language>en</dc:language><generator>CommunityServer 2007 SP1 (Build: 20510.895)</generator><item><title>Building an HTML5 Web Sockets Server with ASP.NET 4.5</title><link>http://weblogs.asp.net/dwahlin/archive/2013/04/13/building-an-html5-web-sockets-server-with-asp-net-4-5.aspx</link><pubDate>Sat, 13 Apr 2013 22:08:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:10152809</guid><dc:creator>dwahlin</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/dwahlin/rsscomments.aspx?PostID=10152809</wfw:commentRss><comments>http://weblogs.asp.net/dwahlin/archive/2013/04/13/building-an-html5-web-sockets-server-with-asp-net-4-5.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_1F239776.png"&gt;&lt;img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: right; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" align="right" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_498FC893.png" width="152" height="152" /&gt;&lt;/a&gt;ASP.NET 4.5 now includes support for HTML5 Web Sockets which can provide a great way to add real-time communication to a Web app where a server can actually push data live to one or more clients. In this video from the &lt;a href="http://pluralsight.com/training/Courses/TableOfContents/aspnet-webforms45-new-features" target="_blank"&gt;New Features in ASP.NET 4.5&lt;/a&gt; Pluralsight course I walk through getting started with creating a Web Sockets server using a Nuget package from Microsoft called &lt;a href="http://nuget.org/packages/Microsoft.WebSockets/" target="_blank"&gt;Microsoft.WebSockets&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;Learn to Use ASP.NET 4.5 Web Sockets - The Easy Way&lt;/h2&gt;  &lt;br /&gt;&lt;iframe height="480" src="http://www.youtube.com/embed/RKzxOUeVrIU" frameborder="0" width="640" allowfullscreen="allowfullscreen"&gt;&lt;/iframe&gt;  &lt;br /&gt;  &lt;br /&gt;  &lt;br /&gt;If you'd like to learn more about the new features in the 4.5 release and in Visual Studio 2012 check out my &lt;a href="http://pluralsight.com/training/Courses/TableOfContents/aspnet-webforms45-new-features" target="_blank"&gt;Pluralsight course&lt;/a&gt;.   &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://pluralsight.com/training/Courses/TableOfContents/aspnet-webforms45-new-features" target="_blank"&gt;&lt;img style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; padding-right: 0px" border="0" src="http://weblogs.asp.net/blogs/dwahlin/image_7668CFF2.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;br /&gt;
&lt;br /&gt;
Download samples of using the "raw" ASP.NET support for Web Sockets as well as the Microsoft.WebSockets support &lt;a href="https://dl.dropboxusercontent.com/u/6037348/HTML5AndJavaScript/WebSockets.zip"&gt;here&lt;/a&gt;. I've also included a Node.js sample for anyone who may be interested.
&lt;br /&gt;
&lt;br /&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=10152809" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/dwahlin/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/HTML5/default.aspx">HTML5</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/Websockets/default.aspx">Websockets</category></item><item><title>Video Tutorial: AngularJS Fundamentals in 60-ish Minutes</title><link>http://weblogs.asp.net/dwahlin/archive/2013/04/12/video-tutorial-angularjs-fundamentals-in-60-ish-minutes.aspx</link><pubDate>Sat, 13 Apr 2013 03:07:28 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:10146910</guid><dc:creator>dwahlin</dc:creator><slash:comments>11</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/dwahlin/rsscomments.aspx?PostID=10146910</wfw:commentRss><comments>http://weblogs.asp.net/dwahlin/archive/2013/04/12/video-tutorial-angularjs-fundamentals-in-60-ish-minutes.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_3E5C0C5B.png"&gt;&lt;img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: right; padding-top: 0px; padding-left: 0px; margin: 0px 0px 0px 15px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" align="right" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_325A1C27.png" width="290" height="108" /&gt;&lt;/a&gt;The term &amp;quot;Single Page Application&amp;quot; (&lt;a href="http://en.wikipedia.org/wiki/Single_page_application" target="_blank"&gt;SPA&lt;/a&gt;) is one of the biggest buzz words out there right now especially when it comes to building client-centric applications. SPAs provide a great way to load different views into a screen without reloading everything from scratch. When done right, true SPAs have support for history, routing, page lifecycle management, two-way data binding and more. How you get started with SPAs though? Do you go down the road of building 100% custom SPA applications or rely on a framework? &lt;/p&gt;  &lt;p&gt;I've debated that question a lot over the past year and preached (pretty strongly) that building a SPA from scratch just doesn't make any sense if productivity and maintenance are important to you. It may not be an issue for smaller apps but for larger, enterprise-scale apps with multiple screens, custom business rules and a plethora of other features &lt;em&gt;custom&lt;/em&gt; SPAs just don't make sense in my opinion. If you work on a team with multiple developers all having different skill levels then you can imagine what it'd be like to have everyone contributing custom code that doesn't have any consistency across it. In the long-run it becomes a maintenance nightmare especially if there isn't any documentation or tests available (which is bad I realize). Add in several 3rd party libraries and the problem can get even worse especially over time as new versions of scripts are released and others become stale.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_71B7CFB7.png"&gt;&lt;img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: left; padding-top: 0px; padding-left: 0px; margin: 0px 15px 0px 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" align="left" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_1C2400D5.png" width="235" height="236" /&gt;&lt;/a&gt;The good news is that several different SPA frameworks have appeared on the scene that can greatly simplify the process of building SPAs while also making maintenance easier. One of the SPA frameworks that I really like is &lt;a href="http://angularjs.org" target="_blank"&gt;AngularJS&lt;/a&gt; since it provides a robust set of features that can be used out-of-the-box without having to be an expert in routing, history, data binding and more. It provides a solid base that you can build on top of. The challenge that I hear from many people though is that &amp;quot;AngularJS has a steep learning curve!&amp;quot;. I just gave a talk on AngularJS at the &lt;a href="http://anglebrackets.org/" target="_blank"&gt;AngleBrackets&lt;/a&gt; conference in Las Vegas and heard this statement from several people. To be real honest, I felt the same way the first time I looked at it. However, the more I dug in the more I realized how powerful the framework was and all of the ways it could enhance productivity while simplifying maintenance. &lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_7B9CC122.png"&gt;&lt;img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: right; padding-top: 0px; padding-left: 0px; margin: 10px 0px 0px 15px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" align="right" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_16D51A24.png" width="288" height="180" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Before moving on I should mention that I also like the &lt;a href="http://durandaljs.com/" target="_blank"&gt;Durandal&lt;/a&gt; SPA framework too - it has robust functionality built-in as well and is definitely worth checking out.&lt;/p&gt;  &lt;p&gt;To help break down the learning curve I've put together a short video series titled &amp;quot;AngularJS Fundamentals in 60-ish Minutes&amp;quot; (I added &amp;quot;ish&amp;quot; because it ended up being more than 60 minutes :-)). In the video you'll learn how to get started with the AngularJS framework and some of the key features it provides that simplify SPA development. You'll see how to use directives, filters and data binding techniques to capture and display data. Next up is views, controllers and scope and the role they play followed by a discussion of modules, routes and factories/services. At the end of the video a sample application built using AngularJS is shown. I hope you enjoy the video and that it helps jumpstart your AngularJS learning process!&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;AngularJS Fundamentals in 60-ish Minutes&lt;/h1&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Watch the complete video tutorial here or choose specific sections from the video below.&lt;/p&gt;  &lt;br /&gt;&lt;iframe height="480" src="http://www.youtube.com/embed/i9MHigUZKEM" frameborder="0" width="640" allowfullscreen="allowfullscreen"&gt;&lt;/iframe&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;Jump to a Specific Section:&lt;/h2&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=0g_KpX08T4c" target="_blank"&gt;Introduction to AngularJS&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=_kux-YQujjM" target="_blank"&gt;Getting Started with AngularJS Features&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=LFEHq8YANLI" target="_blank"&gt;Directives, Filters and Data Binding&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=Uj-KLCTsQrw" target="_blank"&gt;Views, Controllers and Scope&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=rAyEGv67P-U" target="_blank"&gt;Modules, Routes and Factories/Services&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=qCzYrDgOy1A" target="_blank"&gt;Customer Manager App Demo&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=SL5sTjyowLY" target="_blank"&gt;Summary and Resources&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;   &lt;br /&gt;&lt;a href="http://tinyurl.com/AngularJSDemos"&gt;Download AngularJS samples&lt;/a&gt; and the Customer Manager sample application shown in the video.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=10146910" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/dwahlin/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/HTML5/default.aspx">HTML5</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/Pluralsight/default.aspx">Pluralsight</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/Ajax/default.aspx">Ajax</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/Databinding/default.aspx">Databinding</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/SPA/default.aspx">SPA</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/AngularJS/default.aspx">AngularJS</category></item><item><title>Getting Started Managing Client-Side Data with the Breeze JavaScript Library</title><link>http://weblogs.asp.net/dwahlin/archive/2013/03/27/getting-started-managing-client-side-data-with-the-breeze-javascript-library.aspx</link><pubDate>Wed, 27 Mar 2013 07:28:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:10057191</guid><dc:creator>dwahlin</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/dwahlin/rsscomments.aspx?PostID=10057191</wfw:commentRss><comments>http://weblogs.asp.net/dwahlin/archive/2013/03/27/getting-started-managing-client-side-data-with-the-breeze-javascript-library.aspx#comments</comments><description>&lt;p&gt;If you work with JavaScript a lot then you know that there’s no shortage of script libraries being released. New scripts come out on a daily basis providing UI functionality, data binding support, form validation, framework functionality and more. With all of the scripts in circulation it feels like nearly every aspect of client-side development has been covered. However, there’s one area that has seen precious few scripts – the area of client-side data management. &lt;/p&gt;  &lt;p&gt;If you need to query local caches of data, track dirty objects, send modified objects to the server as a batch or validate in-memory data, then you’ve probably been writing custom code or cobbling together various script libraries to solve the problem. Fortunately, a new script library named Breeze has been released that can help with these challenges and more.&lt;/p&gt;  &lt;p&gt;In this post I’ll provide an overview of how to get started using Breeze and discuss some of the data management features that it offers client-side developers. Let’s start by taking a quick look at some of the features that Breeze offers.    &lt;br /&gt;&lt;/p&gt;  &lt;h2&gt;Breeze Features&lt;/h2&gt;  &lt;p&gt;Breeze (&lt;a href="http://breezejs.com"&gt;http://breezejs.com&lt;/a&gt;) is a free open source library from IdeaBlade that aims to solve many of the data management challenges that developers face when building SPAs and other client-centric applications. Although it’s a relatively new library, it provides robust functionality out of the box such as client-side caching, change tracking, entity validation, a variety of data management features (support for custom metadata, import/export entities, entity ID strategies, support for multiple caches, etc.), rich entity query support (both local and remote) directly from JavaScript, and batch saves of entities to a server. &lt;/p&gt;  &lt;p&gt;In addition to these features, Breeze is designed to integrate with many of the popular libraries out there such as KnockoutJS, AngularJS, Backbone and more. If you’re already using KnockoutJS to handle client-side data binding then you can plug-in Breeze anywhere you’re currently retrieving, querying, or manipulating data and still keep all of the existing KnockoutJS functionality intact. The same can be said when using the other libraries mentioned. &lt;/p&gt;  &lt;p&gt;Breeze can also integrate with different back end server technologies and doesn’t force you to use a particular framework. Out of the box it provides support for ASP.NET Web API and Entity Framework so if you’re already using ASP.NET MVC 4 you can get started quickly. A different back end framework such as Node.js can also be used although you’d have to write the code to handle serving data to the client and processing data received from the client.&lt;/p&gt;  &lt;p&gt;Now that you’ve seen some of the general features that Breeze offers let’s take a look at how you can get started using it. Although I’ll use Visual Studio and NuGet in the examples that follow, any editor can be used.   &lt;br /&gt;&lt;/p&gt;  &lt;h2&gt;Getting Started with Breeze&lt;/h2&gt;  &lt;p&gt;One of the best ways to get started with Breeze is to load a sample application into an empty ASP.NET MVC 4 project using NuGet. To do that, right-click on the project References, select Manage NuGet Packages, and then click the Online option to the left of the dialog window. In the Search Online box type Breeze. Once the search results come back select the &lt;strong&gt;Breeze for ASP.NET MVC4 Web Api Client Sample &lt;/strong&gt;package and select Install. Here's an example of the NuGet dialog. The Breeze site also has a video walk-through of getting started with the NuGet package at &lt;a href="http://www.breezejs.com/documentation/start-NuGet"&gt;http://www.breezejs.com/documentation/start-NuGet&lt;/a&gt; if you're new to it.    &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_49C7ED8C.png"&gt;&lt;img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_74341EA9.png" width="725" height="441" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Once the NuGet package loads a readme.txt file is displayed in Visual Studio 2012 that walks through the application. To get started with it you can simply press F5 to run the sample. Once the application loads in the browser you'll see a screen similar to the one shown next:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/clip_image003_21490B78.png"&gt;&lt;img title="clip_image003" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="clip_image003" src="http://weblogs.asp.net/blogs/dwahlin/clip_image003_thumb_6EE537F8.png" width="470" height="370" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;You can edit tasks, mark tasks as done, and save changes. Anything you change gets pushed back to the server using the Breeze library and is handled by an ASP.NET Web API controller class (more on this later). Key server-side classes added into the project by the Breeze NuGet package include BreezeClientSampleConfig which handles default routing for the application, BreezeWebApiConfig which handles ASP.NET Web API routing, BreezeSampleController which acts as the ASP.NET Web Api controller and BreezeSampleShellController which handles serving up the initial view and HTML to the browser. &lt;/p&gt;  &lt;p&gt;Key client-side files added into the project include breeze.debug.js (the debug version of the Breeze script), breeze.js (the production version), logger.js and sampleViewModel.js. The sampleViewModel.js script relies on KnockoutJS to provide data binding capabilities. Here are the files that you'll see in the Solution Explorer:   &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/clip_image004_0774D549.png"&gt;&lt;img title="clip_image004" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="clip_image004" src="http://weblogs.asp.net/blogs/dwahlin/clip_image004_thumb_20047299.png" width="230" height="569" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Now that a Breeze project has been created let's take a closer look at some of the code that's used on the server-side.   &lt;br /&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;h2&gt;The Server-Side Code   &lt;br /&gt;&lt;/h2&gt;  &lt;p&gt;The BreezeSampleController class derives from the standard ApiController class and provides ASP.NET Web Api controller support for sending data to and from a client. It includes a Breeze-specific class named EFContextProvider&amp;lt;T&amp;gt; that wraps a custom Entity Framework Code First DbContext class named BreezeSampleContext. The code for the BreezeSampleController and BreezeSampleContext classes are shown in Listings 1 and 2 respectively. It's important to note that although the sample application relies on specific Breeze server-side objects such as EFContextProvider&amp;lt;T&amp;gt;, Breeze is designed to work with a variety of server-side frameworks.&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;    &lt;pre class="csharpcode"&gt;[BreezeController]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; BreezeSampleController : ApiController {

    &lt;span class="kwrd"&gt;readonly&lt;/span&gt; EFContextProvider&amp;lt;BreezeSampleContext&amp;gt; _contextProvider =
        &lt;span class="kwrd"&gt;new&lt;/span&gt; EFContextProvider&amp;lt;BreezeSampleContext&amp;gt;();

    [HttpGet]
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Metadata() {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; _contextProvider.Metadata();
    }
        
    [HttpPost]
    &lt;span class="kwrd"&gt;public&lt;/span&gt; SaveResult SaveChanges(JObject saveBundle) {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; _contextProvider.SaveChanges(saveBundle);
    }
        
    [HttpGet]
    &lt;span class="kwrd"&gt;public&lt;/span&gt; IQueryable&amp;lt;BreezeSampleTodoItem&amp;gt; Todos() {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; _contextProvider.Context.Todos;
    }

}&lt;/pre&gt;
  &lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Listing 1&lt;/b&gt;. The BreezeSampleController class that acts as the ASP.NET Web API controller for the sample application. &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; BreezeSampleContext : DbContext 
{
    &lt;span class="rem"&gt;// DEVELOPMENT ONLY: initialize the database&lt;/span&gt;
    &lt;span class="kwrd"&gt;static&lt;/span&gt; BreezeSampleContext()
    {
        Database.SetInitializer(&lt;span class="kwrd"&gt;new&lt;/span&gt; BreezeSampleDatabaseInitializer());
    }    
    &lt;span class="kwrd"&gt;public&lt;/span&gt; DbSet&amp;lt;BreezeSampleTodoItem&amp;gt; Todos { get; set; }
}&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;Listing 2&lt;/b&gt;. The BreezeSampleContext handles dynamically initializing the database and defines a Todos property used by the application to display Todo data.

  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;Looking at the code in Listing 1 you can see that a readonly field named _contextProvider of type EFContextProvider&amp;lt;BreezeSampleContext&amp;gt; is defined in the controller class. Because the service relies on Entity Framework for data access, this ContextProvider wraps an instance of an Entity Framework (EF) context. It extracts metadata from the EF model that the client needs and translates client save requests into EF save operations after applying server-side business logic to authorize and validate those changes. It also exposes the DbContext’s Todos property, an IQueryable that can be filtered, sorted, and paged before returning BreezeSampleTodoItem objects (see Listing 3) to the client.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; BreezeSampleTodoItem
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Id { get; set; }             &lt;span class="rem"&gt;// 42&lt;/span&gt;
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Description { get; set; } &lt;span class="rem"&gt;// &amp;quot;Try Breeze&amp;quot;&lt;/span&gt;
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; IsDone { get; set; }        &lt;span class="rem"&gt;// false&lt;/span&gt;
}&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;&lt;b&gt;Listing 3&lt;/b&gt;. The BreezeSampleTodoItem class.

  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;To see the metadata returned by the Metadata() action found in BreezeSampleController you can open your browser and navigate to the following path (note that you'll have to change the port to match the port assigned to your application):&lt;/p&gt;

&lt;p&gt;http://localhost:55143/api/BreezeSample/metadata
  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;The metadata describes important aspects of the model that is used by the client-side portion of Breeze such as the entity types, each type’s property names, their data types, key properties, and the relationships among entities.&lt;del datetime="2012-12-20T10:59" cite="mailto:Dan%20Wahlin"&gt;
    &lt;br /&gt;&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;Now that you've seen the Web API controller class let's switch gears and look at the client-side code that interacts with the Web Api controller and see how Breeze fits into the overall picture.
  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;h2&gt;The Client-Side Code&lt;/h2&gt;





&lt;p&gt;The Breeze sample application contains a script in the Scripts/app folder named sampleViewModel.js that contains the main client-side Breeze functionality. It handles retrieving metadata and Todo objects from the server and then binds the Todo objects into the page using KnockoutJS. As changes are made it uses Breeze to batch up changes and then send them back to the server for processing. Keep in mind that in a more complex application the view model may call out to a separate BreezeJS JavaScript object that focuses specifically on data functionality. That helps promote re-use in situations where multiple view models need to access and manipulate data through Breeze.
  &lt;br /&gt;

  &lt;br /&gt;The sampleViewModel.js script starts by creating a new Breeze EntityManager object that targets the Web Api controller discussed earlier. The KnockoutJS view model relies on the entity manager for queries and saves&amp;#160; (see Listing 4).&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// service name is route to the Web API controller&lt;/span&gt;
&lt;span class="kwrd"&gt;var&lt;/span&gt; serviceName = &lt;span class="str"&gt;'api/BreezeSample'&lt;/span&gt;;

&lt;span class="rem"&gt;// manager is the service gateway and cache holder&lt;/span&gt;
&lt;span class="kwrd"&gt;var&lt;/span&gt; manager = &lt;span class="kwrd"&gt;new&lt;/span&gt; breeze.EntityManager(serviceName);

&lt;span class="rem"&gt;// define the viewmodel&lt;/span&gt;
&lt;span class="kwrd"&gt;var&lt;/span&gt; vm = {
    todos: ko.observableArray(),
    includeDone: ko.observable(&lt;span class="kwrd"&gt;false&lt;/span&gt;),
    save: saveChanges,
    show: ko.observable(&lt;span class="kwrd"&gt;false&lt;/span&gt;)
};

&lt;span class="rem"&gt;// start fetching Todos&lt;/span&gt;
getTodos();

&lt;span class="rem"&gt;// re-query when &amp;quot;includeDone&amp;quot; checkbox changes&lt;/span&gt;
vm.includeDone.subscribe(getTodos);

&lt;span class="rem"&gt;// bind view to the viewmodel&lt;/span&gt;
ko.applyBindings(vm);&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;
    &lt;br /&gt;Listing 4&lt;/strong&gt;. Creating an EntityManager to handle interacting with the server.&lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;

  &lt;br /&gt;All data interaction goes through the EntityManager object including queries to the server, sending saved batches of data to the server and more. To query data from the server an EntityQuery object must be created and then executed by the EntityManager. Listing 5 shows an example of creating an EntityQuery object, executing the query and handling the results. 

  &lt;br /&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// get Todos asynchronously&lt;/span&gt;
&lt;span class="rem"&gt;// returning a promise to wait for     &lt;/span&gt;
&lt;span class="kwrd"&gt;function&lt;/span&gt; getTodos() {

    logger.info(&lt;span class="str"&gt;&amp;quot;querying Todos&amp;quot;&lt;/span&gt;);

    &lt;span class="kwrd"&gt;var&lt;/span&gt; query = breeze.EntityQuery.from(&lt;span class="str"&gt;&amp;quot;Todos&amp;quot;&lt;/span&gt;);

    &lt;span class="kwrd"&gt;if&lt;/span&gt; (!vm.includeDone()) {
        query = query.where(&lt;span class="str"&gt;&amp;quot;IsDone&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;==&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;false&lt;/span&gt;);
    }

    &lt;span class="kwrd"&gt;return&lt;/span&gt; manager
        .executeQuery(query)
        .then(querySucceeded)
        .fail(queryFailed);

    &lt;span class="rem"&gt;// reload vm.todos with the results &lt;/span&gt;
    &lt;span class="kwrd"&gt;function&lt;/span&gt; querySucceeded(data) {
        logger.success(&lt;span class="str"&gt;&amp;quot;queried Todos&amp;quot;&lt;/span&gt;);
        vm.todos(data.results);
        vm.show(&lt;span class="kwrd"&gt;true&lt;/span&gt;); &lt;span class="rem"&gt;// show the view&lt;/span&gt;
    }
};&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Listing 5&lt;/strong&gt;. Executing a query against the ASP.NET Web API controller using the Breeze EntityManager and EntityQuery objects.

  &lt;br /&gt;

  &lt;br /&gt;

  &lt;br /&gt;The code starts by identifying which method to query on the server-side controller (Todos in this example), creates a dynamic query, and then executes it. If the view model's includeDone property is false then a dynamic WHERE clause is added that will be sent to the server when querying Todo objects. The ability to write client-side queries that ultimately make their way to the server is a unique feature of Breeze and something I've personally wanted for quite a while for client-side application development. More complex queries can be written as well using the EntityQuery object combined with a Predicate object as shown in Listing 6 (see &lt;a href="http://www.breezejs.com/documentation/query-examples#Composite"&gt;http://www.breezejs.com/documentation/query-examples#Composite&lt;/a&gt; Where clauses for additional examples). 

  &lt;br /&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// Start with a base query for all Todos &lt;/span&gt;
&lt;span class="kwrd"&gt;var&lt;/span&gt; query = breeze.EntityQuery.from(&lt;span class="str"&gt;&amp;quot;Todos&amp;quot;&lt;/span&gt;); 

&lt;span class="rem"&gt;// A Predicate is a condition that is true or false&lt;/span&gt;
&lt;span class="rem"&gt;// Combine two predicates with &amp;quot;.and&amp;quot; to&lt;/span&gt;
&lt;span class="rem"&gt;// query for Todos that are done and&lt;/span&gt;
&lt;span class="rem"&gt;// the description contains the letter 's'&lt;/span&gt;
&lt;span class="kwrd"&gt;var&lt;/span&gt; p1 = &lt;span class="kwrd"&gt;new&lt;/span&gt; breeze.Predicate(&lt;span class="str"&gt;&amp;quot;IsDone&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;eq&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;true&lt;/span&gt;);
&lt;span class="kwrd"&gt;var&lt;/span&gt; p2 = &lt;span class="kwrd"&gt;new&lt;/span&gt; breeze.Predicate(&lt;span class="str"&gt;&amp;quot;Description&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;contains&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;s&amp;quot;&lt;/span&gt;);
query = query.where(p1.and(p2));

&lt;span class="kwrd"&gt;return&lt;/span&gt; manager.executeQuery(query);&lt;/pre&gt;

&lt;p&gt;
  &lt;br /&gt;&lt;strong&gt;Listing 6&lt;/strong&gt;. Creating queries using the EntityQuery and Predicate objects. The queries can be used to query client-side or server-side objects.

  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;In addition to querying objects on the server, the EntityManager can also save changes made on the client back to the server. When the user clicks the “save” link, the view model calls the EntityManager’s saveChanges() function. The EntityManager batches up all pending changes and sends them back to the controller for processing. Listing 7 shows how the EntityManager's saveChanges() function can be invoked and used to detect success or failure using promises.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; saveChanges() {
    &lt;span class="kwrd"&gt;return&lt;/span&gt; manager.saveChanges()
        .then(&lt;span class="kwrd"&gt;function&lt;/span&gt; () { logger.success(&lt;span class="str"&gt;&amp;quot;changes saved&amp;quot;&lt;/span&gt;); })
        .fail(saveFailed);
}

&lt;span class="kwrd"&gt;function&lt;/span&gt; saveFailed(error) {
    logger.error(&lt;span class="str"&gt;&amp;quot;Save failed: &amp;quot;&lt;/span&gt; + error.message);
}&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Listing 7&lt;/strong&gt;. Using Breeze's EntityManager to save changes made on the client back to the server.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Breeze fills a huge hole in client-side development through its data management capabilities. By providing query capabilities, batch save functionality, and the ability to perform a variety of other features it greatly simplifies the process of building CRUD-style (create, read, update, delete) applications and allows developers to focus on application logic as opposed to data plumbing code. Find out more information about Breeze by visiting the website at &lt;a href="http://www.breezejs.com"&gt;http://www.breezejs.com&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=10057191" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/dwahlin/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/ASP.NET+MVC/default.aspx">ASP.NET MVC</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/HTML5/default.aspx">HTML5</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/SPA/default.aspx">SPA</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/ASP.NET+Web+API/default.aspx">ASP.NET Web API</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/Breeze/default.aspx">Breeze</category></item><item><title>New Features in ASP.NET 4.5 Web Forms Course Released on Pluralsight.com</title><link>http://weblogs.asp.net/dwahlin/archive/2013/03/24/new-features-in-asp-net-4-5-web-forms-course-released-on-pluralsight-com.aspx</link><pubDate>Mon, 25 Mar 2013 06:36:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:10047282</guid><dc:creator>dwahlin</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/dwahlin/rsscomments.aspx?PostID=10047282</wfw:commentRss><comments>http://weblogs.asp.net/dwahlin/archive/2013/03/24/new-features-in-asp-net-4-5-web-forms-course-released-on-pluralsight-com.aspx#comments</comments><description>&lt;p&gt;I've been hard at work the past few months filming a new course for Pluralsight covering some of the great new features in ASP.NET 4.5 Web Forms. I'm excited to announce that the new course is titled &lt;a href="http://pluralsight.com/training/Courses/TableOfContents/aspnet-webforms45-new-features" target="_blank"&gt;New Features in ASP.NET 4.5 Web Forms&lt;/a&gt; and is now available on &lt;a href="http://www.pluralsight.com" target="_blank"&gt;Pluralsight.com&lt;/a&gt;! If you're an ASP.NET Web Forms developer (and there are many of you out there!) then you should definitely take a look at the new features available in the 4.5 release if you haven't already. In my opinion, this is the most significant release since ASP.NET 2.0. I say that because some of the new features will truly change how you write your ASP.NET applications - especially the data binding features.&lt;/p&gt;  &lt;p&gt;Here's the official description of the course and the content that's covered. I hope you enjoy it and are able to apply some of the new features in your applications! If you're not a Pluralsight subscriber and still want to view some of the course check out their &lt;a href="https://pluralsight.com/training/Subscribe/Step1?isTrial=True" target="_blank"&gt;free trial offer&lt;/a&gt;.    &lt;br /&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://pluralsight.com/training/Courses/TableOfContents/aspnet-webforms45-new-features" target="_blank"&gt;&lt;img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image_7668CFF2.png" width="788" height="92" /&gt;&lt;/a&gt;     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;The New Features in ASP.NET 4.5 Web Forms course provides a tour of what's new in Visual Studio 2012 for ASP.NET Web Forms developers and how it can make you more productive as a developer. The course begins by showing you key enhancements to Visual Studio's HTML editor and its improved support for working with CSS and JavaScript. Next, you’ll explore what's new with data binding (some significant features have been added here!) including model binding and strongly typed data controls. You’ll also see enhancements that have been made to the ASP.NET framework such as bundling and minification of JavaScript and CSS, asynchronous modules and handlers, SignalR and more. Several new HTML5 features are also demonstrated including new HTML5 input types, Web Sockets and support for multiple file uploads. The course concludes with a look at important security-related improvements in ASP.NET including support for oAuth, request validation and support for preventing cross-site request forgery (XSRF) attacks. &lt;/p&gt;  &lt;h3&gt;Course Content&lt;/h3&gt;  &lt;table class="linkContainer" width="492"&gt;&lt;thead&gt;&lt;/thead&gt;&lt;tbody&gt;     &lt;tr class="module"&gt;       &lt;td class="title tocModule" style="padding-left: 0px"&gt;         &lt;div class="playButton"&gt;&lt;strong&gt;&amp;#160;&lt;span style="margin-left: 10px"&gt;Visual Studio Features&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Course Overview&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Introduction &lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;HTML Editor Features&lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;Demo: HTML Editor Features&lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;JavaScript Editor Features&lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;Demo: JavaScript Editor Features&lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;CSS Editor Features&lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;Demo: CSS Editor Features&lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;The Page Inspector&lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;Demo: The Page Inspector&lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;Using Web Essentials&lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;Demo: Using Web Essentials&lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;Summary&lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;&amp;nbsp;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr id="typescript-m2" class="module"&gt;       &lt;td class="title tocModule" style="padding-left: 0px"&gt;         &lt;div class="playButton"&gt;&amp;#160;&lt;span style="margin-left: 10px"&gt;&lt;strong&gt;Working with Data&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Introduction&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Strongly Typed Data Controls&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Demo: Strongly Typed Data Controls&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Model Binding&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Model Binding Attributes&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;Demo: Model Binding&lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;HTML Encoded Data Binding Expressions&lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;Unobtrusive Validation&lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;Summary&lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;&amp;nbsp;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr id="typescript-m3" class="module"&gt;       &lt;td class="title tocModule" style="padding-left: 0px"&gt;         &lt;div class="playButton"&gt;&amp;#160;&lt;span style="margin-left: 10px"&gt;&lt;strong&gt;Framework Features&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Introduction &lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Bundling and Minification&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Demo: Bundling and Minification&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Async Support&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Demo: Creating Asynchronous HttpModules&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Demo: Creating Asynchronous HttpHandlers&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;FriendlyUrls&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Demo: Implementing FriendlyUrls&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;ASP.NET Web API&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Demo: Using the ASP.NET WebAPI&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Demo: Using HTTP Verbs&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;SignalR&lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;Demo: Using SignalR&lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Summary &lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;&amp;nbsp;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="module"&gt;       &lt;td class="title tocModule" style="padding-left: 0px"&gt;         &lt;div class="playButton"&gt;&amp;#160;&lt;strong&gt;&lt;span style="margin-left: 10px"&gt;HTML5 Features&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Introduction&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;TextMode Property Enhancements&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Demo: TextBox HTML5 Enhancements&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Multiple File Uploads&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Demo: Uploading Multiple Files with FileUpload &lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;WebSockets&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Demo: WebSockets with System.Web.WebSockets&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Demo: WebSockets with Microsoft.Web.WebSockets&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Additional HTML5 Features&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Demo: Unobtrusive Validation and Validator Controls&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;Summary&lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;&amp;nbsp;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="module"&gt;       &lt;td class="title tocModule" style="padding-left: 0px"&gt;         &lt;div class="playButton"&gt;&amp;#160;&lt;strong&gt;&lt;span style="margin-left: 10px"&gt;oAuth and Security Features&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Introduction&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;oAuth Support&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Demo: oAuth Facebook Integration&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;         &lt;div&gt;Demo: Enhancing Facebook Integration&lt;/div&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;Deferred Request Validation&lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;Demo: Using Deferred Request Validation&lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;Unvalidated Requests and AntiXSS Encoding&lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;Demo: Handling Unvalidated Requests and Encoding with the AntiXssEncoder&lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;Anti-XSRF Validation&lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;Demo: Anti-XSRF Validation Code&lt;/td&gt;     &lt;/tr&gt;      &lt;tr class="tocClips"&gt;       &lt;td class="clipTitle" style="padding-left: 55px"&gt;Summary&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=10047282" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/dwahlin/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/HTML5/default.aspx">HTML5</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/CSS/default.aspx">CSS</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/Pluralsight/default.aspx">Pluralsight</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/Ajax/default.aspx">Ajax</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/Databinding/default.aspx">Databinding</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/ASP.NET+Web+API/default.aspx">ASP.NET Web API</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/Websockets/default.aspx">Websockets</category></item><item><title>What's Hot in the World of JavaScript and SPAs?</title><link>http://weblogs.asp.net/dwahlin/archive/2013/01/13/what-s-hot-in-the-world-of-javascript-and-spas.aspx</link><pubDate>Mon, 14 Jan 2013 00:06:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:9748358</guid><dc:creator>dwahlin</dc:creator><slash:comments>25</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/dwahlin/rsscomments.aspx?PostID=9748358</wfw:commentRss><comments>http://weblogs.asp.net/dwahlin/archive/2013/01/13/what-s-hot-in-the-world-of-javascript-and-spas.aspx#comments</comments><description>&lt;p&gt;Client-side development continues to be more and more popular which is both good and bad for developers. It's good (great!) because we have more power than ever at our fingertips. It's bad because it can be challenging to stay up-to-speed with all of the libraries and frameworks being released (I call that job security). I hear some developers complaining about Web development and all of the script libraries being released but I personally think it provides us with a lot of choice and flexibility, not to mention enhanced productivity. I’d rather have the flexibility of choosing from a variety of scripts as opposed to only a handful.&lt;/p&gt;  &lt;p&gt;From time to time people ask me about what libraries I'm using or keeping an eye on as my company builds custom applications or provides training to companies. As a result, I thought I'd put together a post that includes a few script libraries and frameworks that I find interesting and that I think might interest you as well. Some of them have been around for quite some time while others are brand new to the scene. I plan to update the list over time as I find something else interesting or move away from a particular script for whatever reason. &lt;/p&gt;  &lt;p&gt;Keep in mind that I can’t list every library and framework out there. My goal is to list ones that I personally find quite compelling and that I (or someone I know very well) has direct experience using.    &lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;h1&gt;Script Libraries    &lt;br /&gt;&lt;/h1&gt;  &lt;p&gt;There are a lot of great script libraries out there that perform a variety of functionality. Here are a few scripts that I find interesting and quite useful for building client-side applications.    &lt;br /&gt;&lt;/p&gt;  &lt;h4&gt;jQuery&lt;/h4&gt;  &lt;p&gt;&lt;a href="http://jquery.com"&gt;http://jquery.com&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This one is rather obvious and no surprise if you've been building client-side applications over the past 5+ years. jQuery is the most widely used script library on the planet and the base for many other scripts out there. It provides support for selecting DOM elements, handling events, performing animations, making Ajax calls, working with plugins and more. If you haven't taken the time to learn jQuery then there's no time like the present. Check out &lt;a href="http://pluralsight.com/training/Courses/TableOfContents/jquery-fundamentals"&gt;my jQuery Fundamentals course on Pluralsight&lt;/a&gt; for additional details on what you can do with it in client-side applications. I've also blogged quite a bit about jQuery over the years. See &lt;a href="http://weblogs.asp.net/dwahlin/archive/tags/jQuery/default.aspx"&gt;http://weblogs.asp.net/dwahlin/archive/tags/jQuery/default.aspx&lt;/a&gt; for more details. &lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;If you’re new to jQuery and interested in learning it check out my &lt;a href="http://pluralsight.com/training/Courses/TableOfContents/jquery-fundamentals" target="_blank"&gt;jQuery Fundamentals&lt;/a&gt; course on Pluralsight.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://pluralsight.com/training/Courses/TableOfContents/jquery-fundamentals" target="_blank"&gt;&lt;img style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; padding-right: 0px" border="0" src="http://weblogs.asp.net/blogs/dwahlin/image_5F8B21BF.png" width="697" height="82" /&gt;&lt;/a&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;h3&gt;Knockout&lt;/h3&gt;  &lt;p&gt;&lt;a href="http://knockoutjs.com"&gt;http://knockoutjs.com&lt;/a&gt;     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;Knockout is arguably the most popular script library out there for handling client-side data binding. It provides a flexible way to declare bindings in HTML, write view model objects that are bound to HTML, handle dependency tracking and write templates. If you're working with a lot of data in a client-centric application then KnockoutJS is definitely worth taking a look at. It has an excellent set of online tutorials available at &lt;a href="http://learn.knockoutjs.com"&gt;http://learn.knockoutjs.com&lt;/a&gt;. Check out &lt;a href="http://pluralsight.com/training/Courses/TableOfContents/knockout-mvvm"&gt;John Papa's course&lt;/a&gt; on Pluralsight as well for a nice walk-through of the features it offers and how they can be used. My good friend John Papa has a nice &lt;a href="http://pluralsight.com/training/Courses/TableOfContents/knockout-mvvm" target="_blank"&gt;course on Knockout&lt;/a&gt;!    &lt;br /&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;h3&gt;RequireJS&lt;/h3&gt;  &lt;p&gt;&lt;a href="http://requirejs.org"&gt;http://requirejs.org&lt;/a&gt;     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;As more and more script libraries are used in an application it can become difficult to manage all of the dependencies between scripts and ensure that they're loaded when they're needed. RequireJS is a module-based script loader that can handle loading scripts upfront or as they're needed. By using it you can simplify the process of managing script dependencies.    &lt;br /&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;h3&gt;AmplifyJS&lt;/h3&gt;  &lt;p&gt;&lt;a href="http://amplifyjs.com"&gt;http://amplifyjs.com&lt;/a&gt;     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;AmplifyJS provides a set of jQuery components that can be used for Ajax requests, client-side communication between components (publish/subscribe), and client-side storage (desktop or mobile). It provides a unified API for accessing different data sources that can make your code more re-useable and easier to maintain. If you find yourself duplicating Ajax calls across an application then you can use AmplifyJS to define them in a more centralized component.    &lt;br /&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;h3&gt;Bootstrap&lt;/h3&gt;  &lt;p&gt;&lt;a href="http://twitter.github.com/bootstrap"&gt;http://twitter.github.com/bootstrap&lt;/a&gt;     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;Twitter released the Bootstrap library that provides dozens of components that speed-up client-side development and make it look good at the same time. It includes built-in components such as dropdown menus, buttons, navbars, pagination and progress bars as well as jQuery plugins that handle transitions, modal dialogs, tabs, tooltips, slideshow carousels and more. Bootstrap also includes CSS to help make the various components look good without having to write a lot of custom styles or code. I’ve used &lt;a href="http://jqueryui.com/" target="_blank"&gt;jQuery UI&lt;/a&gt; quite a bit over the years as well but also like what Bootstrap offers.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h5&gt;Backbone.js    &lt;br /&gt;&lt;/h5&gt;  &lt;p&gt;&lt;a href="http://backbonejs.org"&gt;http://backbonejs.org&lt;/a&gt;     &lt;br /&gt;    &lt;br /&gt;Backbone.js is a popular client-side option that can be used to build MVC-like applications that have models, collections, views and routes. It provides a way to introduce a formal structure into an application which is great for overall architecture and maintenance and supports declarative binding, templates, events, routing and more. Objects used in an application are created by extending the Model, View, Collection, or Router objects provided by Backbone.js. Check out the Todo application available at &lt;a title="https://github.com/addyosmani/todomvc/tree/gh-pages/architecture-examples/backbone" href="https://github.com/addyosmani/todomvc/tree/gh-pages/architecture-examples/backbone"&gt;https://github.com/addyosmani/todomvc/tree/gh-pages/architecture-examples/backbone&lt;/a&gt; to get started using it. While I personally consider Backbone.js to be a framework since you build upon it, it’s “officially” categorized as a library.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;Breeze&lt;/h3&gt;  &lt;p&gt;&lt;a href="http://breezejs.com"&gt;http://breezejs.com&lt;/a&gt;     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;Are you working with a lot of data in your application and performing a variety of CRUD (create, read, update, delete) operations? If you are, you’ll definitely want to check out Breeze since it provides much needed client-side data management capabilities. It can handle data caching, change tracking, entity data validation, entity query support and batch saves of data back to the server. Breeze integrates well with many popular script libraries and can also play nicely with different back-end frameworks as well. To get started with Breeze check out the interactive tutorials at &lt;a href="http://learn.breezejs.com"&gt;http://learn.breezejs.com&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Script Frameworks    &lt;br /&gt;&lt;/h1&gt;  &lt;p&gt;My close friends will tell you that I haven't been a huge fan of Single Page Applications (SPAs) – at least not &amp;quot;true&amp;quot; SPAs as they’re defined today since they involve a lot of scripts, dependencies and complexities that I find to be overkill in some cases. You won't find a single post on my blog dedicated to SPAs because I just haven't been a big believer in them up to this point. &lt;/p&gt;  &lt;p&gt;Why haven't I jumped on the SPA bandwagon? I've done a lot of production support over my career working with both large and small teams and am worried about what happens down the road as a lot of interrelated scripts in an application change versions, people come and go on dev teams without sharing the &amp;quot;tribal knowledge&amp;quot; they have, different developer skill levels are involved with a SPA application, etc. If you only have a few scripts in an application then it’s not a big deal to manage but once you approach 10+ scripts things get more interesting over time as those scripts evolve. Hopefully they’ll always play together nicely but past experience leads me to believe otherwise. You can certainly build a solid SPA application with some of the script libraries I mentioned (and others not mentioned) but you'll definitely have to spend quite a bit of time learning the ins-and-outs of the different libraries (that’s not a bad thing of course). You'll also want to factor in maintenance costs if you're building them with a team – something that a lot of people just don't seem to think about (one direct reason I've spent quite a bit of time working with &lt;a href="http://www.typescriptlang.org/"&gt;TypeScript&lt;/a&gt; over the past few months by the way).&lt;/p&gt;  &lt;p&gt;So what's my take on SPAs now days? The good news is that SPA frameworks are emerging to help manage the complexity and dependencies (history, navigation, data management, data binding, storage, templates, etc.) which I'm really excited about. If you've been holding off on building SPAs at your company due to some of the reasons I mentioned above then here are a few frameworks that might change your mind. I've started to blog about some of these frameworks and why I think they're a much better approach compared to creating a SPA from scratch using a mish-mash of scripts and will have more posts in the near future.    &lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;h5&gt;&lt;b&gt;AngularJS      &lt;br /&gt;      &lt;br /&gt;&lt;/b&gt;&lt;/h5&gt;  &lt;p&gt;&lt;a href="http://angularjs.org"&gt;http://angularjs.org&lt;/a&gt;     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;Although not explicitly stated on its homepage, AngularJS is a robust Single Page Application (SPA) framework with an enormous amount of functionality built-in. It stands on its own and doesn't require any other scripts while providing features such as two-way data binding, MVC-like architecture, form validation, routing, history, Ajax functionality and much more. I've blogged about AngularJS in the past and recommend you check out their tutorials as well located at &lt;a href="http://docs.angularjs.org/tutorial"&gt;http://docs.angularjs.org/tutorial&lt;/a&gt;. If you’re worried about managing multiple scripts over time in an application then the AngularJS framework provides a nice alternative.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://weblogs.asp.net/dwahlin/archive/2012/07/29/javascript-data-binding-with-angularjs-getting-started.aspx"&gt;JavaScript Data Binding with AngularJS Part I – Getting Started&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://weblogs.asp.net/dwahlin/archive/2012/08/05/javascript-data-binding-with-angularjs-part-ii-binding-a-view-to-a-controller-viewmodel.aspx"&gt;JavaScript Data Binding with AngularJS Part II – Binding a View to a Controller/ViewModel&lt;/a&gt;       &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;h5&gt;&lt;b&gt;Durandal      &lt;br /&gt;      &lt;br /&gt;&lt;/b&gt;&lt;/h5&gt;  &lt;p&gt;&lt;a href="http://durandaljs.com"&gt;http://durandaljs.com&lt;/a&gt;     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;Durandal is a brand new framework by Rob Eisenberg (creator of frameworks such as &lt;a href="http://caliburnmicro.codeplex.com/"&gt;Caliburn Micro&lt;/a&gt;) but I wanted to include it here since I'm excited about what I've seen so far. It's another option for building SPAs (I personally think a better name would be Rich Web Applications or RWAs but that's just me) and provides a lot of functionality such as a clean architecture, modularity, messaging between components in a page, navigation and history to name a few. It's built on top of the jQuery, Knockout and RequireJS script libraries so they’re still used behind the scenes and as you build your views and view models. However, I really like how it abstracts many of the complexities of SPAs away and seems to offer a more maintainable and modular solution compared to building SPAs by hand. Documentation for Durandal can be found at &lt;a href="https://github.com/EisenbergEffect/Durandal/wiki"&gt;https://github.com/EisenbergEffect/Durandal/wiki&lt;/a&gt; and I'll be blogging about it more over the next few months (I’m considering doing a new &lt;a href="http://pluralsight.com/training" target="_blank"&gt;Pluralsight&lt;/a&gt; course on it as well). I'll also be speaking about Durandal at the upcoming &lt;a href="http://devintersection.com/"&gt;DevIntersection conference&lt;/a&gt; in Las Vegas in April. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h5&gt;&lt;b&gt;Sammy.js      &lt;br /&gt;      &lt;br /&gt;&lt;/b&gt;&lt;/h5&gt;  &lt;p&gt;&lt;a href="http://www.sammyjs.org"&gt;http://www.sammyjs.org&lt;/a&gt;     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;Sammy.js is one of the smallest frameworks out there (currently around 5.2k compressed/gzipped) but is designed to be modular so that it can be extended using plugins and adapters. It’s built on top of jQuery and provides a way to organize code into routes that are linked to callback functions (very handy in SPA applications) and you can use built-in events or define your own. A great way to get started with Sammy.js is to check out their tutorial at &lt;a title="http://sammyjs.org/docs/tutorials/json_store_1" href="http://sammyjs.org/docs/tutorials/json_store_1"&gt;http://sammyjs.org/docs/tutorials/json_store_1&lt;/a&gt;. A list of some of the plugins available for the framework can be found in the Github repository located at &lt;a title="https://github.com/quirkey/sammy/tree/master/lib/plugins" href="https://github.com/quirkey/sammy/tree/master/lib/plugins"&gt;https://github.com/quirkey/sammy/tree/master/lib/plugins&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h5&gt;&lt;b&gt;Node.js      &lt;br /&gt;      &lt;br /&gt;&lt;/b&gt;&lt;/h5&gt;  &lt;p&gt;&lt;a href="http://nodejs.org"&gt;http://nodejs.org&lt;/a&gt;     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;Node.js is different than the other frameworks mentioned since it can be used in a variety of ways. It's primarily a server-side JavaScript framework (although it can be used in other ways as well) that can be used to build fast and scalable Web applications, serve up data through RESTful services and more. What's unique about Node.js compared to other server-side frameworks is that all of the code is written in JavaScript providing an end to end story for application development - JavaScript on the client and JavaScript on the server. It's also supported by a large community that consistently adds new modules that can be accessed using the built-in Node Package Manager (NPM). Node.js is capable of performing functionality seen in other server-side frameworks such as ASP.NET, PHP and Ruby on Rails. A lot of companies are using Node.js more and more now (I just did some custom training on the framework for a big bank in the United States with a large team using Node.js).    &lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;h4&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;/h4&gt;  &lt;p&gt;So is that all of the libraries and frameworks that you should take a look at? Not even close – there are many other worthy scripts out there that can be used and that are quite popular. I've tried to cover a few of the key scripts that I like (or find interesting) and hope that will spark your interest in taking a closer look at some of them. There are certainly others I’m interested in as well. I think it’s safe to say that we’re on the cusp of a new movement where more and more frameworks like AngularJS and Durandal will be released to simplify the process of creating robust client-side SPA applications. &lt;/p&gt;  &lt;p&gt;Do you have other scripts you use a lot? Leave a comment about them below to give myself and anyone else reading the post some details about what you like about them.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=9748358" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/dwahlin/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/HTML5/default.aspx">HTML5</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/TypeScript/default.aspx">TypeScript</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/SPA/default.aspx">SPA</category></item><item><title>Code and Slides from my Fall 2012 DevConnections Talks</title><link>http://weblogs.asp.net/dwahlin/archive/2012/10/31/code-and-slides-from-my-fall-2012-devconnections-talks.aspx</link><pubDate>Thu, 01 Nov 2012 05:06:36 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:9271192</guid><dc:creator>dwahlin</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/dwahlin/rsscomments.aspx?PostID=9271192</wfw:commentRss><comments>http://weblogs.asp.net/dwahlin/archive/2012/10/31/code-and-slides-from-my-fall-2012-devconnections-talks.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_7DC75174.png"&gt;&lt;img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_3671FB82.png" width="192" height="68" /&gt;&lt;/a&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;Thanks to everyone who attended my sessions at the Fall 2012 DevConnections conference in Las Vegas. There was a ton of interest in different JavaScript and HTML5 topics. Here’s a picture taken after finishing up my first talk. The second one was packed (standing room only…forgot to take a picture though unfortunately) – thanks to everyone for the great questions and interest in the sessions! I really enjoyed talking with everyone that came up afterward.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/2012-10-31-11.06.48_5620D54A.jpg"&gt;&lt;img title="2012-10-31 11.06.48" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="2012-10-31 11.06.48" src="http://weblogs.asp.net/blogs/dwahlin/2012-10-31-11.06.48_thumb_54DC3C6B.jpg" width="720" height="540" /&gt;&lt;/a&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;As promised, here’s where you can find the code and slides I demonstrated during my talks on building an HTML5 application with a variety of technologies and structuring JavaScript code.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="https://dl.dropbox.com/u/6037348/Conferences/DevConnectionsFall2012/Building%20an%20HTML5%20Application.zip"&gt;Building the Account at a Glance ASP.NET MVC, HTML5 and jQuery Application&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="https://dl.dropbox.com/u/6037348/Conferences/DevConnectionsFall2012/Structuring%20JavaScript%20Code.zip"&gt;Structuring JavaScript Code - Techniques, Strategies and Patterns&lt;/a&gt;      &lt;br /&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;If you’re on Twitter keep in touch with me through my &lt;a href="https://twitter.com/danwahlin" target="_blank"&gt;DanWahlin&lt;/a&gt; alias.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=9271192" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/dwahlin/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/Entity+Framework/default.aspx">Entity Framework</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/JSON/default.aspx">JSON</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/ASP.NET+MVC/default.aspx">ASP.NET MVC</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/HTML5/default.aspx">HTML5</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/DevConnections/default.aspx">DevConnections</category></item><item><title>Getting Started with TypeScript – Classes, Static Types and Interfaces</title><link>http://weblogs.asp.net/dwahlin/archive/2012/10/31/getting-started-with-typescript-classes-static-types-and-interfaces.aspx</link><pubDate>Thu, 01 Nov 2012 04:38:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:9270960</guid><dc:creator>dwahlin</dc:creator><slash:comments>11</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/dwahlin/rsscomments.aspx?PostID=9270960</wfw:commentRss><comments>http://weblogs.asp.net/dwahlin/archive/2012/10/31/getting-started-with-typescript-classes-static-types-and-interfaces.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_02DF4693.png"&gt;&lt;img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: left; padding-top: 0px; padding-left: 0px; margin: 0px 10px 5px 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" align="left" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_17649611.png" width="240" height="63" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I had the opportunity to speak on different JavaScript topics at DevConnections in Las Vegas this fall and heard a lot of interesting comments about JavaScript as I talked with people. The most frequent comment I heard from people was, “I guess it’s time to start learning JavaScript”. Yep – if you don’t already know JavaScript then it’s time to learn it. As HTML5 becomes more and more popular the amount of JavaScript code written will definitely increase. After all, many of the HTML5 features available in browsers have little to do with “tags” and more to do with JavaScript (web workers, web sockets, canvas, local storage, etc.). As the amount of JavaScript code being used in applications increases, it’s more important than ever to structure the code in a way that’s maintainable and easy to debug. While JavaScript patterns can certainly be used (check out my &lt;a href="http://weblogs.asp.net/dwahlin/archive/2011/07/31/techniques-strategies-and-patterns-for-structuring-javascript-code.aspx" target="_blank"&gt;previous posts on the subject&lt;/a&gt; or my course on &lt;a href="http://pluralsight.com/training/Courses/TableOfContents/structuring-javascript" target="_blank"&gt;Pluralsight.com&lt;/a&gt;), several alternatives have come onto the scene such as CoffeeScript, Dart and TypeScript. In this post I’ll describe some of the features TypeScript offers and the benefits that they can potentially offer enterprise-scale JavaScript applications.&lt;/p&gt;  &lt;p&gt;It’s important to note that while TypeScript has several great features, it’s definitely not for everyone or every project especially given how new it is. The goal of this post isn’t to convince you to use TypeScript instead of standard JavaScript….I’m a big fan of JavaScript. Instead, I’ll present several TypeScript features and let you make the decision as to whether TypeScript is a good fit for your applications.    &lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;h4&gt;TypeScript Overview&lt;/h4&gt;  &lt;p&gt;Here’s the official definition of TypeScript from the &lt;a href="http://typescriptlang.org"&gt;http://typescriptlang.org&lt;/a&gt; site: &lt;/p&gt;  &lt;p&gt;“TypeScript is a language for application-scale JavaScript development. TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. Any browser. Any host. Any OS. Open Source.” &lt;/p&gt;  &lt;p&gt;TypeScript was created by Anders Hejlsberg (the creator of the C# language) and his team at Microsoft. To sum it up, TypeScript is a new language that can be compiled to JavaScript much like alternatives such as CoffeeScript or Dart. It isn’t a stand-alone language that’s completely separate from JavaScript’s roots though. It’s a superset of JavaScript which means that standard JavaScript code can be placed in a TypeScript file (a file with a .ts extension) and used directly. That’s a very important point/feature of the language since it means you can use existing code and frameworks with TypeScript without having to do major code conversions to make it all work. Once a TypeScript file is saved it can be compiled to JavaScript using TypeScript’s tsc.exe compiler tool or by using a variety of editors/tools.&lt;/p&gt;  &lt;p&gt;TypeScript offers several key features. First, it provides built-in type support meaning that you define variables and function parameters as being “string”, “number”, “bool”, and more to avoid incorrect types being assigned to variables or passed to functions. Second, TypeScript provides a way to write modular code by directly supporting class and module definitions and it even provides support for custom interfaces that can be used to drive consistency. Finally, TypeScript integrates with several different tools such as Visual Studio, Sublime Text, Emacs, and Vi to provide syntax highlighting, code help, build support, and more depending on the editor. Find out more about editor support at &lt;a href="http://www.typescriptlang.org/#Download"&gt;http://www.typescriptlang.org/#Download&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;TypeScript can also be used with existing JavaScript frameworks such as Node.js, jQuery, and others and even catch type issues and provide enhanced code help. Special “declaration” files that have a &lt;i&gt;d.ts&lt;/i&gt; extension are available for Node.js, jQuery, and other libraries out-of-the-box. Visit &lt;a href="http://typescript.codeplex.com/SourceControl/changeset/view/fe3bc0bfce1f#samples%2fjquery%2fjquery.d.ts"&gt;http://typescript.codeplex.com/SourceControl/changeset/view/fe3bc0bfce1f#samples%2fjquery%2fjquery.d.ts&lt;/a&gt; for an example of a jQuery TypeScript declaration file that can be used with tools such as Visual Studio 2012 to provide additional code help and ensure that a string isn’t passed to a parameter that expects a number. Although declaration files certainly aren’t required, TypeScript’s support for declaration files makes it easier to catch issues upfront while working with existing libraries such as jQuery. In the future I expect TypeScript declaration files will be released for different HTML5 APIs such as canvas, local storage, and others as well as some of the more popular JavaScript libraries and frameworks.&lt;/p&gt;  &lt;h4&gt;   &lt;br /&gt;Getting Started with TypeScript&lt;/h4&gt;  &lt;p&gt;To get started learning TypeScript visit the TypeScript Playground available at &lt;a href="http://www.typescriptlang.org"&gt;http://www.typescriptlang.org&lt;/a&gt;. Using the playground editor you can experiment with TypeScript code, get code help as you type, and see the JavaScript that TypeScript generates once it’s compiled. Here’s an example of the TypeScript playground in action:     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/Figure1_42D258B4.png"&gt;&lt;img title="Figure1" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Figure1" src="http://weblogs.asp.net/blogs/dwahlin/Figure1_thumb_3A6E835D.png" width="806" height="558" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;One of the first things that may stand out to you about the code shown above is that classes can be defined in TypeScript. This makes it easy to group related variables and functions into a container which helps tremendously with re-use and maintainability especially in enterprise-scale JavaScript applications. While you can certainly simulate classes using JavaScript patterns (note that ECMAScript 6 will support classes directly), TypeScript makes it quite easy especially if you come from an object-oriented programming background. An example of the Greeter class shown in the TypeScript Playground is shown next:    &lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; Greeter {
    greeting: &lt;span class="kwrd"&gt;string&lt;/span&gt;;

    constructor (message: &lt;span class="kwrd"&gt;string&lt;/span&gt;) {
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.greeting = message;
    }

    greet() {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Hello, &amp;quot;&lt;/span&gt; + &lt;span class="kwrd"&gt;this&lt;/span&gt;.greeting;
    }
}&lt;/pre&gt;

&lt;br /&gt;

&lt;p&gt;Looking through the code you’ll notice that static types can be defined on variables and parameters such as &lt;i&gt;greeting: string&lt;/i&gt;, that constructors can be defined, and that functions can be defined such as &lt;i&gt;greet()&lt;/i&gt;. The ability to define static types is a key feature of TypeScript (and where its name comes from) that can help identify bugs upfront before even running the code. Many types are supported including primitive types like string, number, bool, undefined, and null as well as object literals and more complex types such as HTMLInputElement (for an &amp;lt;input&amp;gt; tag). Custom types can be defined as well.&lt;/p&gt;

&lt;p&gt;The JavaScript output by compiling the TypeScript Greeter class (using an editor like Visual Studio, Sublime Text, or the tsc.exe compiler) is shown next: 
  &lt;br /&gt;

  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;var&lt;/span&gt; Greeter = (&lt;span class="kwrd"&gt;function&lt;/span&gt; () {
    &lt;span class="kwrd"&gt;function&lt;/span&gt; Greeter(message) {
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.greeting = message;
    }
    Greeter.prototype.greet = &lt;span class="kwrd"&gt;function&lt;/span&gt; () {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Hello, &amp;quot;&lt;/span&gt; + &lt;span class="kwrd"&gt;this&lt;/span&gt;.greeting;
    };
    &lt;span class="kwrd"&gt;return&lt;/span&gt; Greeter;
})();&lt;/pre&gt;

&lt;p&gt;
  &lt;br /&gt;Notice that the code is using JavaScript prototyping and closures to simulate a Greeter class in JavaScript. The body of the code is wrapped with a self-invoking function to take the variables and functions out of the global JavaScript scope. This is important feature that helps avoid naming collisions between variables and functions. 

  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;In cases where you’d like to wrap a class in a naming container (similar to a namespace in C# or a package in Java) you can use TypeScript’s &lt;i&gt;module&lt;/i&gt; keyword. The following code shows an example of wrapping an AcmeCorp module around the Greeter class. In order to create a new instance of Greeter the module name must now be used. This can help avoid naming collisions that may occur with the Greeter class.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;



&lt;pre class="csharpcode"&gt;module AcmeCorp {
    export &lt;span class="kwrd"&gt;class&lt;/span&gt; Greeter {
        greeting: &lt;span class="kwrd"&gt;string&lt;/span&gt;;

        constructor (message: &lt;span class="kwrd"&gt;string&lt;/span&gt;) {
            &lt;span class="kwrd"&gt;this&lt;/span&gt;.greeting = message;
        }

        greet() {
            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Hello, &amp;quot;&lt;/span&gt; + &lt;span class="kwrd"&gt;this&lt;/span&gt;.greeting;
        }
    }
}

&lt;span class="kwrd"&gt;var&lt;/span&gt; greeter = &lt;span class="kwrd"&gt;new&lt;/span&gt; AcmeCorp.Greeter(&lt;span class="str"&gt;&amp;quot;world&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

&lt;br /&gt;In addition to being able to define custom classes and modules in TypeScript, you can also take advantage of inheritance by using TypeScript’s &lt;i&gt;extends&lt;/i&gt; keyword. The following code shows an example of using inheritance to define two report objects:



&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; Report {
    name: &lt;span class="kwrd"&gt;string&lt;/span&gt;;

    constructor (name: &lt;span class="kwrd"&gt;string&lt;/span&gt;) {
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.name = name;
    }

    print() {
        alert(&lt;span class="str"&gt;&amp;quot;Report: &amp;quot;&lt;/span&gt; + &lt;span class="kwrd"&gt;this&lt;/span&gt;.name);
    }
}

&lt;span class="kwrd"&gt;class&lt;/span&gt; FinanceReport extends Report {
    constructor (name: &lt;span class="kwrd"&gt;string&lt;/span&gt;) {
        super(name);
    }

    print() {
        alert(&lt;span class="str"&gt;&amp;quot;Finance Report: &amp;quot;&lt;/span&gt; + &lt;span class="kwrd"&gt;this&lt;/span&gt;.name);
    }

    getLineItems() {
        alert(&lt;span class="str"&gt;&amp;quot;5 line items&amp;quot;&lt;/span&gt;);
    }
}

&lt;span class="kwrd"&gt;var&lt;/span&gt; report = &lt;span class="kwrd"&gt;new&lt;/span&gt; FinanceReport(&lt;span class="str"&gt;&amp;quot;Month's Sales&amp;quot;&lt;/span&gt;);
report.print();
report.getLineItems();&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;In this example a base Report class is defined that has a variable (name), a constructor that accepts a name parameter of type string, and a function named print(). The FinanceReport class inherits from Report by using TypeScript’s &lt;i&gt;extends&lt;/i&gt; keyword. As a result, it automatically has access to the print() function in the base class. In this example the FinanceReport overrides the base class’s print() method and adds its own. The FinanceReport class also forwards the name value it receives in the constructor to the base class using the &lt;i&gt;super()&lt;/i&gt; call.&lt;/p&gt;

&lt;p&gt;TypeScript also supports the creation of custom interfaces when you need to provide consistency across a set of objects. The following code shows an example of an interface named &lt;i&gt;Thing&lt;/i&gt; (from the TypeScript samples) and a class named &lt;i&gt;Plane&lt;/i&gt; that implements the interface to drive consistency across the app. Notice that the Plane class includes intersect and normal as a result of implementing the interface. &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;interface&lt;/span&gt; Thing {
    intersect: (ray: Ray) =&amp;gt; Intersection;
    normal: (pos: Vector) =&amp;gt; Vector;
    surface: Surface;
}

&lt;span class="kwrd"&gt;class&lt;/span&gt; Plane implements Thing {
    normal: (pos: Vector) =&amp;gt;Vector;

    intersect: (ray: Ray) =&amp;gt;Intersection;

    constructor (norm: Vector, offset: number, &lt;span class="kwrd"&gt;public&lt;/span&gt; surface: Surface) {
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.normal = &lt;span class="kwrd"&gt;function&lt;/span&gt; (pos: Vector) { &lt;span class="kwrd"&gt;return&lt;/span&gt; norm; }
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.intersect = &lt;span class="kwrd"&gt;function&lt;/span&gt; (ray: Ray): Intersection {
            &lt;span class="kwrd"&gt;var&lt;/span&gt; denom = Vector.dot(norm, ray.dir);
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (denom &amp;gt; 0) {
                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt;;
            } &lt;span class="kwrd"&gt;else&lt;/span&gt; {
                &lt;span class="kwrd"&gt;var&lt;/span&gt; dist = (Vector.dot(norm, ray.start) + offset) / (-denom);
                &lt;span class="kwrd"&gt;return&lt;/span&gt; { thing: &lt;span class="kwrd"&gt;this&lt;/span&gt;, ray: ray, dist: dist };
            }
        }
    }
}&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;At first glance it doesn’t appear that the surface member is implemented in Plane but it’s actually included automatically due to the &lt;i&gt;public surface: Surface&lt;/i&gt; parameter in the constructor. Adding &lt;i&gt;public varName: Type&lt;/i&gt; to a constructor automatically adds a typed variable into the class without having to explicitly write the code as with &lt;i&gt;normal&lt;/i&gt; and &lt;i&gt;intersect&lt;/i&gt;.&lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;TypeScript has additional language features but defining static types and creating classes, modules, and interfaces are some of the key features it offers. So is TypeScript right for you and your applications? That’s a not a question that I or anyone else can answer for you. You’ll need to give it a spin to see what you think. In future posts I’ll discuss additional details about TypeScript and how it can be used with enterprise-scale JavaScript applications. In the meantime, I’m in the process of working with &lt;a href="http://johnpapa.net" target="_blank"&gt;John Papa&lt;/a&gt; on a new Typescript course for &lt;a href="http://www.pluralsight.com" target="_blank"&gt;Pluralsight&lt;/a&gt; that we hope to have out in December of 2012.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=9270960" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/dwahlin/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/HTML5/default.aspx">HTML5</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/TypeScript/default.aspx">TypeScript</category></item><item><title>Working with Tile Notifications in Windows 8 Store Apps – Part I</title><link>http://weblogs.asp.net/dwahlin/archive/2012/10/03/working-with-tile-notifications-in-windows-8-store-apps-part-i.aspx</link><pubDate>Thu, 04 Oct 2012 06:38:49 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:9041979</guid><dc:creator>dwahlin</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/dwahlin/rsscomments.aspx?PostID=9041979</wfw:commentRss><comments>http://weblogs.asp.net/dwahlin/archive/2012/10/03/working-with-tile-notifications-in-windows-8-store-apps-part-i.aspx#comments</comments><description>&lt;p&gt;One of the features that really makes Windows 8 apps stand out from others is the tile functionality on the start screen. While icons allow a user to start an application, tiles provide a more engaging way to engage the user and draw them into an application. Examples of “live” tiles on part of my current start screen are shown next: &lt;br&gt;&lt;br&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_09361A10.png"&gt;&lt;img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_5278BF0B.png" width="492" height="557"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;br&gt;I’ll admit that if you get enough of these tiles going the start screen can actually be a bit distracting. Fortunately, a user can easily disable a live tile by right-clicking on it or pressing and holding a tile on a touch device and then selecting &lt;strong&gt;Turn live tile off&lt;/strong&gt; from the AppBar: &lt;br&gt;&lt;br&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_383855E7.png"&gt;&lt;img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_3040B385.png" width="492" height="205"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;br&gt;The can also make a wide tile smaller (into a square tile) or make a square tile bigger assuming the application supports both squares and rectangles. In this post I’ll walk through how to add tile notification functionality into an application. Both XAML/C# and HTML/JavaScript apps support live tiles and I’ll show the code for both options. &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h1&gt;Understanding Tile Templates&lt;br&gt;&lt;/h1&gt; &lt;p&gt;The first thing you need to know if you want to add custom tile functionality (live tiles) into your application is that there is a collection of tile templates available out-of-the-box. Each tile template has XML associated with it that you need to load, update with your custom data, and then feed into a tile update manager. By doing that you can control what shows in your app’s tile on the Windows 8 start screen.&lt;/p&gt; &lt;p&gt;So how do you learn more about the different tile templates and their respective XML? Fortunately, Microsoft has a nice documentation page in the Windows 8 Store SDK. Visit &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh761491.aspx"&gt;http://msdn.microsoft.com/en-us/library/windows/apps/hh761491.aspx&lt;/a&gt; to see a complete list of square and wide/rectangular tile templates that you can use. Looking through the templates you’ll &lt;/p&gt; &lt;p&gt;&lt;br&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_48641DE0.png"&gt;&lt;img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_43ED9D19.png" width="150" height="150"&gt;&lt;/a&gt; &lt;br&gt;&lt;/p&gt; &lt;p&gt;It has the following XML template associated with it:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;tile&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;visual&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;binding&lt;/span&gt; &lt;span class="attr"&gt;template&lt;/span&gt;&lt;span class="kwrd"&gt;="TileSquareBlock"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;text&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="1"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Text Field 1&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;text&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;text&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="2"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Text Field 2&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;text&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;binding&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;  
  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;visual&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;tile&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;br&gt;An example of a wide/rectangular tile template is shown next:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_4EAAF46E.png"&gt;&lt;img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_5BA4D47F.png" width="240" height="116"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;tile&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;visual&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;binding&lt;/span&gt; &lt;span class="attr"&gt;template&lt;/span&gt;&lt;span class="kwrd"&gt;="TileWideImageAndText01"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;image&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="1"&lt;/span&gt; &lt;span class="attr"&gt;src&lt;/span&gt;&lt;span class="kwrd"&gt;="image1.png"&lt;/span&gt; &lt;span class="attr"&gt;alt&lt;/span&gt;&lt;span class="kwrd"&gt;="alt text"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;text&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="1"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Text Field 1&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;text&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;binding&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;  
  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;visual&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;tile&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;To use these tile templates (or others you find interesting), update their content, and get them to show for your app’s tile on the Windows 8 start screen you’ll need to perform the following steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Define the tile template to use in your app 
&lt;li&gt;Load the tile template’s XML into memory 
&lt;li&gt;Modify the children of the &amp;lt;binding&amp;gt; tag
&lt;li&gt;Feed the modified tile XML into a new TileNotification instance 
&lt;li&gt;Feed the TileNotification instance into the Update() method of the TileUpdateManager &lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;In the remainder of the post I’ll walk through each of the steps listed above to provide wide and square tile notifications for an application. The wide tile that’s shown will show an image and text while the square tile will only show text. If you’re going to provide custom tile notifications it’s recommended that you provide wide and square tiles since users can switch between the two of them directly on the start screen.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;strong&gt;Note:&lt;/strong&gt; When working with tile notifications it’s possible to manipulate and update a tile’s XML template without having to know XML parsing techniques. This can be accomplished using some C# notification extension classes that are available. In this post I’m going to focus on working with tile notifications using an XML parser so that the focus is on the steps required to add notifications to the Windows 8 start screen rather than on external extension classes. You can access the extension classes in the &lt;a href="http://code.msdn.microsoft.com/windowsapps/App-tiles-and-badges-sample-5fc49148/view/SourceCode#content" target="_blank"&gt;Windows 8 samples gallery&lt;/a&gt; if you’re interested.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Steps to Create Custom App Tile Notifications&lt;/h1&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;&lt;font color="#0000c1"&gt;Step 1: Define the tile template to use in your app&lt;/font&gt;&lt;/h2&gt;
&lt;p&gt;Although you can cut-and-paste a tile template’s XML directly into your C# or HTML/JavaScript Windows store app and then parse it using an XML parser, it’s easier to use the built-in &lt;strong&gt;TileTemplateType&lt;/strong&gt; enumeration from the &lt;strong&gt;Windows.UI.Notifications&lt;/strong&gt; namespace. It provides direct access to the XML for the various templates so once you locate a template you like in the documentation (mentioned above), simplify reference it:&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;strong&gt;HTML/JavaScript&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;var&lt;/span&gt; notifications = Windows.UI.Notifications;
&lt;span class="kwrd"&gt;var&lt;/span&gt; template = notifications.TileTemplateType.tileWideImageAndText01;&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;XAML/C#&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;pre class="csharpcode"&gt;var template = TileTemplateType.TileWideImageAndText01;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;br&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;h2&gt;&lt;font color="#0000c1"&gt;Step 2: Load the tile template’s XML into memory&lt;/font&gt; &lt;/h2&gt;
&lt;p&gt;Once the target template’s XML is identified, load it into memory using the TileUpdateManager’s GetTemplateContent() method. This method parses the template XML and returns an XmlDocument object:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTML/JavaScript&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;var&lt;/span&gt; tileXml = notifications.TileUpdateManager.getTemplateContent(template);&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;


&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;XAML/C#&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;pre class="csharpcode"&gt;var tileXml = TileUpdateManager.GetTemplateContent(template);&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;&lt;font color="#0000ff"&gt;&lt;br&gt;&lt;/font&gt;&lt;font color="#0000c1"&gt;Step 3: Modify the children of the &amp;lt;binding&amp;gt; tag&lt;/font&gt;&lt;/h2&gt;
&lt;p&gt;Once the XML for a given template is loaded into memory you need to locate the appropriate &amp;lt;image&amp;gt; and/or &amp;lt;text&amp;gt; elements in the XML and update them with your app data. This can be done using standard XML DOM manipulation techniques. The example code below locates the image folder and loads the path to an image file located in the project into it’s inner text. The code also creates a square tile that consists of text, updates it’s &amp;lt;text&amp;gt; element, and then imports and appends it into the wide tile’s XML.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTML/JavaScript&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;var&lt;/span&gt; image = tileXml.selectSingleNode(&lt;span class="str"&gt;'//image[@id="1"]'&lt;/span&gt;);
image.setAttribute(&lt;span class="str"&gt;'src'&lt;/span&gt;, &lt;span class="str"&gt;'ms-appx:///images/'&lt;/span&gt; + imageFile);
image.setAttribute(&lt;span class="str"&gt;'alt'&lt;/span&gt;, &lt;span class="str"&gt;'Live Tile'&lt;/span&gt;);

&lt;span class="kwrd"&gt;var&lt;/span&gt; squareTemplate = notifications.TileTemplateType.tileSquareText04;
&lt;span class="kwrd"&gt;var&lt;/span&gt; squareTileXml = notifications.TileUpdateManager.getTemplateContent(squareTemplate);
&lt;span class="kwrd"&gt;var&lt;/span&gt; squareTileTextAttributes = squareTileXml.selectSingleNode(&lt;span class="str"&gt;'//text[@id="1"]'&lt;/span&gt;);
squareTileTextAttributes.appendChild(squareTileXml.createTextNode(content));

&lt;span class="kwrd"&gt;var&lt;/span&gt; node = tileXml.importNode(squareTileXml.selectSingleNode(&lt;span class="str"&gt;'//binding'&lt;/span&gt;), &lt;span class="kwrd"&gt;true&lt;/span&gt;);
tileXml.selectSingleNode(&lt;span class="str"&gt;'//visual'&lt;/span&gt;).appendChild(node);
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;


&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;XAML/C#&lt;/strong&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;var tileXml = TileUpdateManager.GetTemplateContent(template);
var text = tileXml.SelectSingleNode(&lt;span class="str"&gt;"//text[@id='1']"&lt;/span&gt;);
text.AppendChild(tileXml.CreateTextNode(content));

var image = (XmlElement)tileXml.SelectSingleNode(&lt;span class="str"&gt;"//image[@id='1']"&lt;/span&gt;);
image.SetAttribute(&lt;span class="str"&gt;"src"&lt;/span&gt;, &lt;span class="str"&gt;"ms-appx:///Assets/"&lt;/span&gt; + imageFile);
image.SetAttribute(&lt;span class="str"&gt;"alt"&lt;/span&gt;, &lt;span class="str"&gt;"Live Tile"&lt;/span&gt;);
Debug.WriteLine(image.GetXml());

var squareTemplate = TileTemplateType.TileSquareText04;
var squareTileXml = TileUpdateManager.GetTemplateContent(squareTemplate);
var squareTileTextAttributes = squareTileXml.SelectSingleNode(&lt;span class="str"&gt;"//text[@id='1']"&lt;/span&gt;);
squareTileTextAttributes.AppendChild(squareTileXml.CreateTextNode(content));

var node = tileXml.ImportNode(squareTileXml.SelectSingleNode(&lt;span class="str"&gt;"//binding"&lt;/span&gt;), &lt;span class="kwrd"&gt;true&lt;/span&gt;);
tileXml.SelectSingleNode(&lt;span class="str"&gt;"//visual"&lt;/span&gt;).AppendChild(node);&lt;br&gt;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;br&gt;&lt;br&gt;&amp;nbsp;&lt;/pre&gt;
&lt;h2&gt;&lt;font color="#0000c1"&gt;Step 4: Feed the modified tile XML into a new TileNotification instance&lt;/font&gt;&lt;/h2&gt;
&lt;p&gt;Now that the XML data has been updated with the desired text and images, it’s time to load the XmlDocument object into a new TileNotification instance:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTML/JavaScript&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;var&lt;/span&gt; tileNotification = &lt;span class="kwrd"&gt;new&lt;/span&gt; notifications.TileNotification(tileXml);&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;


&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;XAML/C#&lt;/strong&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;var tileNotification = &lt;span class="kwrd"&gt;new&lt;/span&gt; TileNotification(tileXml);&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;h2&gt;&lt;br&gt;&lt;font color="#0000c1"&gt;Step 5: Feed the TileNotification instance into the Update() method of the TileUpdateManager&lt;/font&gt; &lt;/h2&gt;
&lt;p&gt;Once the TileNotification instance has been created and the XmlDocument has been passed to its constructor, it needs to be passed to the Update() method of a TileUpdator in order to be shown on the Windows 8 start screen:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTML/JavaScript&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="csharpcode"&gt;notifications.TileUpdateManager.createTileUpdaterForApplication().update(tileNotification);&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;


&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;XAML/C#&lt;/strong&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;TileUpdateManager.CreateTileUpdaterForApplication().Update(tileNotification);&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Once the tile notification is updated it’ll show up on the start screen. An example of the wide and square tiles created with the included demo code are shown next:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_33FE5855.png"&gt;&lt;img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_21495E9E.png" width="240" height="115"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_1951BC3C.png"&gt;&lt;img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_39009604.png" width="128" height="127"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Download the HTML/JavaScript and XAML/C# sample &lt;a href="https://dl.dropbox.com/u/6037348/Windows8/LiveTilesDemos.zip"&gt;application here&lt;/a&gt;. In the next post in this series I’ll walk through how to queue multiple tiles and clear a queue.&lt;/p&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=9041979" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/dwahlin/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/HTML5/default.aspx">HTML5</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/XAML/default.aspx">XAML</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/WinRT/default.aspx">WinRT</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/Windows+8/default.aspx">Windows 8</category></item><item><title>JavaScript Data Binding with AngularJS Part II – Binding a View to a Controller/ViewModel</title><link>http://weblogs.asp.net/dwahlin/archive/2012/08/05/javascript-data-binding-with-angularjs-part-ii-binding-a-view-to-a-controller-viewmodel.aspx</link><pubDate>Sun, 05 Aug 2012 17:00:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8817036</guid><dc:creator>dwahlin</dc:creator><slash:comments>15</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/dwahlin/rsscomments.aspx?PostID=8817036</wfw:commentRss><comments>http://weblogs.asp.net/dwahlin/archive/2012/08/05/javascript-data-binding-with-angularjs-part-ii-binding-a-view-to-a-controller-viewmodel.aspx#comments</comments><description>&lt;div class="note"&gt;   &lt;p&gt;     &lt;br /&gt;&lt;strong&gt;Related Posts:&lt;/strong&gt;&lt;/p&gt;    &lt;ul&gt;     &lt;li&gt;&lt;a href="http://weblogs.asp.net/dwahlin/archive/2012/07/08/javascript-data-binding-frameworks.aspx" target="_blank"&gt;JavaScript Data Binding Frameworks&lt;/a&gt; &lt;/li&gt;      &lt;li&gt;&lt;a href="http://weblogs.asp.net/dwahlin/archive/2012/07/27/The-JavaScript-Cheese-is-Moving_3A00_-Data_2D00_Oriented-vs.-Control_2D00_Oriented-Programming.aspx" target="_blank"&gt;The JavaScript Cheese is Moving: Data-Oriented vs. Control-Oriented Programming&lt;/a&gt; &lt;/li&gt;      &lt;li&gt;&lt;a href="http://weblogs.asp.net/dwahlin/archive/2012/07/29/javascript-data-binding-with-angularjs-getting-started.aspx" target="_blank"&gt;JavaScript Data Binding with AngularJS Part I – Getting Started&lt;/a&gt;         &lt;br /&gt;        &lt;br /&gt;&lt;/li&gt;   &lt;/ul&gt; &lt;/div&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;img style="margin: 0px 15px 15px 0px; display: inline; float: left" align="left" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_0D4C5C5C.png" width="170" height="48" /&gt;In my &lt;a href="http://weblogs.asp.net/dwahlin/archive/2012/07/29/javascript-data-binding-with-angularjs-getting-started.aspx" target="_blank"&gt;previous post&lt;/a&gt; I showed how the &lt;a href="http://angularjs.org" target="_blank"&gt;AngularJS&lt;/a&gt; framework could be used to bind data into a webpage. By using special directives such as &lt;strong&gt;ng-model&lt;/strong&gt; combined with moustache data binding syntax (i.e. {{ name }}) it’s easy to get started binding data into a page. In this post I’ll walk you through the process of creating a controller that stores data and provides functions that can be called from a page. The controller will reference and rely on a special object named $scope that acts as a type of “View Model” (a common term to those who use the MVVM pattern) and is responsible for monitoring changes to properties. Let’s take a look at the steps required to create an AngularJS controller and bind its properties into a page’s controls.     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;Step 1: Add the ng-app Directive and the AngularJS Script    &lt;br /&gt;    &lt;br /&gt;&lt;/h2&gt;  &lt;p&gt;To get started you’ll need to add the &lt;strong&gt;ng-app&lt;/strong&gt; directive into the page (adding it on the root &amp;lt;html&amp;gt; tag makes AngularJS functionality available throughout the entire page) and add a script reference to AngularJS. You can grab it directly from the CDN location at &lt;a href="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"&gt;https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js&lt;/a&gt; if you want – just change the version to the latest as needed.    &lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: maroon"&gt;DOCTYPE &lt;/span&gt;&lt;span style="color: red"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;html &lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;ng-app&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;a href="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"&gt;https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js&lt;/a&gt;&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;       ...        &lt;/span&gt;&lt;span style="color: blue"&gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Step 2: Create a Controller/ViewModel Script&lt;/h2&gt;

&lt;p&gt;
  &lt;br /&gt;Add a new JavaScript file named &lt;strong&gt;peopleCtrl.js&lt;/strong&gt; into the site with the following code: &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;PeopleCtrl($scope)  {
    $scope.people = [
        {firstName: &lt;span style="color: maroon"&gt;'John'&lt;/span&gt;, lastName: &lt;span style="color: maroon"&gt;'Doe'&lt;/span&gt;, address: {city: &lt;span style="color: maroon"&gt;'Chandler'&lt;/span&gt;, state: &lt;span style="color: maroon"&gt;'AZ'&lt;/span&gt;, zip: 85248}},
        {firstName: &lt;span style="color: maroon"&gt;'Jane'&lt;/span&gt;, lastName: &lt;span style="color: maroon"&gt;'Doe'&lt;/span&gt;, address: {city: &lt;span style="color: maroon"&gt;'Chandler'&lt;/span&gt;, state: &lt;span style="color: maroon"&gt;'AZ'&lt;/span&gt;, zip: 85248}},
        {firstName: &lt;span style="color: maroon"&gt;'Johnny'&lt;/span&gt;, lastName: &lt;span style="color: maroon"&gt;'Doe'&lt;/span&gt;, address: {city: &lt;span style="color: maroon"&gt;'Phoenix'&lt;/span&gt;, state: &lt;span style="color: maroon"&gt;'AZ'&lt;/span&gt;, zip: 85003}}
    ];

    $scope.addNew = &lt;span style="color: blue"&gt;function&lt;/span&gt;() {
        $scope.people.push({ firstName: $scope.firstName, lastName: $scope.lastName,
                             address: {city: $scope.city, state: $scope.state, zip: $scope.zip} });
    }
}&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;
  &lt;br /&gt;This example defines a &lt;strong&gt;people&lt;/strong&gt; property that has an array of objects assigned to it as well as a function named &lt;strong&gt;addNew()&lt;/strong&gt; that can be used to add additional people to the array. The property will be bound into the view. In looking through the code you’ll note that a &lt;a href="http://docs.angularjs.org/guide/scope" target="_blank"&gt;$scope parameter&lt;/a&gt; is passed into PeopleCtrl. This parameter acts as the “glue” between the view (the webpage) and the controller and handles watching the model for changes (think of it as the view model). Any model changes that are detected are propagated back to the view or to the controller depending on which side initiated the model change. The $scope parameter is automatically passed by AngularJS into the controller.&lt;/p&gt;

&lt;p&gt;The $scope parameter is used inside of the controller to define properties and functions. This allows the controller to be completely isolated from the view and the DOM which is necessary if you’d like to do unit testing. Using $scope also allows properties such as &lt;strong&gt;people&lt;/strong&gt; in this example to automatically be monitored for changes without having to write any quirky code inside of it. Any property that needs to be monitored for changes can be associated with $scope to have its changes pushed down to the view. If the property is bound to a control such as a textbox in the view, any changes made by the end user will cause the appropriate controller property to automatically be updated. This provides an excellent mechanism for writing &lt;a href="http://weblogs.asp.net/dwahlin/archive/2012/07/27/The-JavaScript-Cheese-is-Moving_3A00_-Data_2D00_Oriented-vs.-Control_2D00_Oriented-Programming.aspx" target="_blank"&gt;data-oriented code&lt;/a&gt; as opposed to control-oriented code.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Step 3: Define the Controller/ViewModel in the Page 
  &lt;br /&gt;

  &lt;br /&gt;&lt;/h2&gt;

&lt;p&gt;To associate the controller with the view the &lt;strong&gt;ng-controller&lt;/strong&gt; directive can be added into the HTML as shown next. &lt;/p&gt;

&lt;div class="note"&gt;
  &lt;p&gt;
    &lt;br /&gt;Note that AngularJS directives can be prefixed with &lt;strong&gt;data-&lt;/strong&gt; if you prefer which can be helpful when running the code against validators that don’t like custom attributes and instead require that any custom attributes be prefixed with data-. For example, &lt;strong&gt;data-ng-controller=”PeopleCtrl”&lt;/strong&gt; is perfectly acceptable with AngularJS as is &lt;strong&gt;data-ng-app&lt;/strong&gt;. 

    &lt;br /&gt;

    &lt;br /&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;ng-controller&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;PeopleCtrl&amp;quot;&lt;/strong&gt;&amp;gt;        
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;peopleContainer&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;h4&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Add New Person:&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;h4&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;table &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;: 300px&amp;quot;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;: 30%;&amp;quot;&amp;gt;&lt;/span&gt;First Name:&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;: 70%;&amp;quot;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;ng-model&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;firstName&amp;quot; /&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;: 30%;&amp;quot;&amp;gt;&lt;/span&gt;Last Name:&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;: 70%;&amp;quot;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;ng-model&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;lastName&amp;quot; /&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;: 30%;&amp;quot;&amp;gt;&lt;/span&gt;City:&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;: 70%;&amp;quot;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;ng-model&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;city&amp;quot; /&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;: 30%;&amp;quot;&amp;gt;&lt;/span&gt;State:&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;: 70%;&amp;quot;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;ng-model&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;state&amp;quot; /&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;: 30%;&amp;quot;&amp;gt;&lt;/span&gt;Zip:&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;: 70%;&amp;quot;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;ng-model&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;zip&amp;quot; /&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;colspan&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;2&amp;quot;&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;button&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Add&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;button&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;table&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;                
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;br /&gt;

&lt;p&gt;
  &lt;br /&gt;This code handles referencing the controller as well as some textboxes and a button that the user can use to add a new person. Each textbox has an &lt;strong&gt;ng-model&lt;/strong&gt; attribute on it to allow the values to easily be accessed in the controller. You’ll see how the textbox values are accessed in a later step.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Step 4: Iterate Through the people Property Values&lt;/h2&gt;

&lt;p&gt;
  &lt;br /&gt;Once the &lt;strong&gt;PeopleCtrl &lt;/strong&gt;is referenced in the view you can add code to iterate through the controller’s &lt;strong&gt;people&lt;/strong&gt; property. Iteration can be accomplished using AngularJS’s &lt;strong&gt;ng-repeat&lt;/strong&gt; directive as shown next. 

  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;peopleContainer&amp;quot;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li &lt;/span&gt;&lt;span style="color: red"&gt;ng-repeat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;person in people&amp;quot;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;span &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;bold&amp;quot;&amp;gt;&lt;/span&gt;{{person.firstName}} {{person.lastName}}&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;span&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;br &lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;
            &lt;/span&gt;{{person.address.city}}, {{person.address.state}}&lt;span style="color: red"&gt;&amp;amp;nbsp;&amp;amp;nbsp;&lt;/span&gt;{{person.address.zip}}
        &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;br /&gt;

&lt;br /&gt;The &lt;strong&gt;ng-repeat&lt;/strong&gt; directive iterates through each object in the &lt;strong&gt;people&lt;/strong&gt; property of the controller and assigns each object to a variable named &lt;strong&gt;person&lt;/strong&gt;. Each &lt;strong&gt;person&lt;/strong&gt; object is then bound into the view using the mustache syntax (for example, {{person.lastName}} binds the lastName property of each person into the view) resulting in multiple &amp;lt;li&amp;gt; elements being created dynamically. 

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Step 5: Calling Controller Functions&lt;/h2&gt;

&lt;br /&gt;

&lt;p&gt;The controller has a function named &lt;strong&gt;addNew()&lt;/strong&gt; that needs to be called when the &lt;strong&gt;Add&lt;/strong&gt; button is clicked. To wire up the button to the controller function the &lt;strong&gt;ng-click&lt;/strong&gt; directive can be used: 

  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;button &lt;/span&gt;&lt;span style="color: red"&gt;ng-click&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;addNew()&amp;quot;&amp;gt;&lt;/span&gt;Add&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;button&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;When the button is clicked the values from the textboxes are accessed in the controller through the $scope and the new person is added to the &lt;strong&gt;people&lt;/strong&gt; property array. This is made possible due to the presence of the &lt;strong&gt;ng-model&lt;/strong&gt; directive on each each textbox. &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre class="code"&gt;$scope.addNew = &lt;span style="color: blue"&gt;function&lt;/span&gt;() {
    $scope.people.push({ firstName: $scope.firstName, lastName: $scope.lastName,
                            address: {city: $scope.city, state: $scope.state, zip: $scope.zip} });
}&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;
  &lt;br /&gt;

  &lt;br /&gt;In this example we’re accessing each textbox value directly through the $scope variable. It’s important to note that no code is written to manually find textbox controls by their ID (something I call &lt;a href="http://weblogs.asp.net/dwahlin/archive/2012/07/27/The-JavaScript-Cheese-is-Moving_3A00_-Data_2D00_Oriented-vs.-Control_2D00_Oriented-Programming.aspx" target="_blank"&gt;control-oriented programming&lt;/a&gt;) and then extract the value. Instead, we’re relying on JavaScript data binding which significantly reduces the amount of code that has to be written. 

  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;While this works well, it can be cleaned up a little by having AngularJS create a JavaScript object literal for us automatically that is then added into the controller’s &lt;strong&gt;people&lt;/strong&gt; collection. By prefixing the &lt;strong&gt;ng-model&lt;/strong&gt; directive with &lt;strong&gt;person.&lt;/strong&gt; an object literal will be created which can then be added more easily into &lt;strong&gt;$scope.people &lt;/strong&gt;in the controller. Here’s an example of how the modified HTML looks – notice the change to each &lt;strong&gt;ng-model&lt;/strong&gt; directive on the different textboxes. 

  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;table &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;: 300px&amp;quot;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;: 30%;&amp;quot;&amp;gt;&lt;/span&gt;First Name:&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;: 70%;&amp;quot;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;ng-model&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;person.firstName&amp;quot; /&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;: 30%;&amp;quot;&amp;gt;&lt;/span&gt;Last Name:&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;: 70%;&amp;quot;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;ng-model&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;person.lastName&amp;quot; /&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;: 30%;&amp;quot;&amp;gt;&lt;/span&gt;City:&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;: 70%;&amp;quot;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;ng-model&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;person.address.city&amp;quot; /&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;: 30%;&amp;quot;&amp;gt;&lt;/span&gt;State:&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;: 70%;&amp;quot;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;ng-model&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;person.address.state&amp;quot; /&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;: 30%;&amp;quot;&amp;gt;&lt;/span&gt;Zip:&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;: 70%;&amp;quot;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;ng-model&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;person.address.zip&amp;quot; /&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;colspan&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;2&amp;quot;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;button &lt;/span&gt;&lt;span style="color: red"&gt;data-ng-click&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;addNew(person)&amp;quot;&amp;gt;&lt;/span&gt;Add&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;button&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;table&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;This will create the following object literal behind the scenes automatically:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre class="code"&gt;{
    firstName: &lt;span style="color: maroon"&gt;'...'&lt;/span&gt;,
    lastName: &lt;span style="color: maroon"&gt;'...'
    &lt;/span&gt;address: {
        street: &lt;span style="color: maroon"&gt;'...'&lt;/span&gt;,
        city: &lt;span style="color: maroon"&gt;'...'&lt;/span&gt;,
        zip: &lt;span style="color: maroon"&gt;'...'
    &lt;/span&gt;}
}&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;
  &lt;br /&gt;

  &lt;br /&gt;Code in the addNew() function can be reduced quite a bit by having the object literal available. This is nice especially when you consider that with a control-oriented approach you’d have to write code to access each control by ID and grab the value. Using this approach, addNew() in the webpage becomes addNew(person) and the function in the controller changes to the following:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre class="code"&gt;$scope.addNew = &lt;span style="color: blue"&gt;function&lt;/span&gt;(person) {
    $scope.people.push(person);
    $scope.person = {}; //Clear out person object
}&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;
  &lt;br /&gt;

  &lt;br /&gt;A live example of the demo code in action is shown next. Click the &lt;strong&gt;Result&lt;/strong&gt; tab to run it. 

  &lt;br /&gt;

  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;
&lt;iframe style="width: 100%; height: 404px" src="http://jsfiddle.net/dwahlin/Y3BJa/embedded/" frameborder="0" allowfullscreen="allowfullscreen"&gt;&lt;/iframe&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;In this post you’ve seen how an AngularJS controller/view model can be created and how its properties can be bound to a view. By using a data-oriented framework like AngularJS (see my &lt;a href="http://weblogs.asp.net/dwahlin/archive/2012/07/08/javascript-data-binding-frameworks.aspx" target="_blank"&gt;previous post&lt;/a&gt; for a list of additional frameworks) you can minimize the amount of code that has to be written and simplify the overall application. In future posts I’ll keep digging into the AngularJS framework and provide additional examples of some of the great features it provides. 

  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;&lt;strong&gt;&lt;img src="http://weblogs.asp.net/blogs/dwahlin/pluralsight.png" /&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pluralsight Subscribers:&lt;/strong&gt; Would you be interested in seeing a course on AngularJS? Help me out by completing the simple &lt;a href="http://www.surveymonkey.com/s/PN2XKJJ" target="_blank"&gt;1-question survey here&lt;/a&gt;. If there’s enough interest I’ll add it to my list of future courses to consider building.&lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;

  &lt;br /&gt;&lt;strong&gt;Pluralsight Courses:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://www.pluralsight-training.net/microsoft/Courses/TableOfContents?courseName=web-development"&gt;Building ASP.NET MVC, EF Code First, HTML5, and jQuery Apps&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://www.pluralsight-training.net/microsoft/Courses/TableOfContents?courseName=html5-canvas-fundamentals"&gt;HTML5 Canvas Fundamentals&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://www.pluralsight-training.net/microsoft/Courses/TableOfContents?courseName=jquery-fundamentals"&gt;jQuery Fundamentals&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://www.pluralsight-training.net/microsoft/Courses/TableOfContents?courseName=aspdotnet-webforms4-intro"&gt;Introduction to ASP.NET WebForms&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://www.pluralsight-training.net/microsoft/Courses/TableOfContents?courseName=win8-intro"&gt;Introduction to Windows 8 Metro Apps&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://www.pluralsight-training.net/microsoft/Courses/TableOfContents?courseName=structuring-javascript"&gt;Structuring JavaScript Code&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8817036" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/dwahlin/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/JSON/default.aspx">JSON</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/HTML5/default.aspx">HTML5</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/Design+Patterns/default.aspx">Design Patterns</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/jQuery+Mobile/default.aspx">jQuery Mobile</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/Databinding/default.aspx">Databinding</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/AngularJS/default.aspx">AngularJS</category></item><item><title>JavaScript Data Binding with AngularJS Part I –  Getting Started</title><link>http://weblogs.asp.net/dwahlin/archive/2012/07/29/javascript-data-binding-with-angularjs-getting-started.aspx</link><pubDate>Mon, 30 Jul 2012 04:52:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8798152</guid><dc:creator>dwahlin</dc:creator><slash:comments>17</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/dwahlin/rsscomments.aspx?PostID=8798152</wfw:commentRss><comments>http://weblogs.asp.net/dwahlin/archive/2012/07/29/javascript-data-binding-with-angularjs-getting-started.aspx#comments</comments><description>&lt;div class="note"&gt;   &lt;p&gt;     &lt;br /&gt;&lt;strong&gt;Related Posts:&lt;/strong&gt;&lt;/p&gt;    &lt;ul&gt;     &lt;li&gt;&lt;a href="http://weblogs.asp.net/dwahlin/archive/2012/07/08/javascript-data-binding-frameworks.aspx" target="_blank"&gt;JavaScript Data Binding Frameworks&lt;/a&gt; &lt;/li&gt;      &lt;li&gt;&lt;a href="http://weblogs.asp.net/dwahlin/archive/2012/07/27/The-JavaScript-Cheese-is-Moving_3A00_-Data_2D00_Oriented-vs.-Control_2D00_Oriented-Programming.aspx" target="_blank"&gt;The JavaScript Cheese is Moving: Data-Oriented vs. Control-Oriented Programming&lt;/a&gt; &lt;/li&gt;   &lt;/ul&gt; &lt;/div&gt;
&lt;br /&gt;&lt;br /&gt;

&lt;p&gt;In a &lt;a href="http://weblogs.asp.net/dwahlin/archive/2012/07/27/The-JavaScript-Cheese-is-Moving_3A00_-Data_2D00_Oriented-vs.-Control_2D00_Oriented-Programming.aspx" target="_blank"&gt;previous post&lt;/a&gt; I talked about where I see things moving when it comes to the world of client-side JavaScript development. Although a lot of applications are still being built using control-oriented programming with JavaScript frameworks like jQuery, I think that the the development landscape is gradually embracing a more data-oriented programming approach and starting to take advantage of &lt;a href="http://weblogs.asp.net/dwahlin/archive/2012/07/08/javascript-data-binding-frameworks.aspx" target="_blank"&gt;data binding frameworks&lt;/a&gt; that make it easier to build and maintain CRUD applications. &lt;/p&gt;  &lt;p&gt;In this post I’m going to introduce one of the JavaScript data binding frameworks that can be used for data-oriented programming called &lt;a href="http://angularjs.org/" target="_blank"&gt;AngularJS&lt;/a&gt; and show how it can be used. I’ve been experimenting with AngularJS a lot lately and like what I’ve seen up to this point. I’ll follow this post up with additional posts that drill-down into the framework more and provide details on pros and cons I’ve found. If you’re interested in seeing alternative data binding frameworks check out my &lt;a href="http://weblogs.asp.net/dwahlin/archive/2012/07/08/javascript-data-binding-frameworks.aspx" target="_blank"&gt;earlier post&lt;/a&gt;.     &lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;h2&gt;Getting Started with AngularJS    &lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;/h2&gt;  &lt;p&gt;&lt;img style="margin: 0px 15px 10px 0px; display: inline; float: left" align="left" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_0D4C5C5C.png" /&gt;So what is AngularJS and why is it worth taking a closer look? To answer that question take a moment to think about the features provided by HTML. It’s no secret that it wasn’t designed with dynamic applications in mind – it’s a static markup language after all. With raw HTML you can’t perform looping operations that create new elements, filter UI elements as other elements change, or perform a variety of other tasks that dynamic Web applications require. When compared to Flex, Silverlight, WPF, and other UI frameworks it’s quite limiting. We work around the limitations by generating HTML dynamically on the server or by using JavaScript frameworks like jQuery to manipulate the DOM on the client-side.&lt;/p&gt;  &lt;p&gt;AngularJS extends HTML to support dynamic applications which means it’s well suited for CRUD-centric types of applications. For example, it allows &amp;lt;option&amp;gt; tags in a &amp;lt;select&amp;gt; to be dynamically generated without having to write custom JavaScript code to perform that task, tracks changes made to UI elements and the data they’re bound to, provides filtering/sorting support, and much more. The AngularJS documentation (&lt;a href="http://docs.angularjs.org/guide/overview"&gt;http://docs.angularjs.org/guide/overview&lt;/a&gt;) words it this way:&lt;/p&gt;  &lt;p&gt;“Angular takes another approach. It attempts to minimize the impedance mismatch between document centric HTML and what application needs by creating new HTML constructs. Angular teaches the browser new syntax through a construct we call directives.”&lt;/p&gt;  &lt;p&gt;AngularJS frees you from having to do the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Register callbacks &lt;/li&gt;    &lt;li&gt;Manipulate the DOM programmatically &lt;/li&gt;    &lt;li&gt;Move data in and out of the UI manually with code &lt;/li&gt;    &lt;li&gt;Writing a bunch of initialization code just to get started &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Here’s a list of features that it provides out of the box. &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Data binding &lt;/li&gt;    &lt;li&gt;Data filtering/sorting &lt;/li&gt;    &lt;li&gt;Data templates &lt;/li&gt;    &lt;li&gt;Ajax support &lt;/li&gt;    &lt;li&gt;Form validation &lt;/li&gt;    &lt;li&gt;Routing &lt;/li&gt;    &lt;li&gt;History support &lt;/li&gt;    &lt;li&gt;Deep linking &lt;/li&gt;    &lt;li&gt;Modular and reusable components &lt;/li&gt;    &lt;li&gt;Loosely coupled architecture (dependency injection) &lt;/li&gt;    &lt;li&gt;MVC-style applications &lt;/li&gt;    &lt;li&gt;Architected with unit testing in mind &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;You can see that AngularJS is much more than a simple data binding framework – it’s more of a client-side JavaScript application framework. If you don’t like a particular feature that AngularJS provides you can inject custom code using the dependency injection functionality that’s provided. I won’t cover that topic here but you can find additional details about it and many other topics in the &lt;a href="http://docs.angularjs.org/guide/" target="_blank"&gt;AngularJS docs&lt;/a&gt;.     &lt;br /&gt;    &lt;br /&gt;To help get you started with AngularJS I’ve put together a “Hello World” type tutorial that I plan to follow-up with additional posts in the future. Let’s jump in and take a look at the basics.     &lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;h3&gt;Step 1: Get the Script&lt;/h3&gt;  &lt;p&gt;To get started using AngularJS you’ll need to grab the script from &lt;a href="http://www.angularjs.org"&gt;http://www.angularjs.org&lt;/a&gt; (or from their &lt;a href="https://github.com/angular/angular.js" target="_blank"&gt;github&lt;/a&gt; site) and include it in your page.     &lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: maroon"&gt;DOCTYPE &lt;/span&gt;&lt;span style="color: red"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;js/libs/angular-[version].js&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        ...&lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;h3&gt;
  &lt;br /&gt;

  &lt;br /&gt;Step 2: Add the ng-app Directive&lt;/h3&gt;

&lt;p&gt;
  &lt;br /&gt;Next, you’ll need to add an AngularJS directive named &lt;strong&gt;ng-app&lt;/strong&gt; into the page that defines your application root. You can put &lt;strong&gt;ng-app&lt;/strong&gt; on the &amp;lt;html&amp;gt; tag or on a tag somewhere else in the document (such as a &amp;lt;div&amp;gt;) if only a portion of a page needs AngularJS functionality. AngularJS initializes when the DOMContentLoaded event fires and then looks for the &lt;strong&gt;ng-app&lt;/strong&gt; directive. 

  &lt;br /&gt;

  &lt;br /&gt;Here’s an example of defining the &lt;strong&gt;ng-app&lt;/strong&gt; directive on the &amp;lt;html&amp;gt; element. This example doesn’t assign a value to the directive but in a future post I’ll show how &lt;strong&gt;ng-app&lt;/strong&gt; can be used to define custom application modules that provide additional functionality such as routing, REST calls, and more. 

  &lt;br /&gt;

  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: maroon"&gt;DOCTYPE &lt;/span&gt;&lt;span style="color: red"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;html &lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;ng-app&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;js/libs/angular-[version].js&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;       ...        &lt;/span&gt;&lt;span style="color: blue"&gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
  &lt;br /&gt;

  &lt;br /&gt;Alternatively, you can define the application root programmatically if you’d prefer to go with a more jQuery-style approach: 

  &lt;br /&gt;

  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: maroon"&gt;DOCTYPE &lt;/span&gt;&lt;span style="color: red"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;    &lt;span style="color: blue"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;js/libs/angular-[version].js&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt; &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &lt;/span&gt;angular.element(document).ready(&lt;span style="color: blue"&gt;function &lt;/span&gt;() {
            angular.bootstrap(document);
        });
    &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;  &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt; &lt;br /&gt;&lt;br /&gt;     ...  &lt;br /&gt;&lt;span style="color: blue"&gt;  &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
  &lt;br /&gt;

  &lt;br /&gt;Note that jQuery can be used with AngularJS but it isn’t required. 

  &lt;br /&gt;

  &lt;br /&gt;

  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;h3&gt;Step 3: Add a Control with an ng-model Directive&lt;/h3&gt;

&lt;p&gt;
  &lt;br /&gt;Once the &lt;strong&gt;ng-app&lt;/strong&gt; directive is added you can start using AngularJS’s data binding functionality. You can do simple data binding which I’ll show here or bind to objects that define properties and functions. To get started, add a control such as a textbox that has another AngularJS directive named &lt;strong&gt;ng-model &lt;/strong&gt;on it. The &lt;strong&gt;ng-model&lt;/strong&gt; directive defines the property of the model that you’ll bind to. In this example I don’t have a model object (I’ll show how to create one in a future post) and will bind the “name” property to text in the page. 

  &lt;br /&gt;

  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;pre class="code"&gt;Name: &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;ng-model&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;name&amp;quot; /&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
  &lt;br /&gt;

  &lt;br /&gt;To bind another part of the page to the value of the textbox simple “mustache” brackets ({{ and }} brackets) can be used. This is common with template frameworks like Mustache.js and others. An example of binding to the &lt;strong&gt;ng-model&lt;/strong&gt; value defined on the textbox is shown next: 

  &lt;br /&gt;

  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;pre class="code"&gt;Welcome to AngularJS {{name}}&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;
  &lt;br /&gt;

  &lt;br /&gt;And that’s it! You’ve just performed your first AngularJS data binding operation. As the textbox value changes the {{name}} binding will automatically change as well. Try it out in the following live example (you’ll need to click on the “Result” tab below to run it): 

  &lt;br /&gt;

  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;
&lt;iframe style="width: 100%; height: 187px" src="http://jsfiddle.net/dwahlin/qLxur/embedded/" frameborder="0" allowfullscreen="allowfullscreen"&gt;&lt;/iframe&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;I’ve barely scratched the surface when it comes to building data-oriented applications with AngularJS – the goal with this post is to provide a rudimentary sample. In the next post I’ll show how AngularJS can be used to bind to model object properties and perform two-way data binding.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8798152" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/dwahlin/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/JSON/default.aspx">JSON</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/HTML5/default.aspx">HTML5</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/Design+Patterns/default.aspx">Design Patterns</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/jQuery+Mobile/default.aspx">jQuery Mobile</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/Databinding/default.aspx">Databinding</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/AngularJS/default.aspx">AngularJS</category></item><item><title>The JavaScript Cheese is Moving: Data-Oriented vs. Control-Oriented Programming</title><link>http://weblogs.asp.net/dwahlin/archive/2012/07/27/The-JavaScript-Cheese-is-Moving_3A00_-Data_2D00_Oriented-vs.-Control_2D00_Oriented-Programming.aspx</link><pubDate>Fri, 27 Jul 2012 22:52:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8790706</guid><dc:creator>dwahlin</dc:creator><slash:comments>11</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/dwahlin/rsscomments.aspx?PostID=8790706</wfw:commentRss><comments>http://weblogs.asp.net/dwahlin/archive/2012/07/27/The-JavaScript-Cheese-is-Moving_3A00_-Data_2D00_Oriented-vs.-Control_2D00_Oriented-Programming.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/Cheese_14DFB731.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top: 0px; border-right: 0px; padding-top: 0px" title="Cheese" border="0" alt="Cheese" align="left" src="http://weblogs.asp.net/blogs/dwahlin/Cheese_thumb_1EC4A89C.png" width="114" height="108" /&gt;&lt;/a&gt;In a previous post I listed several of the &lt;a href="http://weblogs.asp.net/dwahlin/archive/2012/07/08/javascript-data-binding-frameworks.aspx" target="_blank"&gt;JavaScript data binding frameworks&lt;/a&gt; that are available and talked about why they’re essential as applications move more and more functionality to the client. Data binding is a key aspect of client-centric programming that can significantly minimize the amount of code written, simplify maintenance, and ultimately reduce the number of bugs that crop up in an application. Without data binding you have to locate each control in a page with code and then assign or extract a value to/from it – something I call “control-oriented” programming. Here’s an example of control-oriented programming:&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;    &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;loadApprovalDiv()
{
    &lt;span style="color: blue"&gt;var &lt;/span&gt;subTotal = parseFloat($(&lt;span style="color: maroon"&gt;'#SubTotal'&lt;/span&gt;).text());
    $(&lt;span style="color: maroon"&gt;'#ClientSubTotal'&lt;/span&gt;).val(subTotal.toFixed(2));
    &lt;span style="color: blue"&gt;var &lt;/span&gt;salesTaxRate = parseFloat($(&lt;span style="color: maroon"&gt;'#SalesTaxRate'&lt;/span&gt;).val()) / 100;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;salesTaxAmount = (subTotal * salesTaxRate) * .9;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;deliveryFee = parseFloat($(&lt;span style="color: maroon"&gt;'#DeliveryFee'&lt;/span&gt;).val());
    &lt;span style="color: blue"&gt;var &lt;/span&gt;adminFee = ((subTotal + salesTaxAmount + deliveryFee) * .05);
    &lt;span style="color: blue"&gt;var &lt;/span&gt;total = (Round(subTotal) + Round(salesTaxAmount) + Round(deliveryFee) + 
                 Round(adminFee));
    $(&lt;span style="color: maroon"&gt;'#ClientTotal'&lt;/span&gt;).val(total);
    &lt;span style="color: blue"&gt;var &lt;/span&gt;deliveryAddress = $(&lt;span style="color: maroon"&gt;'#Delivery_Street'&lt;/span&gt;).val();
    &lt;span style="color: #006400"&gt;//See if they entered a suite
    &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;($(&lt;span style="color: maroon"&gt;'#Delivery_Suite'&lt;/span&gt;).val() != &lt;span style="color: maroon"&gt;''&lt;/span&gt;) deliveryAddress += &lt;span style="color: maroon"&gt;', Suite ' &lt;/span&gt;+ $(&lt;span style="color: maroon"&gt;'#Delivery_Suite'&lt;/span&gt;).val();
    deliveryAddress += &lt;span style="color: maroon"&gt;' ' &lt;/span&gt;+ $(&lt;span style="color: maroon"&gt;'#Delivery_City'&lt;/span&gt;).val() + &lt;span style="color: maroon"&gt;' ' &lt;/span&gt;+ &lt;br /&gt;                       $(&lt;span style="color: maroon"&gt;'#Delivery_StateID option:selected'&lt;/span&gt;).text() + &lt;span style="color: maroon"&gt;' ' &lt;/span&gt;+ $(&lt;span style="color: maroon"&gt;'#Delivery_Zip'&lt;/span&gt;).val();
   
    &lt;span style="color: blue"&gt;var &lt;/span&gt;data = {
                   &lt;span style="color: maroon"&gt;FinalSubTotal  &lt;/span&gt;: subTotal.toFixed(2),
                   &lt;span style="color: maroon"&gt;FinalSalesTax  &lt;/span&gt;: salesTaxAmount.toFixed(2),
                   &lt;span style="color: maroon"&gt;FinalTotal     &lt;/span&gt;: total.toFixed(2),
                   &lt;span style="color: maroon"&gt;DeliveryFee    &lt;/span&gt;: deliveryFee.toFixed(2),
                   &lt;span style="color: maroon"&gt;AdminFee       &lt;/span&gt;: adminFee.toFixed(2),
                   &lt;span style="color: maroon"&gt;DeliveryName   &lt;/span&gt;: $(&lt;span style="color: maroon"&gt;'#Delivery_Name'&lt;/span&gt;).val(),
                   &lt;span style="color: maroon"&gt;DeliveryAddress&lt;/span&gt;: deliveryAddress,
                   &lt;span style="color: maroon"&gt;DeliveryDate   &lt;/span&gt;: $(&lt;span style="color: maroon"&gt;'#Delivery_DeliveryDate'&lt;/span&gt;).val(),
                   &lt;span style="color: maroon"&gt;DeliveryTime   &lt;/span&gt;: $(&lt;span style="color: maroon"&gt;'#Delivery_DeliveryTime option:selected'&lt;/span&gt;).text(),
                   &lt;span style="color: maroon"&gt;MainItems      &lt;/span&gt;: generateJson(&lt;span style="color: maroon"&gt;'Main'&lt;/span&gt;),
                   &lt;span style="color: maroon"&gt;AccessoryItems &lt;/span&gt;: generateJson(&lt;span style="color: maroon"&gt;'Accessory'&lt;/span&gt;)
               };


        $(&lt;span style="color: maroon"&gt;&amp;quot;#OrderSummaryOutput&amp;quot;&lt;/span&gt;).html(
            $(&lt;span style="color: maroon"&gt;&amp;quot;#OrderSummaryTemplate&amp;quot;&lt;/span&gt;).render(data)
        );
}&lt;br /&gt;&lt;/pre&gt;
  &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Looking through the code you can see that a lot of it is dedicated to finding controls in the page and extracting their values. This works absolutely fine – after all, many applications take this approach. However, when an application is focused on controls and not on data a lot of extra code and plumbing ends up being written which complicates things if control IDs are changed, new controls are added, or existing controls are removed. If you only have a few controls that’s not a big deal, but as the number of controls grows it becomes problematic. I think the &lt;a href="http://www.amazon.com/Who-Moved-My-Cheese-Amazing/dp/0399144463/ref=sr_1_1?s=books&amp;amp;ie=UTF8&amp;amp;qid=1343614094&amp;amp;sr=1-1&amp;amp;keywords=who+moved+my+cheese" target="_blank"&gt;cheese is definitely moving&lt;/a&gt; when it comes to client-side programming and that the smart money is on building data-oriented applications rather than control-oriented applications like the one above. That’s why we’re seeing more and more &lt;a href="http://weblogs.asp.net/dwahlin/archive/2012/07/08/javascript-data-binding-frameworks.aspx" target="_blank"&gt;data binding frameworks&lt;/a&gt; for JavaScript being released.

  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;h2&gt;What is Data-Oriented Programming?&lt;/h2&gt;

&lt;p&gt;I refer to applications that use data binding as being “data-oriented” (&lt;a href="http://weblogs.asp.net/dwahlin/archive/2009/06/20/control-oriented-vs-data-oriented-programming-in-silverlight.aspx" target="_blank"&gt;here’s a previous post&lt;/a&gt; on that very topic) since they’re focused on the actual data as opposed to writing code to access controls in a given page (“control-oriented” as mentioned earlier). I’ve built a lot of control-oriented applications over the years and found that making the transition to building data-oriented applications definitely requires a different thought process.&amp;#160; However, making the move to building data-oriented applications is well worth the effort and ultimately results in better applications in my experience. I think it’s especially important for client-centric applications built using JavaScript. &lt;/p&gt;

&lt;p&gt;Although I’m a big fan of jQuery, I’ve started realizing over the past few years that when it’s used mainly to build control-oriented applications (where jQuery is used to find controls, update values, extract values, etc.) a lot of unnecessary code is being written that could be eliminated by using a data-oriented framework. jQuery absolutely has its place in applications, but using it to build control-oriented applications isn’t a good use of its functionality in my opinion given some of the other options now available. It’s great when you require low-level DOM access but not as great when an application has a lot of CRUD operations going on. This probably sounds a bit controversial given the popularity of jQuery (and to people who know I’m definitely a huge jQuery fan), but when you understand what a data-oriented application is and why it’s important, then using a data-oriented framework makes more sense for many CRUD applications.
  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;h2&gt;The Role of Data Binding&lt;/h2&gt;

&lt;p&gt;By using a data binding library/framework you can wire JavaScript object properties to controls and have the controls and object properties update automatically (a process referred to as “two-way” binding) as changes are made on either side without having to write control-specific code. This means that you don’t have to write selectors to find controls in the DOM and update them or grab values. If you’ve ever worked with application frameworks such as Flex, Silverlight, or Windows Presentation Foundation (WPF) then you’re used to this type of functionality and I’m willing to bet that you can’t live without it. Data binding is addictive once you start using it.&lt;/p&gt;

&lt;p&gt;With application frameworks like Flex or Silverlight the data binding engine is built-in so you use whatever the framework gives you. The challenge in the JavaScript world is that there isn’t simply one “best” data binding framework to choose. Many different script libraries/frameworks are appearing on the scene with their own set of pros and cons. &lt;/p&gt;

&lt;p&gt;I’m a big fan of data binding libraries such as &lt;a href="http://knockoutjs.com/" target="_blank"&gt;KnockoutJS&lt;/a&gt; (my friend John Papa has an excellent &lt;a href="http://www.pluralsight-training.net/microsoft/Courses/TableOfContents/knockout-mvvm" target="_blank"&gt;course on KnockoutJS&lt;/a&gt; if you’re interested) but have been spending more and more time lately using a framework called &lt;a href="http://www.angularjs.org" target="_blank"&gt;AngularJS&lt;/a&gt; and plan to write a series of posts on what it is and how it can be used in client-centric applications to perform data binding, routing, Ajax functionality, validation, and much more when building data-oriented applications. In the next post I’ll provide a simple “getting started” example of using AngularJS for basic data binding (the &lt;a href="http://weblogs.asp.net/dwahlin/archive/2012/07/29/javascript-data-binding-with-angularjs-getting-started.aspx" target="_blank"&gt;post&lt;/a&gt; is live now) and then follow-up with additional posts that provide more details on what AngularJS is capable of doing. Until then, check out some of the &lt;a href="http://weblogs.asp.net/dwahlin/archive/2012/07/08/javascript-data-binding-frameworks.aspx" target="_blank"&gt;data binding frameworks&lt;/a&gt; I wrote about previously if you want to get prepared for the data-oriented application revolution that’s coming.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8790706" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/dwahlin/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/JSON/default.aspx">JSON</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/HTML5/default.aspx">HTML5</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/jQuery+Mobile/default.aspx">jQuery Mobile</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/Databinding/default.aspx">Databinding</category></item><item><title>Pluralsight Meet the Author Podcast on HTML5 Canvas Programming</title><link>http://weblogs.asp.net/dwahlin/archive/2012/07/10/pluralsight-meet-the-author-podcast-on-html5-canvas-programming.aspx</link><pubDate>Tue, 10 Jul 2012 17:27:06 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8720326</guid><dc:creator>dwahlin</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/dwahlin/rsscomments.aspx?PostID=8720326</wfw:commentRss><comments>http://weblogs.asp.net/dwahlin/archive/2012/07/10/pluralsight-meet-the-author-podcast-on-html5-canvas-programming.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://www.pluralsight-training.net/microsoft/Courses/TableOfContents/html5-canvas-fundamentals" target="_blank"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" src="http://weblogs.asp.net/blogs/dwahlin/image_72D91BF0.png" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;In the latest installment of Pluralsight’s Meet the Author podcast series, Fritz Onion and I talk about my new course, &lt;a href="http://www.pluralsight-training.net/microsoft/Courses/TableOfContents/html5-canvas-fundamentals" target="_blank"&gt;HTML5 Canvas Fundamentals&lt;/a&gt;.&amp;#160; In the interview I describe different canvas technologies covered throughout the course and a sample application at the end of the course that covers how to build a custom business chart from start to finish.&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;img style="border-right-width: 0px; margin-top: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; margin-right: 15px" title="Play Button" alt="Play Button" src="http://pluralsight.files.wordpress.com/2012/03/play-button-16.png?w=640" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="https://s3.amazonaws.com/pluralsight-free/meet-the-author/dan-wahlin-html5canvas1.mp3"&gt;Meet the Author:&amp;#160; Dan Wahlin on HTML5 Canvas Fundamentals&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Transcript&lt;/strong&gt;&lt;/p&gt;  &lt;hr /&gt;  &lt;blockquote&gt;   &lt;p&gt;[Fritz] Hi. This is Fritz Onion. I’m here today with Dan Wahlin to talk about his new course HTML5 Canvas Fundamentals. Dan founded the Wahlin Group, which you can find at &lt;a href="http://thewahlingroup.com" target="_blank"&gt;thewahlingroup.com&lt;/a&gt;, which specializes in ASP.NET, jQuery, Silverlight, and SharePoint consulting. He’s a Microsoft Regional Director and has been awarded Microsoft’s MVP for ASP.NET, Connected Systems, and Silverlight. Dan is on the INETA Bureau’s — Speaker’s Bureau, speaks at conferences and user groups around the world, and has written several books on .NET. Thanks for talking to me today, Dan.&lt;/p&gt;    &lt;p&gt;[Dan] Always good to talk with you, Fritz.&lt;/p&gt;    &lt;p&gt;[Fritz] So this new course of yours, HTML5 Canvas Fundamentals, I have to say that most of the really snazzy demos I’ve seen with HTML5 have involved Canvas, so I thought it would be a good starting point to chat with you about why we decided to create a course dedicated just to Canvas. If you want to kind of give us that perspective.&lt;/p&gt;    &lt;p&gt;[Dan] Sure. So, you know, there’s quite a bit of material out there on HTML5 in general, and as people that have done a lot with HTML5 are probably aware, a lot of HTML5 is actually JavaScript centric. You know, a lot of people when they first learn it, think it’s tags, but most of it’s actually JavaScript, and it just so happens that the HTML5 Canvas is one of those things. And so it’s not just, you know, a tag you add and it just magically draws all these things. You mentioned there’s a lot of cool things you can do from games to there’s some really cool multimedia applications out there where they integrate video and audio and all kinds of things into the Canvas, to more business scenarios such as charting and things along those lines. So the reason we made a course specifically on it is, a lot of the material out there touches on it but the Canvas is actually a pretty deep topic. You can do some pretty advanced stuff or easy stuff depending on what your application requirements are, and the API itself, you know, there’s over 30 functions just in the Canvas API and then a whole set of properties that actually go with that as well. So it’s a pretty big topic, and that’s why we created a course specifically tailored towards just the Canvas.&lt;/p&gt;    &lt;p&gt;[Fritz] Right. And let’s — let me just review the outline briefly here for everyone. So you start off with an introduction to getting started with Canvas, drawing with the HTML5 Canvas, then you talk about manipulating pixels, and you finish up with building a custom data chart. So I really like your example flow here. I think it will appeal to even business developers, right. Even if you’re not into HTML5 for the games or the media capabilities, there’s still something here for everyone I think working with the Canvas. Which leads me to another question, which is, where do you see the Canvas fitting in to kind of your day-to-day developer, people that are working business applications and maybe vanilla websites that aren’t doing kind of cutting edge stuff with interactivity with users? Is there a still a place for the Canvas in those scenarios?&lt;/p&gt;    &lt;p&gt;[Dan] Yeah, definitely. I think a lot of us — and I include myself here — over the last few years, the focus has generally been, especially if you’re, let’s say, a PHP or ASP.NET or Java type of developer, we’re kind of accustomed to working on the server side, and, you know, we kind of relied on Flash or Silverlight or these other plug-ins for the client side stuff when it was kind of fancy, like charts and graphs and things along those lines. With the what I call massive shift of applications, you know, mainly because of mobile, to more of client side, one of the big benefits I think from a maybe corporate standard way of thinking of things, since we do a lot of work with different corporations, is that, number one, rather than having to have the plug-in, which of course isn’t going to work on iPad and some of these other devices out there that are pretty popular, you can now use a built-in technology that all the modern browsers support, and that includes things like Safari on the iPad and iPhone and the Android tablets and things like that with their browsers, and actually render some really sophisticated charts. Whether you do it by scratch or from scratch or, you know, get a third party type of library involved, it’s just JavaScript. So it downloads fast so it’s good from a performance perspective; and when it comes to what you can render, it’s extremely robust. You can do everything from, you know, your basic circles to polygons or polylines to really advanced gradients as well and even provide some interactivity and animations, and that’s some of the stuff I touch upon in the class. In fact, you mentioned the last part of the outline there is building a custom data chart and that’s kind of gears towards more of the, what I’d call enterprise or corporate type developer.&lt;/p&gt;    &lt;p&gt;[Fritz] Yeah, that makes sense. And it’s, you know, a lot of the demos I’ve seen with HTML5 focus on more the interactivity and kind of game side of things, but the Canvas is such a diverse element within HTML5 that I can see it being applicable pretty much anywhere. So why don’t we talk a little bit about some of the specifics of what you cover? You talk about drawing and then manipulating pixels. You want to kind of give us the different ways of working with the Canvas and what some of those APIs provide for you?&lt;/p&gt;    &lt;p&gt;[Dan] Sure. So going all the way back to the start of the outline, we actually started off by showing different demonstrations of the Canvas in action, and we show some fun stuff — multimedia apps and games and things like that — and then also some more business scenarios; and then once you see that, hopefully it kinds of piques your interest and you go, oh, wow, this is actually pretty phenomenal what you can do. So then we start you off with, so how to you actually draw things. Now, there are some libraries out there that will draw things like graphs, but if you want to customize those or just build something you have from scratch, you need to know the basics, such as, you know, how do you draw circles and lines and arcs and Bezier curves and all those fancy types of shapes that a given chart may have on it or that a game may have in it for that matter. So we start off by covering what I call the core API functions; how do you, for instance, fill a rectangle or convert that to a square by setting the height and the width; how do you draw arcs or different types of curves and there’s different types supported such as I mentioned Bezier curves or quadratic curves; and then we also talk about how do you integrate text into it. You might have some images already that are just regular bitmap type images that you want to integrate, you can do that with a Canvas. And you can even sync video into the Canvas, which actually opens up some pretty interesting possibilities for both business and I think just general multimedia apps. Once you kind of get those core functions down for the basic shapes that you need to be able to draw on any type of Canvas, then we go a little deeper into what are the pixels that are there to manipulate. And that’s one of the important things to understand about the HTML5 Canvas, scalable vector graphics is another thing you can use now in the modern browsers; it’s vector based. Canvas is pixel based. And so we talk about how to do gradients, how can you do transforms, you know, how do you scale things or rotate things, which is extremely useful for charts ’cause you might have text that, you know, flips up on its side for a y-axis or something like that. And you can even do direct pixel manipulation. So it’s really, really powerful. If you want to get down to the RGBA level, you can do that, and I show how to do that in the course, and then kind of wrap that section up with some animation fundamentals.&lt;/p&gt;    &lt;p&gt;[Fritz] Great. Yeah, that’s really powerful stuff for programmatically rendering data to clients and responding to user inputs. Look forward to seeing what everyone’s going to come up with building this stuff. So great. That’s — that’s HTML5 Canvas Fundamentals with Dan Wahlin. Thanks very much, Dan.&lt;/p&gt;    &lt;p&gt;[Dan] Thanks again. I appreciate it.&lt;/p&gt;&lt;/blockquote&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8720326" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/dwahlin/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/HTML5/default.aspx">HTML5</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/Canvas/default.aspx">Canvas</category></item><item><title>JavaScript Data Binding Frameworks</title><link>http://weblogs.asp.net/dwahlin/archive/2012/07/08/javascript-data-binding-frameworks.aspx</link><pubDate>Sun, 08 Jul 2012 23:17:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8711584</guid><dc:creator>dwahlin</dc:creator><slash:comments>14</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/dwahlin/rsscomments.aspx?PostID=8711584</wfw:commentRss><comments>http://weblogs.asp.net/dwahlin/archive/2012/07/08/javascript-data-binding-frameworks.aspx#comments</comments><description>&lt;p&gt;Data binding is where it’s at now days when it comes to building client-centric Web applications. Developers experienced with desktop frameworks like WPF or web frameworks like ASP.NET, Silverlight, or others are used to being able to take model objects containing data and bind them to UI controls quickly and easily. When moving to client-side Web development the data binding story hasn’t been great since neither HTML nor JavaScript natively support data binding. This means that you have to write code to place data in a control and write code to extract it. Although it’s certainly feasible to do it from scratch (many of us have done it this way for years), it’s definitely tedious and not exactly the best solution when it comes to maintenance and re-use.&lt;/p&gt;  &lt;p&gt;Over the last few years several different script libraries have been released to simply the process of binding data to HTML controls. In fact, the subject of data binding is becoming so popular that it seems like a new script library is being released nearly every week. Many of the libraries provide MVC/MVVM pattern support in client-side JavaScript apps and some even integrate directly with server frameworks like Node.js. Here’s a quick list of a few of the available libraries that support data binding (if you like any others please add a comment and I’ll try to keep the list updated):    &lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;table border="0" cellspacing="5" cellpadding="2" width="795"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="273"&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_7C28A485.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_0D4C5C5C.png" width="244" height="69" /&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="505"&gt;         &lt;br /&gt;&lt;a href="http://angularjs.org" target="_blank"&gt;&lt;font size="4"&gt;&lt;strong&gt;AngularJS&lt;/strong&gt;&lt;/font&gt;&lt;/a&gt;&lt;font size="4"&gt;&lt;strong&gt; &lt;/strong&gt;            &lt;br /&gt;&lt;/font&gt;          &lt;br /&gt;MVC framework for data binding (although closely follows the MVVM pattern).           &lt;br /&gt;          &lt;br /&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="278"&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_15144EFE.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_4EB2D4E9.png" width="244" height="63" /&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="500"&gt;         &lt;br /&gt;&lt;a href="http://backbonejs.org/" target="_blank"&gt;&lt;font size="4"&gt;&lt;strong&gt;Backbone.js&lt;/strong&gt;&lt;/font&gt;&lt;/a&gt;&lt;font size="4"&gt;&lt;strong&gt;              &lt;br /&gt;&lt;/strong&gt;&lt;/font&gt;          &lt;br /&gt;MVC framework with support for models, key/value binding, custom events, and more.           &lt;br /&gt;          &lt;br /&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="283"&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_3C819DDE.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_0E281831.png" width="245" height="63" /&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="496"&gt;         &lt;br /&gt;&lt;a href="http://derbyjs.com/" target="_blank"&gt;&lt;font size="4"&gt;&lt;strong&gt;Derby&lt;/strong&gt;&lt;/font&gt;&lt;/a&gt;           &lt;br /&gt;          &lt;br /&gt;Provides a real-time environment that runs in the browser an in Node.js. The library supports data binding and templates.           &lt;br /&gt;          &lt;br /&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="287"&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_4DA65B70.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_5F16BC48.png" width="246" height="64" /&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="492"&gt;         &lt;br /&gt;&lt;a href="http://emberjs.com/" target="_blank"&gt;&lt;strong&gt;&lt;font size="4"&gt;Ember&lt;/font&gt;&lt;/strong&gt;&lt;/a&gt;           &lt;br /&gt;          &lt;br /&gt;Provides support for templates that automatically update as data changes.           &lt;br /&gt;          &lt;br /&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="291"&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_04681A44.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_009A4FA7.png" width="245" height="71" /&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="489"&gt;&lt;strong&gt;&lt;font size="4"&gt;             &lt;br /&gt;&lt;a href="https://github.com/BorisMoore/jsviews" target="_blank"&gt;JsViews&lt;/a&gt;&lt;/font&gt;&lt;/strong&gt;           &lt;br /&gt;          &lt;br /&gt;Data binding framework that provides “interactive data-driven views built on top of JsRender templates”.           &lt;br /&gt;          &lt;br /&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="294"&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_3FB385C6.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_1F2C4614.png" width="244" height="70" /&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="486"&gt;         &lt;br /&gt;&lt;a href="http://jqxb.codeplex.com/" target="_blank"&gt;&lt;font size="4"&gt;&lt;strong&gt;jQXB Expression Binder&lt;/strong&gt;&lt;/font&gt;&lt;/a&gt;           &lt;br /&gt;          &lt;br /&gt;Lightweight jQuery plugin that supports bi-directional data binding support.           &lt;br /&gt;          &lt;br /&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="297"&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_232E6855.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_4C095791.png" width="244" height="66" /&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="484"&gt;         &lt;br /&gt;&lt;a href="http://knockoutjs.com/" target="_blank"&gt;&lt;font size="4"&gt;&lt;strong&gt;KnockoutJS&lt;/strong&gt;&lt;/font&gt;&lt;/a&gt;           &lt;br /&gt;          &lt;br /&gt;MVVM framework with robust support for data binding. For an excellent look at using KnockoutJS check out &lt;a href="http://johnpapa.net/" target="_blank"&gt;John Papa’s&lt;/a&gt; course on &lt;a href="http://www.pluralsight-training.net/microsoft/Courses/TableOfContents/knockout-mvvm" target="_blank"&gt;Pluralsight&lt;/a&gt;.           &lt;br /&gt;          &lt;br /&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="299"&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_5A7FABD2.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_730F4922.png" width="244" height="61" /&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="482"&gt;         &lt;br /&gt;&lt;a href="http://meteor.com/main" target="_blank"&gt;&lt;strong&gt;&lt;font size="4"&gt;Meteor&lt;/font&gt;&lt;/strong&gt;&lt;/a&gt;           &lt;br /&gt;          &lt;br /&gt;End to end framework that uses Node.js on the server and provides support for data binding on&amp;#160; the client.           &lt;br /&gt;          &lt;br /&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="301"&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_6B83D9B5.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_11E5BD01.png" width="246" height="59" /&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="481"&gt;         &lt;br /&gt;&lt;a href="http://jacwright.com/438/javascript-data-binding/" target="_blank"&gt;&lt;strong&gt;&lt;font size="4"&gt;Simpli5&lt;/font&gt;&lt;/strong&gt;&lt;/a&gt;           &lt;br /&gt;          &lt;br /&gt;JavaScript framework that provides support for two-way data binding.           &lt;br /&gt;          &lt;br /&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="302"&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_5C6CFADB.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_7BAFA1AE.png" width="244" height="60" /&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="480"&gt;         &lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh700356.aspx" target="_blank"&gt;&lt;strong&gt;&lt;font size="4"&gt;WinRT with HTML5/JavaScript&lt;/font&gt;&lt;/strong&gt;&lt;/a&gt;           &lt;br /&gt;          &lt;br /&gt;If you’re building Windows 8 applications using HTML5 and JavaScript there’s built-in support for data binding in the WinJS library.           &lt;br /&gt;          &lt;br /&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;I won’t have time to write about each of these frameworks, but in the next post I’m going to talk about my (current) favorite when it comes to client-side JavaScript data binding libraries which is &lt;a href="http://angularjs.org" target="_blank"&gt;AngularJS&lt;/a&gt;. AngularJS provides an extremely clean way – in my opinion - to extend HTML syntax to support data binding while keeping model objects (the objects that hold the data) free from custom framework method calls or other weirdness. While I’m writing up the next post, feel free to visit the &lt;a href="http://docs.angularjs.org/guide/" target="_blank"&gt;AngularJS developer guide&lt;/a&gt; if you’d like additional details about the API and want to get started using it. &lt;/p&gt;  &lt;p&gt;Now that you’ve seen several client-side data binding libraries, let’s talk through whether or not it’s worth it to move shift an application’s focus from the server to the client and some of the issues that may come up.   &lt;br /&gt;&lt;/p&gt;  &lt;h2&gt;Client-Centric or Server-Centric – That is the Question&lt;/h2&gt;  &lt;p&gt;Over the past 10 years Microsoft, Sun/Oracle, IBM, and others have been pushing developers to write server-side code that outputs HTML to the browser. As a result, making the leap to client-centric programming can be challenging if you’ve never done it before. Given the disparity across browsers in the past, generating HTML on the server made sense (and still works fine in today’s applications of course) but today’s modern browsers and even browsers going back to IE6 are much more capable of rendering HTML on their own and performing additional functionality. Enhanced browser features, faster JavaScript engines, and more and more mobile devices like the iPad have definitely shifted the trend from server-side development to client-side development. &lt;/p&gt;  &lt;p&gt;One of the questions I hear a lot is whether or not server-side templates and code should still be used for data binding or if it’s worth it to move a lot of code down to the client and support data binding there. The answer isn’t simply “use the server” or “use the client” of course since a lot of factors have to be taken into account. I don’t believe in the “one size fits all” approach since applications all have their own unique characteristics. First off, do you (or the team you’re working on) already have a lot invested in server-side technologies? If so then it may be worthwhile to continue doing what you’re doing and sprinkle in some Ajax where appropriate to minimize postback operations. There’s no hard and fast rule that says you have to convert everything to client-side code. If you’re using ASP.NET Web Forms or ASP.NET MVC it’s pretty straightforward to add Ajax functionality without having to write much (if any) JavaScript code. Going that route won’t be as efficient as doing it with pure JavaScript (or using a library like jQuery) but it gets the job done and you can always start learning the new client-centric techniques along the way.&lt;/p&gt;  &lt;p&gt;As far as templates and data binding, ASP.NET Web Forms controls like ListView, Repeater, GridView, and others definitely make it easy to bind data to a template that automatically generates HTML for the browser. If you use ASP.NET Web Forms a lot you’re probably familiar with this, but here’s a quick example of a ListView control template that data could be bound to:   &lt;br /&gt;&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: maroon"&gt;ListView &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;ID&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;CustomersListView&amp;quot;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;LayoutTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;table &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;tr &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;itemPlaceholder&amp;quot; &amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;table&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;LayoutTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ItemTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                 &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: maroon"&gt;Label &lt;/span&gt;&lt;span style="color: red"&gt;ID&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;CustomerNameLabel&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot; 
                    &lt;/span&gt;&lt;span style="color: red"&gt;Text&lt;/span&gt;&lt;span style="color: blue"&gt;='&lt;/span&gt;&lt;span style="background: yellow"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;#&lt;/span&gt;Eval(&amp;quot;CustomerName&amp;quot;) &lt;span style="background: yellow"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;' /&amp;gt;
            &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ItemTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: maroon"&gt;ListView&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;ASP.NET MVC has data templates, editor extensions, model binders, and other great features that also simplify the process while generating very clean markup on the server. An example of using the EditorFor() method to auto-generate HTML for a Customer type in an ASP.NET MVC view is shown next. If a custom editor template for Customer is defined the template will automatically handle binding properties of the Customer type to different UI controls.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre class="code"&gt;@Html.EditorFor(model =&amp;gt; model.Customer)&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;Server-side programming definitely isn’t the only game in town any more. Custom templates combined with data binding can be used quite successfully on the client-side leading to a more interactive, engaging, and productive application from the client perspective if done right. Whether you write custom code or use a JavaScript library, you can integrate some pretty impressive functionality directly into the client. Going this route definitely requires a solid knowledge of JavaScript but if you already know a language then JavaScript is quite easy to pick up. With the available libraries out there you don’t even have to write a lot of JavaScript code in some cases. As an example, here’s a simple code sample that uses a framework called AngularJS to perform bi-directional client-side data binding:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: maroon"&gt;doctype &lt;/span&gt;&lt;span style="color: red"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;html &lt;/span&gt;&lt;span style="color: red"&gt;ng-app&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;http://code.angularjs.org/angular-1.0.1.min.js&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;ng-model&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;age&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;placeholder&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Enter your age...&amp;quot;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;br &lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;h1&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;You are {{age}} years old!&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;h1&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;
  &lt;br /&gt;As the user types into the textbox the “model” property named “age” will be updated. It’s bound into the h1 element using the {{ age }} syntax. Anytime &lt;em&gt;age&lt;/em&gt; changes the text inside the h1 element will change as well. Not bad for zero lines of custom JavaScript. For more real-world applications you can go much deeper and perform some impressive data binding operations whether you use AngularJS or one of the other available frameworks.&lt;/p&gt;

&lt;p&gt;For me personally, the server versus client discussion all comes down to data exchange.&amp;#160; Do you want the server to send pre-formatted HTML down to the client or do you want it to send raw data that is dynamically formatted on the client? If you’re looking for increases in speed, better performance on mobile devices, and more, then sending raw JavaScript Object Notation (JSON) data can be a win for dynamic applications especially given that the payload sent over the wire will likely be much smaller.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Making the Leap to Client Side Development&lt;/h2&gt;

&lt;p&gt;
  &lt;br /&gt;Up to this point I’ve focused on client-side and server-side developer skills but they certainly aren’t the only factor to consider. Who will be using the application and how dynamic does it need to be? Will the application be used on mobile devices in addition to standard desktop browsers? If you want to minimize postbacks, move a lot of the application’s functionality down to the client, and provide an overall better experience for the client then learning JavaScript and one or more JavaScript frameworks may be worthwhile. Moving functionality down to the client isn’t a decision that should be taken lightly though especially for teams that don’t have much experience there. Here are a few things to consider:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;How well does your team know JavaScript?&lt;/li&gt;

  &lt;li&gt;Do you know different JavaScript Patterns that can be used to &lt;a href="http://www.pluralsight-training.net/microsoft/Courses/TableOfContents/structuring-javascript" target="_blank"&gt;structure code&lt;/a&gt; and make it re-useable and maintainable?&lt;/li&gt;

  &lt;li&gt;How are you going to divide up your JavaScript files to promote re-use, avoid naming collisions, and support future maintenance?&lt;/li&gt;

  &lt;li&gt;How are you going to load your JavaScript files – an important point to consider if you’ll be working with a lot of .js files since they load synchronously by default in browsers.&lt;/li&gt;

  &lt;li&gt;Do you know how to &lt;a href="http://blogs.interfacett.com/getting-data-asp-net-applications-using-ajax-jquery-using-custom-httphandler" target="_blank"&gt;expose JSON data&lt;/a&gt; through RESTful endpoints on the server so that it can be consumed by JavaScript clients? &lt;/li&gt;

  &lt;li&gt;How much of your code do you want available for prying eyes to see on the client? Although there are ways to obfuscate JavaScript code, it’s quite easy to get to it using browser developer tools.&lt;/li&gt;

  &lt;li&gt;How will dynamically generating HTML code in the browser affect search engine optimizations?&lt;/li&gt;

  &lt;li&gt;Have you thought through any security implications of moving a lot of application functionality to the client?&lt;/li&gt;

  &lt;li&gt;Does the application need to run offline?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you answered “no” or were unsure about several of the above questions then it’s time to invest in educating yourself about client-side development practices. As more and more applications move this direction you’ll see more and more customers demanding this type of rich client functionality. I’ll talking about that very subject in upcoming posts.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8711584" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/dwahlin/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/JSON/default.aspx">JSON</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/HTML5/default.aspx">HTML5</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/Databinding/default.aspx">Databinding</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/Node.js/default.aspx">Node.js</category></item><item><title>Mobile Friendly Websites with CSS Media Queries</title><link>http://weblogs.asp.net/dwahlin/archive/2012/06/25/mobile-friendly-websites-with-css-media-queries.aspx</link><pubDate>Mon, 25 Jun 2012 07:06:18 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8646556</guid><dc:creator>dwahlin</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/dwahlin/rsscomments.aspx?PostID=8646556</wfw:commentRss><comments>http://weblogs.asp.net/dwahlin/archive/2012/06/25/mobile-friendly-websites-with-css-media-queries.aspx#comments</comments><description>&lt;p&gt;In a &lt;a href="http://weblogs.asp.net/dwahlin/archive/2012/05/22/getting-started-with-css-media-queries.aspx" target="_blank"&gt;previous post&lt;/a&gt; the concept of CSS media queries was introduced and I discussed the fundamentals of how they can be used to target different screen sizes. I showed how they could be used to convert a 3-column wide page into a more vertical view of data that displays better on devices such as an iPhone: &lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_503DEE89.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_636E7F5B.png" width="607" height="617" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;In this post I'll provide an additional look at how CSS media queries can be used to mobile-enable a sample site called &amp;quot;Widget Masters&amp;quot; without having to change any server-side code or HTML code. The site that will be discussed is shown next:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_3DD4DC2D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_6B8E6B26.png" width="694" height="529" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;This site has some of the standard items shown in most websites today including a title area, menu bar, and sections where data is displayed. Without including CSS media queries the site is readable but has to be zoomed out to see everything on a mobile device, cuts-off some of the menu items, and requires horizontal scrolling to get to additional content. The following image shows what the site looks like on an iPhone. While the site works on mobile devices it's definitely not optimized for mobile.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_65937BF3.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_3992B69D.png" width="277" height="527" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Let's take a look at how CSS media queries can be used to override existing styles in the site based on different screen widths.    &lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;h2&gt;Adding CSS Media Queries into a Site&lt;/h2&gt;  &lt;p&gt;The Widget Masters Website relies on standard CSS combined with HTML5 elements to provide the layout shown earlier. For example, to layout the menu bar shown at the top of the page the nav element is used as shown next. A standard div element could certainly be used as well if desired.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;nav&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;clearfix&amp;quot;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;a &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;#home&amp;quot;&amp;gt;&lt;/span&gt;Home&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;a&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;a &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;#products&amp;quot;&amp;gt;&lt;/span&gt;Products&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;a&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;a &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;#aboutus&amp;quot;&amp;gt;&lt;/span&gt;About Us&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;a&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;a &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;#contactus&amp;quot;&amp;gt;&lt;/span&gt;Contact Us&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;a&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;a &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;#store&amp;quot;&amp;gt;&lt;/span&gt;Store&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;a&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;nav&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;This HTML is combined with the CSS shown next to add a CSS3 gradient, handle the horizontal orientation, and add some general hover effects.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: maroon"&gt;nav
&lt;/span&gt;{
    &lt;span style="color: red"&gt;width&lt;/span&gt;: &lt;span style="color: blue"&gt;100%&lt;/span&gt;;
}
        
&lt;span style="color: maroon"&gt;nav ul
&lt;/span&gt;{
    &lt;span style="color: red"&gt;border-radius&lt;/span&gt;: &lt;span style="color: blue"&gt;6px&lt;/span&gt;;
    &lt;span style="color: red"&gt;height&lt;/span&gt;: &lt;span style="color: blue"&gt;40px&lt;/span&gt;;
    &lt;span style="color: red"&gt;width&lt;/span&gt;: &lt;span style="color: blue"&gt;100%&lt;/span&gt;;
    &lt;span style="color: red"&gt;margin&lt;/span&gt;: &lt;span style="color: blue"&gt;0&lt;/span&gt;;
    &lt;span style="color: red"&gt;padding&lt;/span&gt;: &lt;span style="color: blue"&gt;0&lt;/span&gt;;
    &lt;span style="color: red"&gt;background&lt;/span&gt;: &lt;span style="color: blue"&gt;rgb(125,126,125)&lt;/span&gt;; &lt;span style="color: #006400"&gt;/* Old browsers */
    &lt;/span&gt;&lt;span style="color: red"&gt;background&lt;/span&gt;: &lt;span style="color: blue"&gt;-moz-linear-gradient(top, rgba(125,126,125,1) 0%, 
                rgba(14,14,14,1) 100%)&lt;/span&gt;; &lt;span style="color: #006400"&gt;/* FF3.6+ */
    &lt;/span&gt;&lt;span style="color: red"&gt;background&lt;/span&gt;: &lt;span style="color: blue"&gt;-webkit-gradient(linear, left top, left bottom, 
                color-stop(0%,rgba(125,126,125,1)), 
                color-stop(100%,rgba(14,14,14,1)))&lt;/span&gt;; &lt;span style="color: #006400"&gt;/* Chrome,Safari4+ */
    &lt;/span&gt;&lt;span style="color: red"&gt;background&lt;/span&gt;: &lt;span style="color: blue"&gt;-webkit-linear-gradient(top, rgba(125,126,125,1) 0%, 
                rgba(14,14,14,1) 100%)&lt;/span&gt;; &lt;span style="color: #006400"&gt;/* Chrome10+,Safari5.1+ */
    &lt;/span&gt;&lt;span style="color: red"&gt;background&lt;/span&gt;: &lt;span style="color: blue"&gt;-o-linear-gradient(top, rgba(125,126,125,1) 0%, 
                rgba(14,14,14,1) 100%)&lt;/span&gt;; &lt;span style="color: #006400"&gt;/* Opera 11.10+ */
    &lt;/span&gt;&lt;span style="color: red"&gt;background&lt;/span&gt;: &lt;span style="color: blue"&gt;-ms-linear-gradient(top, rgba(125,126,125,1) 0%, 
                rgba(14,14,14,1) 100%)&lt;/span&gt;; &lt;span style="color: #006400"&gt;/* IE10+ */
    &lt;/span&gt;&lt;span style="color: red"&gt;background&lt;/span&gt;: &lt;span style="color: blue"&gt;linear-gradient(top, rgba(125,126,125,1) 0%, 
                rgba(14,14,14,1) 100%)&lt;/span&gt;; &lt;span style="color: #006400"&gt;/* W3C */
    &lt;/span&gt;&lt;span style="color: red"&gt;filter&lt;/span&gt;: &lt;span style="color: blue"&gt;progid:DXImageTransform.Microsoft.gradient( 
            startColorstr='#7d7e7d', 
            endColorstr='#0e0e0e',GradientType=0 )&lt;/span&gt;; &lt;span style="color: #006400"&gt;/* IE6-9 */
&lt;/span&gt;}
        
&lt;span style="color: maroon"&gt;nav ul &amp;gt; li
&lt;/span&gt;{
    &lt;span style="color: red"&gt;list-style&lt;/span&gt;: &lt;span style="color: blue"&gt;none&lt;/span&gt;;
    &lt;span style="color: red"&gt;float&lt;/span&gt;: &lt;span style="color: blue"&gt;left&lt;/span&gt;;
    &lt;span style="color: red"&gt;margin&lt;/span&gt;: &lt;span style="color: blue"&gt;0&lt;/span&gt;;
    &lt;span style="color: red"&gt;padding&lt;/span&gt;: &lt;span style="color: blue"&gt;0&lt;/span&gt;;
}
        
&lt;span style="color: maroon"&gt;nav ul &amp;gt; li:first-child
&lt;/span&gt;{
    &lt;span style="color: red"&gt;margin-left&lt;/span&gt;: &lt;span style="color: blue"&gt;8px&lt;/span&gt;;
}
        
&lt;span style="color: maroon"&gt;nav ul &amp;gt; li &amp;gt; a
&lt;/span&gt;{
    &lt;span style="color: red"&gt;color&lt;/span&gt;: &lt;span style="color: blue"&gt;#ccc&lt;/span&gt;;
    &lt;span style="color: red"&gt;text-decoration&lt;/span&gt;: &lt;span style="color: blue"&gt;none&lt;/span&gt;;
    &lt;span style="color: red"&gt;line-height&lt;/span&gt;: &lt;span style="color: blue"&gt;2.8em&lt;/span&gt;;
    &lt;span style="color: red"&gt;font-size&lt;/span&gt;: &lt;span style="color: blue"&gt;0.95em&lt;/span&gt;;
    &lt;span style="color: red"&gt;font-weight&lt;/span&gt;: &lt;span style="color: blue"&gt;bold&lt;/span&gt;;
    &lt;span style="color: red"&gt;padding&lt;/span&gt;: &lt;span style="color: blue"&gt;8px 25px 7px 25px&lt;/span&gt;;
    &lt;span style="color: red"&gt;font-family&lt;/span&gt;: &lt;span style="color: blue"&gt;Arial, Helvetica, sans-serif&lt;/span&gt;;
}
        
&lt;span style="color: maroon"&gt;nav ul &amp;gt; li a:hover
&lt;/span&gt;{
    &lt;span style="color: red"&gt;background-color&lt;/span&gt;: &lt;span style="color: blue"&gt;rgba(0, 0, 0, 0.1)&lt;/span&gt;;
    &lt;span style="color: red"&gt;color&lt;/span&gt;: &lt;span style="color: blue"&gt;#fff&lt;/span&gt;;
}&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;When mobile devices hit the site the layout of the menu items needs to be adjusted so that they're all visible without having to swipe left or right to get to them. This type of modification can be accomplished using CSS media queries by targeting specific screen sizes. To start, a media query can be added into the site's CSS file as shown next: 
  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;@media &lt;/span&gt;screen and (max-width:320px) {

    &lt;span style="color: #006400"&gt;/* CSS style overrides for this screen width go here */

&lt;/span&gt;}&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;
  &lt;br /&gt;This media query targets screens that have a maximum width of 320 pixels. Additional types of queries can also be added – refer to my &lt;a href="http://weblogs.asp.net/dwahlin/archive/2012/05/22/getting-started-with-css-media-queries.aspx" target="_blank"&gt;previous post&lt;/a&gt; for more details as well as resources that can be used to test media queries in different devices. In that post I emphasize (and I'll emphasize again) that CSS media queries only modify the overall layout and look and feel of a site. They don't optimize the site as far as the size of the images or content sent to the device which is important to keep in mind.&lt;/p&gt;

&lt;p&gt;To make the navigation menu more accessible on devices such as an iPhone or Android the CSS shown next can be used. This code changes the height of the menu from 40 pixels to 100%, takes off the li element floats, changes the line-height, and changes the margins. &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;@media &lt;/span&gt;screen and (max-width:320px)
{
        
    &lt;span style="color: maroon"&gt;nav ul
    &lt;/span&gt;{
        &lt;span style="color: red"&gt;height&lt;/span&gt;: &lt;span style="color: blue"&gt;100%&lt;/span&gt;;
    }
        
    &lt;span style="color: maroon"&gt;nav ul &amp;gt; li
    &lt;/span&gt;{
        &lt;span style="color: red"&gt;float&lt;/span&gt;: &lt;span style="color: blue"&gt;none&lt;/span&gt;;
    }
        
    &lt;span style="color: maroon"&gt;nav ul &amp;gt; li a
    &lt;/span&gt;{
        &lt;span style="color: red"&gt;line-height&lt;/span&gt;: &lt;span style="color: blue"&gt;1.5em&lt;/span&gt;;
    }
        
    &lt;span style="color: maroon"&gt;nav ul &amp;gt; li:first-child
    &lt;/span&gt;{
        &lt;span style="color: red"&gt;margin-left&lt;/span&gt;: &lt;span style="color: blue"&gt;0px&lt;/span&gt;;
    }
        
    &lt;span style="color: #006400"&gt;/* Additional CSS overrides go here */
        
&lt;/span&gt;}&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;The following image shows an example of what the menu look like when run on a device with a width of 320 pixels: 
  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_42BECC11.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_4F0CA3A0.png" width="263" height="501" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Mobile devices with a maximum width of 480 pixels need different CSS styles applied since they have 160 additional pixels of width. This can be done by adding a new CSS media query into the stylesheet as shown next. Looking through the CSS you'll see that only a minimal override is added to adjust the padding of anchor tags since the menu fits by default in this screen width.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;@media &lt;/span&gt;screen and (max-width: 480px)
{
        
    &lt;span style="color: maroon"&gt;nav ul &amp;gt; li &amp;gt; a
    &lt;/span&gt;{
        &lt;span style="color: red"&gt;padding&lt;/span&gt;: &lt;span style="color: blue"&gt;8px 10px 7px 10px&lt;/span&gt;;
    }
        
}&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Running the site on a device with 480 pixels results in the menu shown next being rendered. Notice that the space between the menu items is much smaller compared to what was shown when the main site loads in a standard browser.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_498E0D2F.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_36A963B8.png" width="558" height="330" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;In addition to modifying the menu, the 3 horizontal content sections shown earlier can be changed from a horizontal layout to a vertical layout so that they look good on a variety of smaller mobile devices and are easier to navigate by end users. The HTML5 article and section elements are used as containers for the 3 sections in the site as shown next: 
  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;article &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;clearfix&amp;quot;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;section &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;info&amp;quot;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;header&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Why Choose Us?&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;header&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;br &lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;img &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;mainImage&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Images/ArticleImage.png&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Article Image&amp;quot; /&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;p&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &lt;/span&gt;Post emensos insuperabilis expeditionis eventus languentibus partium animis, quas
            periculorum varietas fregerat et laborum, nondum tubarum cessante clangore vel milite
            locato per stationes hibernas.
        &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;p&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;section&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;section &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;products&amp;quot;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;header&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Products&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;header&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;br &lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;img &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;gearsImage&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Images/Gears.png&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Article Image&amp;quot; /&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;p&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Widget 1&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Widget 2&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Widget 3&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Widget 4&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Widget 5&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;p&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;section&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;section &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;FAQ&amp;quot;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;header&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;FAQ&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;header&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;br &lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;img &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;faqImage&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Images/faq.png&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Article Image&amp;quot; /&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;p&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;FAQ 1&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;FAQ 2&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;FAQ 3&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;FAQ 4&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;FAQ 5&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;p&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;section&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;article&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;To force the sections into a vertical layout for smaller mobile devices the CSS styles shown next can be added into the media queries targeting 320 pixel and 480 pixel widths. Styles to target the display size of the images in each section are also included. It's important to note that the original image is still being downloaded from the server and isn't being optimized in any way for the mobile device. It's certainly possible for the CSS to include URL information for a mobile-optimized image if desired. 
  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;@media &lt;/span&gt;screen and (max-width:320px)
{
        
    &lt;span style="color: maroon"&gt;section
    &lt;/span&gt;{
        &lt;span style="color: red"&gt;float&lt;/span&gt;: &lt;span style="color: blue"&gt;none&lt;/span&gt;;
        &lt;span style="color: red"&gt;width&lt;/span&gt;: &lt;span style="color: blue"&gt;97%&lt;/span&gt;;
        &lt;span style="color: red"&gt;margin&lt;/span&gt;: &lt;span style="color: blue"&gt;0px&lt;/span&gt;;
        &lt;span style="color: red"&gt;padding&lt;/span&gt;: &lt;span style="color: blue"&gt;5px&lt;/span&gt;;
    }
        
    &lt;span style="color: maroon"&gt;#wrapper
    &lt;/span&gt;{
        &lt;span style="color: red"&gt;padding&lt;/span&gt;: &lt;span style="color: blue"&gt;5px&lt;/span&gt;;
        &lt;span style="color: red"&gt;width&lt;/span&gt;: &lt;span style="color: blue"&gt;96%&lt;/span&gt;;
    }
        
    &lt;span style="color: maroon"&gt;#mainImage&lt;/span&gt;, &lt;span style="color: maroon"&gt;#gearsImage&lt;/span&gt;, &lt;span style="color: maroon"&gt;#faqImage
    &lt;/span&gt;{
        &lt;span style="color: red"&gt;width&lt;/span&gt;: &lt;span style="color: blue"&gt;100%&lt;/span&gt;;
        &lt;span style="color: red"&gt;height&lt;/span&gt;: &lt;span style="color: blue"&gt;100px&lt;/span&gt;;
    }
        
}
        
&lt;span style="color: blue"&gt;@media &lt;/span&gt;screen and (max-width: 480px)
{
        
    &lt;span style="color: maroon"&gt;section
    &lt;/span&gt;{
        &lt;span style="color: red"&gt;float&lt;/span&gt;: &lt;span style="color: blue"&gt;none&lt;/span&gt;;
        &lt;span style="color: red"&gt;width&lt;/span&gt;: &lt;span style="color: blue"&gt;98%&lt;/span&gt;;
        &lt;span style="color: red"&gt;margin&lt;/span&gt;: &lt;span style="color: blue"&gt;0px 0px 10px 0px&lt;/span&gt;;
        &lt;span style="color: red"&gt;padding&lt;/span&gt;: &lt;span style="color: blue"&gt;5px&lt;/span&gt;;
    }
        
    &lt;span style="color: maroon"&gt;article &amp;gt; section:last-child
    &lt;/span&gt;{
        &lt;span style="color: red"&gt;margin-right&lt;/span&gt;: &lt;span style="color: blue"&gt;0px&lt;/span&gt;;
        &lt;span style="color: red"&gt;float&lt;/span&gt;: &lt;span style="color: blue"&gt;none&lt;/span&gt;;
    }
        
    &lt;span style="color: maroon"&gt;#bottomSection
    &lt;/span&gt;{
        &lt;span style="color: red"&gt;width&lt;/span&gt;: &lt;span style="color: blue"&gt;99%&lt;/span&gt;;
    }
        
    &lt;span style="color: maroon"&gt;#wrapper
    &lt;/span&gt;{
        &lt;span style="color: red"&gt;padding&lt;/span&gt;: &lt;span style="color: blue"&gt;5px&lt;/span&gt;;
        &lt;span style="color: red"&gt;width&lt;/span&gt;: &lt;span style="color: blue"&gt;96%&lt;/span&gt;;
    }
        
    &lt;span style="color: maroon"&gt;#mainImage&lt;/span&gt;, &lt;span style="color: maroon"&gt;#gearsImage&lt;/span&gt;, &lt;span style="color: maroon"&gt;#faqImage
    &lt;/span&gt;{
        &lt;span style="color: red"&gt;width&lt;/span&gt;: &lt;span style="color: blue"&gt;100%&lt;/span&gt;;
        &lt;span style="color: red"&gt;height&lt;/span&gt;: &lt;span style="color: blue"&gt;100px&lt;/span&gt;;
    }
        
}&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;The following images show the site rendered on an iPhone with the CSS media queries in place. Each of the sections now displays vertically making it much easier for the user to access them. Images inside of each section also scale appropriately to fit properly.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;table border="0" cellspacing="0" cellpadding="2" width="600"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td valign="top" width="50%"&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image25_29332AE5.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image25_thumb_2E2542C7.png" width="231" height="441" /&gt;&lt;/a&gt;&lt;/td&gt;

      &lt;td valign="top" width="50%"&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image30_7BCD8115.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image30_thumb_4F6088CA.png" width="246" height="443" /&gt;&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;CSS media queries provide a great way to override default styles in a website and target devices with different resolutions. In this post you've seen how CSS media queries can be used to convert a standard browser-based site into a site that is more accessible to mobile users. Although much more can be done to optimize sites for mobile, CSS media queries provide a nice starting point if you don't have the time or resources to create mobile-specific versions of sites.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8646556" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/dwahlin/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/HTML5/default.aspx">HTML5</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/CSS/default.aspx">CSS</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/Mobile/default.aspx">Mobile</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/CSS+Media+Queries/default.aspx">CSS Media Queries</category></item><item><title>Detecting HTML5/CSS3 Features using Modernizr</title><link>http://weblogs.asp.net/dwahlin/archive/2012/06/22/detecting-html5-css3-features-using-modernizr.aspx</link><pubDate>Fri, 22 Jun 2012 15:05:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8061174</guid><dc:creator>dwahlin</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/dwahlin/rsscomments.aspx?PostID=8061174</wfw:commentRss><comments>http://weblogs.asp.net/dwahlin/archive/2012/06/22/detecting-html5-css3-features-using-modernizr.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_54E7071C.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 20px 15px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" align="left" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_7F533839.png" width="244" height="78" /&gt;&lt;/a&gt;HTML5, CSS3, and related technologies such as canvas and web sockets bring a lot of useful new features to the table that can take Web applications to the next level. These new technologies allow applications to be built using only HTML, CSS, and JavaScript allowing them to be viewed on a variety of form factors including tablets and phones. Although HTML5 features offer a lot of promise, it’s not realistic to develop applications using the latest technologies without worrying about supporting older browsers in the process. If history has taught us anything it’s that old browsers stick around for years and years which means developers have to deal with backward compatibility issues. This is especially true when deploying applications to the Internet that target the general public. This begs the question, “How do you move forward with HTML5 and CSS3 technologies while gracefully handling unsupported features in older browsers?”&lt;/p&gt;  &lt;p&gt;Although you can write code by hand to detect different HTML5 and CSS3 features, it’s not always straightforward. For example, to check for canvas support you need to write code similar to the following:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &lt;/span&gt;window.onload = &lt;span style="color: blue"&gt;function &lt;/span&gt;() {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(canvasSupported()) {
            alert(&lt;span style="color: maroon"&gt;'canvas supported'&lt;/span&gt;);
        }
    };
        
    &lt;span style="color: blue"&gt;function &lt;/span&gt;canvasSupported() {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;canvas = document.createElement(&lt;span style="color: maroon"&gt;'canvas'&lt;/span&gt;);
        &lt;span style="color: blue"&gt;return &lt;/span&gt;(canvas.getContext &amp;amp;&amp;amp; canvas.getContext(&lt;span style="color: maroon"&gt;'2d'&lt;/span&gt;));
    }
&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
  &lt;br /&gt;If you want to check for local storage support the following check can be made. It’s more involved than it should be due to a bug in older versions of Firefox.&lt;/p&gt;

&lt;p&gt;&lt;span style="color: blue"&gt;&lt;/span&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &lt;/span&gt;window.onload = &lt;span style="color: blue"&gt;function &lt;/span&gt;() {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(localStorageSupported()) {
            alert(&lt;span style="color: maroon"&gt;'local storage supported'&lt;/span&gt;);
        }
    };

    &lt;span style="color: blue"&gt;function &lt;/span&gt;localStorageSupported() {
        &lt;span style="color: blue"&gt;try &lt;/span&gt;{
            &lt;span style="color: blue"&gt;return &lt;/span&gt;(&lt;span style="color: maroon"&gt;'localStorage' &lt;/span&gt;&lt;span style="color: blue"&gt;in &lt;/span&gt;window &amp;amp;&amp;amp; window[&lt;span style="color: maroon"&gt;'localStorage'&lt;/span&gt;] != &lt;span style="color: blue"&gt;null&lt;/span&gt;);
        }
        &lt;span style="color: blue"&gt;catch&lt;/span&gt;(e) {}
        &lt;span style="color: blue"&gt;return false&lt;/span&gt;;
    }
&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;
  &lt;br /&gt;Looking through the previous examples you can see that there’s more than meets the eye when it comes to checking browsers for HTML5 and CSS3 features. It takes a lot of work to test every possible scenario and every version of a given browser. Fortunately, you don’t have to resort to writing custom code to test what HTML5/CSS3 features a given browser supports. By using a script library called Modernizr you can add checks for different HTML5/CSS3 features into your pages with a minimal amount of code on your part. Let’s take a look at some of the key features Modernizr offers.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Getting Started with Modernizr&lt;/h2&gt;

&lt;p&gt;The first time I heard the name “Modernizr” I thought it “modernized” older browsers by added missing functionality. In reality, Modernizr doesn’t actually handle adding missing features or “modernizing” older browsers. The Modernizr website states, “The name Modernizr actually stems from the goal of modernizing our development practices (and ourselves)”. Because it relies on feature detection rather than browser sniffing (a common technique used in the past – that never worked that great), Modernizr definitely provides a more modern way to test features that a browser supports and can even handle loading additional scripts called shims or polyfills that fill in holes that older browsers may have. It’s a great tool to have in your arsenal if you’re a web developer.&lt;/p&gt;

&lt;p&gt;Modernizr is available at &lt;a href="http://modernizr.com"&gt;http://modernizr.com&lt;/a&gt;. Two different types of scripts are available including a development script and custom production script. To generate a production script, the site provides a custom script generation tool rather than providing a single script that has everything under the sun for HTML5/CSS3 feature detection. Using the script generation tool you can pick the specific test functionality that you need and ignore everything that you don’t need. That way the script is kept as small as possible. An example of the custom script download screen is shown next. Notice that specific CSS3, HTML5, and related feature tests can be selected.

  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/dwahlin/image_4C8331C5.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/dwahlin/image_thumb_36B94968.png" width="690" height="533" /&gt;&lt;/a&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Once you’ve downloaded your custom script you can add it into your web page using the standard &amp;lt;script&amp;gt; element and you’re ready to start using Modernizr.&lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;

  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Scripts/Modernizr.js&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Modernizr and the HTML Element&lt;/h2&gt;

&lt;p&gt;Once you’ve add a script reference to Modernizr in a page it’ll go to work for you immediately. In fact, by adding the script several different CSS classes will be added to the page’s &amp;lt;html&amp;gt; element at runtime. These classes define what features the browser supports and what features it doesn’t support. Features that aren’t supported get a class name of “no-FeatureName”, for example “no-flexbox”. Features that are supported get a CSS class name based on the feature such as “canvas” or “websockets”. An example of classes added when running a page in Chrome is shown next:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;
  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;html &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot; js flexbox canvas canvastext webgl no-touch geolocation postmessage 
              websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla 
              multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity 
              cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d 
              csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers 
              applicationcache svg inlinesvg smil svgclippaths&amp;quot;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;
  

  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Here’s an example of what the &amp;lt;html&amp;gt; element looks like at runtime with Internet Explorer 9:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;html &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot; js no-flexbox canvas canvastext no-webgl no-touch geolocation 
              postmessage no-websqldatabase no-indexeddb hashchange no-history draganddrop no-websockets 
              rgba hsla multiplebgs backgroundsize no-borderimage borderradius boxshadow no-textshadow 
              opacity no-cssanimations no-csscolumns no-cssgradients no-cssreflections csstransforms 
              no-csstransforms3d no-csstransitions fontface generatedcontent video audio localstorage 
              sessionstorage no-webworkers no-applicationcache svg inlinesvg smil svgclippaths&amp;quot;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;When using Modernizr it’s a common practice to define an &amp;lt;html&amp;gt; element in your page with a &lt;strong&gt;no-js&lt;/strong&gt; class added as shown next:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;html &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;no-js&amp;quot;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;You’ll see starter projects such as HTML5 Boilerplate (&lt;a href="http://html5boilerplate.com"&gt;http://html5boilerplate.com&lt;/a&gt;) or Initializr (&lt;a href="http://initializr.com"&gt;http://initializr.com&lt;/a&gt;) follow this approach (see my &lt;a href="http://weblogs.asp.net/dwahlin/archive/2011/06/05/getting-started-using-html5-boilerplate.aspx" target="_blank"&gt;previous post&lt;/a&gt; for more information on HTML5 Boilerplate). By adding the &lt;strong&gt;no-js&lt;/strong&gt; class it’s easy to tell if a browser has JavaScript enabled or not. If JavaScript is disabled then &lt;strong&gt;no-js&lt;/strong&gt; will stay on the &amp;lt;html&amp;gt; element. If JavaScript is enabled, &lt;strong&gt;no-js&lt;/strong&gt; will be removed by Modernizr and a &lt;strong&gt;js&lt;/strong&gt; class will be added along with other classes that define supported/unsupported features. &lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;&lt;/p&gt;

&lt;h2&gt;Working with HTML5 and CSS3 Features&lt;/h2&gt;

&lt;p&gt;You can use the CSS classes added to the &amp;lt;html&amp;gt; element directly in your CSS files to determine what style properties to use based upon the features supported by a given browser. For example, the following CSS can be used to render a box shadow for browsers that support that feature and a simple border for browsers that don’t support the feature:
  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;

  &lt;pre class="code"&gt;&lt;span style="color: maroon"&gt;.boxshadow #MyContainer &lt;/span&gt;{
    &lt;span style="color: red"&gt;border&lt;/span&gt;: &lt;span style="color: blue"&gt;none&lt;/span&gt;;
    &lt;span style="color: red"&gt;-webkit-box-shadow&lt;/span&gt;: &lt;span style="color: blue"&gt;#666 1px 1px 1px&lt;/span&gt;;
    &lt;span style="color: red"&gt;-moz-box-shadow&lt;/span&gt;: &lt;span style="color: blue"&gt;#666 1px 1px 1px&lt;/span&gt;;
}
    
&lt;span style="color: maroon"&gt;.no-boxshadow #MyContainer &lt;/span&gt;{
    &lt;span style="color: red"&gt;border&lt;/span&gt;: &lt;span style="color: blue"&gt;2px solid black&lt;/span&gt;;
}&lt;br /&gt;&lt;/pre&gt;
  &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;If a browser supports box-shadows the boxshadow CSS class will be added to the &amp;lt;html&amp;gt; element by Modernizr. It can then be associated with a given element. This example associates the boxshadow class with a div with an id of MyContainer. If the browser doesn’t support box shadows then the no-boxshadow class will be added to the &amp;lt;html&amp;gt; element and it can be used to render a standard border around the div. This provides a great way to leverage new CSS3 features in supported browsers while providing a graceful fallback for older browsers.&lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;In addition to using the CSS classes that Modernizr provides on the &amp;lt;html&amp;gt; element, you also use a global Modernizr object that’s created. This object exposes different properties that can be used to detect the availability of specific HTML5 or CSS3 features. For example, the following code can be used to detect canvas and local storage support. You can see that the code is much simpler than the code shown at the beginning of this post. It also has the added benefit of being tested by a large community of web developers around the world running a variety of browsers.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre class="code"&gt;$(document).ready(&lt;span style="color: blue"&gt;function &lt;/span&gt;() {

    &lt;span style="color: blue"&gt;if &lt;/span&gt;(Modernizr.canvas) {
        &lt;span style="color: #006400"&gt;//Add canvas code
    &lt;/span&gt;}

    &lt;span style="color: blue"&gt;if &lt;/span&gt;(Modernizr.localstorage) {
        &lt;span style="color: #006400"&gt;//Add local storage code
    &lt;/span&gt;}

});&lt;br /&gt;&lt;/pre&gt;






&lt;p&gt;The global Modernizr object can also be used to test for the presence of CSS3 features. The following code shows how to test support for border-radius and CSS transforms:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre class="code"&gt;$(document).ready(&lt;span style="color: blue"&gt;function &lt;/span&gt;() {

    &lt;span style="color: blue"&gt;if &lt;/span&gt;(Modernizr.borderradius) {
        $(&lt;span style="color: maroon"&gt;'#MyDiv'&lt;/span&gt;).addClass(&lt;span style="color: maroon"&gt;'borderRadiusStyle'&lt;/span&gt;);
    }
        
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(Modernizr.csstransforms) {
        $(&lt;span style="color: maroon"&gt;'#MyDiv'&lt;/span&gt;).addClass(&lt;span style="color: maroon"&gt;'transformsStyle'&lt;/span&gt;);
    }

});&lt;br /&gt;&lt;/pre&gt;


&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Several other CSS3 feature tests can be performed such as support for opacity, rgba, text-shadow, CSS animations, CSS transitions, multiple backgrounds, and more. A complete list of supported HTML5 and CSS3 tests that Modernizr supports can be found at &lt;a href="http://www.modernizr.com/docs"&gt;http://www.modernizr.com/docs&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Loading Scripts using Modernizr&lt;/h2&gt;

&lt;p&gt;In cases where a browser doesn’t support a specific feature you can either provide a graceful fallback or load a shim/polyfill script to fill in missing functionality where appropriate (more information about shims/polyfills can be found at &lt;a href="https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills"&gt;https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills&lt;/a&gt;). Modernizr has a built-in script loader that can be used to test for a feature and then load a script if the feature isn’t available. The script loader is built-into Modernizr and is also available as a standalone yepnope script (&lt;a href="http://yepnopejs.com"&gt;http://yepnopejs.com&lt;/a&gt;). It’s extremely easy to get started using the script loader and it can really simplify the process of loading scripts based on the availability of a particular browser feature.&lt;/p&gt;

&lt;p&gt;To load scripts dynamically you can use Modernizr’s &lt;strong&gt;load()&lt;/strong&gt; function which accepts properties defining the feature to test (test property), the script to load if the test succeeds (yep property), the script to load if the test fails (nope property), and a script to load regardless of if the test succeeds or fails (both property). An example of using load() with these properties is show next:

  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;

  &lt;pre class="code"&gt;Modernizr.load({
    test: Modernizr.canvas,&lt;br /&gt;    yep:  &lt;span style="color: maroon"&gt;'html5CanvasAvailable.js’,&lt;/span&gt;
    nope: &lt;span style="color: maroon"&gt;'excanvas.js’, &lt;br /&gt;    &lt;font color="#000000"&gt;both:&lt;/font&gt; &lt;span style="color: maroon"&gt;'myCustomScript.js'&lt;/span&gt; 
&lt;/span&gt;});&lt;br /&gt;&lt;/pre&gt;
  &lt;/p&gt;

&lt;p&gt;In this example Modernizr is used to not only load scripts but also to test for the presence of the canvas feature. If the target browser supports the HTML5 canvas then the html5CanvasAvailable.js script will be loaded along with the myCustomScript.js script (use of the yep property in this example is a bit contrived – it was added simply to demonstrate how the property can be used in the load() function). Otherwise, a polyfill script named excanvas.js will be loaded to add missing canvas functionality for Internet Explorer versions prior to 9. Once excanvas.js is loaded the myCustomScript.js script will be loaded.&lt;/p&gt;

&lt;p&gt;Because Modernizr handles loading scripts, you can also use it in creative ways. For example, you can use it to load local scripts when a 3rd party Content Delivery Network (CDN) such as one provided by Google or Microsoft is unavailable for whatever reason. The Modernizr documentation provides the following example that demonstrates the process for providing a local fallback for jQuery when a CDN is down:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;
  &lt;pre class="code"&gt;Modernizr.load([
    {
        load: &lt;span style="color: maroon"&gt;'//ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.js'&lt;/span&gt;,
        complete: &lt;span style="color: blue"&gt;function &lt;/span&gt;() {
            &lt;span style="color: blue"&gt;if &lt;/span&gt;(!window.jQuery) {
                Modernizr.load(&lt;span style="color: maroon"&gt;'js/libs/jquery-1.6.4.min.js'&lt;/span&gt;);
            }
        }
    },
    {
        &lt;span style="color: #006400"&gt;// This will wait for the fallback to load and
        // execute if it needs to.
        &lt;/span&gt;load: &lt;span style="color: maroon"&gt;'needs-jQuery.js'
    &lt;/span&gt;}
]);&lt;br /&gt;&lt;/pre&gt;
  This code attempts to load jQuery from the Google CDN first. Once the script is downloaded (or if it fails) the function associated with complete will be called. The function checks to make sure that the jQuery object is available and if it’s not Modernizr is used to load a local jQuery script. After all of that occurs a script named needs-jQuery.js will be loaded. 

  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;If you’re building applications that use some of the latest and greatest features available in HTML5 and CSS3 then Modernizr is an essential tool. By using it you can reduce the amount of custom code required to test for browser features and provide graceful fallbacks or even load shim/polyfill scripts for older browsers to help fill in missing functionality.&amp;#160; &lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8061174" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/dwahlin/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/HTML5/default.aspx">HTML5</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/CSS/default.aspx">CSS</category><category domain="http://weblogs.asp.net/dwahlin/archive/tags/Modernizr/default.aspx">Modernizr</category></item></channel></rss>