<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;DUAFSH84fip7ImA9WhBWFUw.&quot;"><id>tag:blogger.com,1999:blog-7763566905460067738</id><updated>2013-04-09T10:28:39.136-04:00</updated><category term="WinPhone7" /><category term="mobile" /><category term="calendar" /><category term="plans" /><category term="xaml" /><category term="DatePicker" /><category term="html5" /><category term="registry" /><category term="fonts" /><category term="sketchup" /><category term="api" /><category term="phone" /><category term="Aggregate" /><category term="boilerplate" /><category term="wp7dev" /><category term="dirty code" /><category term="Visual Studio 2008" /><category term="push" /><category term="Jtemplate" /><category term="powershell" /><category term="rails" /><category term="Sailing" /><category term="professional" /><category term="developer" /><category term="greed" /><category term="rant" /><category term="slight mancrush" /><category term="scripting" /><category term="LINQ" /><category term="Pattern Matching" /><category term="TERD" /><category term="diy" /><category term="halo" /><category term="CSS" /><category term="decision maker" /><category term="brother" /><category term="AdMob" /><category term="economy" /><category term="woolapalooza" /><category term="Logging" /><category term="mvc3" /><category term="home improvement" /><category term="F#" /><category term="lambda" /><category term="furniture" /><category term="notprofessional" /><category term="construction" /><category term="auger" /><category term="mvvm" /><category term="DotNetNuke" /><category term="brian" /><category term="HTML" /><category term="coding" /><category term="boston cares" /><category term="posts" /><category term="subway" /><category term="Dare Obasanjo" /><category term="SailCity" /><category term="DIV" /><category term="boston" /><category term="pessimism" /><category term="Event" /><category term="douchebaggery" /><category term="web design" /><category term="Rx" /><category term="designer" /><category term="Microsoft" /><category term="MVC" /><category term="javascript" /><category term="cache" /><category term="joomla" /><category term="old fogey" /><category term="behaviors" /><category term="hand rails" /><category term=".Net" /><category term="rapid prototype" /><category term="web development" /><category term="harvard business review" /><category term="business of software" /><category term="service level agreement" /><category term="leadership" /><category term="Module" /><category term="knockoutjs" /><category term="sharepoint" /><category term="planning" /><category term="chat" /><category term="buddha" /><category term="DNN" /><category term="Jquery" /><category term="JSON" /><category term="glorious green" /><category term="mycode" /><category term="joists" /><category term="recession" /><category term="personal" /><category term="silverlight" /><category term="Scripting Games" /><category term="community service" /><category term="imitation is flattery" /><category term="concrete" /><category term="WP7" /><category term="Hackatopia" /><category term="communication" /><category term="reach" /><category term="deck" /><category term="dog" /><category term="fight" /><category term="Carnage4Life" /><category term="C#" /><category term="regex" /><category term="beam" /><category term="PRISM" /><category term="pale guy" /><category term="SEO" /><category term="longpoll" /><category term="functional programming" /><category term="house" /><category term="team" /><category term="mathew 6:3" /><category term="Fluent Interface" /><category term="WPF" /><category term="perfessional" /><title>Jacob Gable</title><subtitle type="html">Software Developer.  Amateur Philosopher.  Young Punk.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://jacob4u2.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://jacob4u2.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Jacob Gable</name><uri>http://www.blogger.com/profile/06143537581139815312</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="27" src="http://2.bp.blogspot.com/_V6SpmG8I6qw/TJoxZU9swWI/AAAAAAAAANs/FKLAJ7MEDpw/S220/babyProfilePic1.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>67</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/Jacob4U2" /><feedburner:info uri="jacob4u2" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;CkQDRH8_eyp7ImA9WhVWFE0.&quot;"><id>tag:blogger.com,1999:blog-7763566905460067738.post-7485000520839273546</id><published>2012-04-25T18:48:00.001-04:00</published><updated>2012-04-25T20:32:55.143-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-04-25T20:32:55.143-04:00</app:edited><title>Bare Minimum JS - Part 2 - Scoping</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div class="posterous_autopost"&gt;
&lt;div&gt;
&lt;b&gt;Scoping Things Out&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
In our &lt;a href="http://blogs.claritycon.com/blog/2012/04/18/bare-minimum-js-part-1-getting-classy/"&gt;last post&lt;/a&gt;, we talked about ways to create objects in order to keep our code tidy and organized. &amp;nbsp;The next concept we're going to explore is also a way to keep our code tidy and out of the way of each other; Closures and Scoping.&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;The Old and Busted way&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;script src="https://gist.github.com/2493978.js"&gt;
 
&lt;/script&gt;
&lt;/div&gt;
&lt;div&gt;
Here's a common story. &amp;nbsp;You start out with just a couple pages on your website. &amp;nbsp;You don't see the harm in just throwing your javascript on each page, maybe even (&amp;lt;gasp&amp;gt;) directly calling javascript from html event attributes. &amp;nbsp;But, quickly, you've added a bunch of new objects to the global scope and if your application ever gets much more complicated your going to end up having a hard time finding what functions are firing and debugging code paths because of the lack of structure.&lt;/div&gt;
&lt;div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div style="margin-left: 1em; margin-right: 1em;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="margin-left: 1em; margin-right: 1em;"&gt;
&lt;img alt="Javascript-onedoesnothtmlattib" height="242" src="http://getfile7.posterous.com/getfile/files.posterous.com/jacob4u2/LCytOZJpYaOXDbiETJ0gxwe5HEaTNuVhkbQeFBFkdGrM4FW4gVc7k4fLikl3/Javascript-OneDoesNotHtmlAttib.jpg" width="400" /&gt; &lt;/div&gt;
&lt;br /&gt;
&lt;div class="p_embed p_image_embed"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote class="gmail_quote" style="border-left-color: rgb(204,204,204); border-left-style: solid; border-left-width: 1px; margin-bottom: 0px; margin-left: 0.8ex; margin-right: 0px; margin-top: 0px; padding-left: 1ex;"&gt;
First off, shame on you for putting javascript in an HTML attribute. &amp;nbsp;Somebody has to make a value judgement at some point, and for me, it's javascript event handlers on HTML tags. &amp;nbsp;Sorry, had to be said.&lt;/blockquote&gt;
&lt;div&gt;
&amp;nbsp;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;The New Hotness&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
Here is a much more stable way to encapsulate your page logic using a "closure" technique.&lt;/div&gt;
&lt;div&gt;
&lt;script src="https://gist.github.com/2493989.js"&gt;
 
&lt;/script&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;i&gt;Whoa&lt;/i&gt;. &amp;nbsp;Settle down. &amp;nbsp;I know, it's a little bit more complicated. &amp;nbsp;Let's start with the toughest thing on the page; the self executing function we wrapped everything in.&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Breaking it Down&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
All we are doing is creating a function and immediately executing it. &amp;nbsp;The main reason we would want to wrap our code like this is to keep it out of the global scope and therefore more modular and tidy. &amp;nbsp;After running this function, we've created a new &lt;i&gt;page1&lt;/i&gt; object and subscribed to the document.ready event with the &lt;i&gt;page1.ready&lt;/i&gt; handler all without any artifacts in the global scope. &amp;nbsp;Plus, we get a nice way to represent the logic on our page in an object oriented way.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
The &lt;i&gt;"use strict"&lt;/i&gt; is kind of esoteric, but it brings some helpful checks for some of the quirks of javascript. &amp;nbsp;I won't go too much into detail here, but check out John Resig's great &lt;a href="http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/"&gt;article on strict mode&lt;/a&gt;.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
Next, we use the handy dandy object initialization syntax we talked about in our &lt;a href="http://blogs.claritycon.com/blog/2012/04/18/bare-minimum-js-part-1-getting-classy/"&gt;last post&lt;/a&gt; to group together the functionality for page1. &amp;nbsp;Also, in the &lt;i&gt;setupEvents()&lt;/i&gt; method I show an example of how to subscribe to events on elements in a more isolated way than putting functions in html attributes.&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Next Time&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
Classes and scoping can really start to make your Javascript heavy projects much easier to handle. &amp;nbsp;But, it gets even better when we start to introduce another concept called the Module Export pattern. &amp;nbsp;Stay tuned, it's gonna be good for you, I promise.&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Now Playing&lt;/b&gt; - &lt;a href="http://www.youtube.com/watch?v=kDdbAhdYpEk" title="and this bottle of Beast, is taking me home..."&gt;Dashboard Confessional - Screaming Infidelities&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Jacob4U2/~4/mg_VbegR5bU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jacob4u2.blogspot.com/feeds/7485000520839273546/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jacob4u2.blogspot.com/2012/04/bare-minimum-js-part-2-scoping.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/7485000520839273546?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/7485000520839273546?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Jacob4U2/~3/mg_VbegR5bU/bare-minimum-js-part-2-scoping.html" title="Bare Minimum JS - Part 2 - Scoping" /><author><name>Jacob Gable</name><uri>http://www.blogger.com/profile/06143537581139815312</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="27" src="http://2.bp.blogspot.com/_V6SpmG8I6qw/TJoxZU9swWI/AAAAAAAAANs/FKLAJ7MEDpw/S220/babyProfilePic1.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://jacob4u2.blogspot.com/2012/04/bare-minimum-js-part-2-scoping.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cMR3Y-cCp7ImA9WhVWE0Q.&quot;"><id>tag:blogger.com,1999:blog-7763566905460067738.post-6801884112425071637</id><published>2012-04-18T19:54:00.001-04:00</published><updated>2012-04-25T20:11:26.858-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-04-25T20:11:26.858-04:00</app:edited><title>Bare Minimum JS - Part 1</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div class="posterous_autopost"&gt;
&lt;div&gt;
&lt;b&gt;The Bare Minimum You Need To Know About Javascript&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Part 1 -Getting Classy&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
These days, it seems JavaScript is taking over the whole earth. &amp;nbsp;Chances are, if you're starting a new project it's probably going to involve some JavaScript.&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
&lt;div class="p_embed p_image_embed"&gt;
&lt;br /&gt;
&lt;img alt="Javascript-allthethings" height="300" src="http://getfile1.posterous.com/getfile/files.posterous.com/jacob4u2/xS9skgx9aMM4JoLFdGGx61HBcxIQR1w8hW6QO1SZfYAwIdsmderO4gHWLyhP/Javascript-AllTheThings.jpg" width="400" /&gt; &lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
A wise man once told me, "JavaScript is for hackers" and, that is both a blessing and a burden for the common developers relationship with the language. &amp;nbsp;A common developer coming from a strict OOP language like C# or Java is going to be turned off by some of the functional concepts and the lack of an easy way to keep things modular and tidy.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
With that in mind, let's dive in by introducing one of the basics that will help keep your code organized.&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Get Object Oriented&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
JavaScript has two common ways to create an object. &amp;nbsp;First, let's take a look at the quick and dirty way to make an object.&lt;/div&gt;
&lt;div&gt;
&lt;script src="https://gist.github.com/2417306.js"&gt;
 
&lt;/script&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
That is the easiest way to just group a bunch of variables into a class. &amp;nbsp;It's quick and easy but has some downsides to keep an eye out for. &amp;nbsp;If you need to make a lot of these you're going to have to type that out a lot which could lead to fat-fingering it some place. &amp;nbsp;There's also the fact that the `speak()` function we created is an instance variable on each object, which means it will take up more memory than if we defined it in the more classical prototype fashion that would share the function across objects.&lt;/div&gt;
&lt;div&gt;
&lt;script src="https://gist.github.com/2417313.js"&gt;
 
&lt;/script&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
The classical prototype way is a little more verbose, but it comes with the benefit that we now have a way to really pump out some `Baby` objects if we needed to. &amp;nbsp;Notice the way we use `this` in the constructor to make instance variables on the object (more on the magic of `this` in another post.&lt;/div&gt;
&lt;br /&gt;
&lt;blockquote class="gmail_quote" style="border-left-color: rgb(204,204,204); border-left-style: solid; border-left-width: 1px; margin-bottom: 0px; margin-left: 0.8ex; margin-right: 0px; margin-top: 0px; padding-left: 1ex;"&gt;
My rule of thumb is to use the quick and dirty way when I'm making a "one off" object that is just temporary and won't have many instantiations. &amp;nbsp;&lt;/blockquote&gt;
&lt;div&gt;
&lt;br /&gt;
I try to be strict about using the classical approach when I'm creating something that will have more than one instance of itself in my app.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
Next time, we'll talk about closures and some of the ways we can keep our newly created objects from banging into each other in the global scope.&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Now Playing&lt;/b&gt; - &lt;a href="http://www.youtube.com/watch?v=F9wukyl_lyg"&gt;The American Dollar - Anything You Synthesize&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
_&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Jacob4U2/~4/uJW4yFNSW2U" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jacob4u2.blogspot.com/feeds/6801884112425071637/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jacob4u2.blogspot.com/2012/04/bare-minimum-js-part-1.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/6801884112425071637?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/6801884112425071637?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Jacob4U2/~3/uJW4yFNSW2U/bare-minimum-js-part-1.html" title="Bare Minimum JS - Part 1" /><author><name>Jacob Gable</name><uri>http://www.blogger.com/profile/06143537581139815312</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="27" src="http://2.bp.blogspot.com/_V6SpmG8I6qw/TJoxZU9swWI/AAAAAAAAANs/FKLAJ7MEDpw/S220/babyProfilePic1.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://jacob4u2.blogspot.com/2012/04/bare-minimum-js-part-1.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0IHQ385cCp7ImA9WhVSEUs.&quot;"><id>tag:blogger.com,1999:blog-7763566905460067738.post-3710685354439706387</id><published>2012-03-07T20:18:00.001-05:00</published><updated>2012-03-07T20:18:52.128-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-03-07T20:18:52.128-05:00</app:edited><title>Ramblings On the Magnitude of Our Work</title><content type="html">&lt;div class='posterous_autopost'&gt;I love code.  I like to write code, I like to read code.  I dream about code, sometimes good dreams, sometimes bad repetitive ones where I’m stuck in a for loop and can’t get out (anybody else ever have that dream?).&lt;p /&gt; Although not the best metric, sometimes a project is measured by lines of code.  As of right now, the GDCT Next Gen site has over 10,000 lines of javascript code alone; not counting the server side code that handles the database interactions, authentication, logging, profiling and business rules.&lt;div&gt; &lt;br /&gt;Here is some code that updates a timer questions response.  There is certainly more code that this code relies on, but it’s the front line in how we start the process of updating the bubbles and scores for a timer question.&lt;p /&gt; &lt;p&gt;&lt;a href="https://gist.github.com/1997755.js?file=timer_page_snip_bug"&gt;https://gist.github.com/1997755.js?file=timer_page_snip_bug&lt;/a&gt;&lt;/p&gt;&lt;p /&gt;This is about 17 lines of a 1200 line file called pages.surveyTimers.js.  All of the code in this file is written by hand, none of it is generated by a tool; blood, sweat, tears and quite a bit of dubstep music have gone into every line.&lt;p /&gt; &lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204,204,204); border-left-style: solid; padding-left: 1ex;"&gt;... blood, sweat, tears and quite a bit of dubstep music have gone into every line.&lt;/blockquote&gt; &lt;br /&gt;But, there’s a bug in this code.  It’s a small one, a sneaky little one character bug that causes the score not to update in certain situations and in other situations the scoring bubble will not update either.  There is no compiler error in the console because of this bug, no indication from anywhere that there is an incorrect character that will cause 5 new tasks, and widespread panic, to be created.  This character could be the result of just a small instantaneous lapse in focus while refactoring one of the other 1200 lines of code in this one particular file; perhaps while adding a new feature or abstracting out this common code from somewhere else.&lt;p /&gt; &lt;p&gt;&lt;a href="https://gist.github.com/1997755.js?file=timer_page_snip_focus"&gt;https://gist.github.com/1997755.js?file=timer_page_snip_focus&lt;/a&gt;&lt;/p&gt;&lt;p /&gt;I wanted to share a bit of the magnitude of our work with you.  This app is no small feat of software engineering.  It’s a complex and mysterious bird.  That’s why when I hear about the tasks coming up as a result of testing, I am not disheartened.  No piece of software comes out perfect the first time and we have the processes in place to fix issues and respond to feedback.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;&lt;b&gt;Now Playing&lt;/b&gt; - &lt;a href="http://www.youtube.com/watch?v=dX3k_QDnzHE"&gt;M83 - Midnight City&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Jacob4U2/~4/nRM4ej-VqCo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jacob4u2.blogspot.com/feeds/3710685354439706387/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jacob4u2.blogspot.com/2012/03/ramblings-on-magnitude-of-our-work.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/3710685354439706387?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/3710685354439706387?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Jacob4U2/~3/nRM4ej-VqCo/ramblings-on-magnitude-of-our-work.html" title="Ramblings On the Magnitude of Our Work" /><author><name>Jacob Gable</name><uri>http://www.blogger.com/profile/06143537581139815312</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="27" src="http://2.bp.blogspot.com/_V6SpmG8I6qw/TJoxZU9swWI/AAAAAAAAANs/FKLAJ7MEDpw/S220/babyProfilePic1.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://jacob4u2.blogspot.com/2012/03/ramblings-on-magnitude-of-our-work.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0IARX0zcCp7ImA9WhdbGUw.&quot;"><id>tag:blogger.com,1999:blog-7763566905460067738.post-6625814510744240579</id><published>2011-10-18T01:25:00.001-04:00</published><updated>2011-10-18T01:25:44.388-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-18T01:25:44.388-04:00</app:edited><title>Modern Web Projects with HTML5 and Javascript</title><content type="html">&lt;div class='posterous_autopost'&gt;&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;a href="/"&gt;&lt;/a&gt;I&amp;#39;ve been doing web development since 2005, matter of fact, the &lt;a href="http://www.beechwoodhome.com"&gt;first website I ever built&lt;/a&gt; is still around .  Back then it was DotNetNuke and WebForms projects, and it sucked.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;I honestly had no idea what real HTML was until .Net MVC came out.  The first time I had to write a real form and learn what happened when you posted information was a mind blowing experience.  I&amp;#39;ve been hooked ever since.&lt;/div&gt; &lt;p /&gt;Modern web development still sucks.  But I&amp;#39;ve learned to manage some of the sucky parts with what your going to see here today.&lt;p /&gt;&lt;div&gt;&lt;b&gt;Step 1: MVC FTW&lt;/b&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;You need to learn &lt;a href="http://www.asp.net/mvc"&gt;MVC 3&lt;/a&gt; immediately.  There should be absolutely no reason we ever willingly start a new WebForms project again.  It&amp;#39;s beyond this article to teach the intricacies of MVC style web development, but I will say that it will immediately boost your HTML, CSS and Javascript understanding.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;MVC Resources&lt;/div&gt;&lt;div&gt; - &lt;a href="http://www.asp.net/mvc/tutorials/getting-started-with-mvc3-part1-cs"&gt;Intro to ASP.NET MVC 3&lt;/a&gt;&lt;/div&gt;&lt;div&gt; - &lt;a href="http://weblogs.asp.net/scottgu/archive/2010/07/02/introducing-razor.aspx"&gt;Introducing &amp;quot;Razor&amp;quot;&lt;/a&gt;&lt;/div&gt; &lt;p /&gt;&lt;div&gt;&lt;b&gt;Step 2: HTML5 Boilerplate, Normalize.css, Modernizr and YepNope + Polyfills for browser consistency&lt;/b&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;Battling display inconsistencies with different browsers is never really going to go away.  &lt;a href="http://paulirish.com/2011/browser-market-pollution-iex-is-the-new-ie6/"&gt;Legacy IE versions are entrenched in the enterprise world&lt;/a&gt; and likely will be there for years to come.  However, we can stand on the shoulders of giants in the web community who have put together a group of collected tips, tricks, magic spells and hacks that give us a pretty consistent baseline experience across most browsers.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;&lt;div class='p_embed p_image_embed'&gt; &lt;a href="http://posterous.com/getfile/files.posterous.com/jacob4u2/lQcFsxODLQGK7GVnY4wRlCJ8Sn3QKNHW3nAydGt1YGBoXUDDLLW4wKQWqpd0/browserlineupin20191.jpg"&gt;&lt;img alt="Browserlineupin20191" height="333" src="http://posterous.com/getfile/files.posterous.com/jacob4u2/EtHNfgjLe4HM1QnK6iDjt9fS1C1ew3uOCljGnXqUebDXmGWUClHRlWTAv2kW/browserlineupin20191.jpg.scaled.500.jpg" width="500" /&gt;&lt;/a&gt; &lt;/div&gt; &lt;br /&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;The HTML5 Boilerplate project is a great project for not only getting a jump start on a consistent site look and feel, it&amp;#39;s also a great way to learn about the cutting edge in web development.  HTML5 Boilerplate code is chock full of tasty bits of knowledge ready for you to expand your mind when you&amp;#39;re ready.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;&lt;div class='p_embed p_image_embed'&gt; &lt;a href="http://posterous.com/getfile/files.posterous.com/jacob4u2/lIKYdDQAqfDrR3bDRjygO3ol9E6PeBJxKHwLFAFnH80RBJpRF6uIniNm93yk/HTML5_Boilerplate_-_A_rock-sol.png"&gt;&lt;img alt="Html5_boilerplate_-_a_rock-sol" height="101" src="http://posterous.com/getfile/files.posterous.com/jacob4u2/LHxIOZa9u60IxIuEkRgJTZ01KcxMWnWQKP3oenJDDo4af2FOIphWC4rd9kL8/HTML5_Boilerplate_-_A_rock-sol.png.scaled.500.jpg" width="500" /&gt;&lt;/a&gt; &lt;/div&gt; &lt;br /&gt;&lt;/div&gt; &lt;p /&gt;&lt;div&gt;HTML5 Boilerplate and Normalize.css Resources&lt;/div&gt;&lt;div&gt; - &lt;a href="http://www.html5boilerplate.com"&gt;HTML5 Boilerplate Site&lt;/a&gt;&lt;/div&gt;&lt;div&gt; - &lt;a href="http://necolas.github.com/normalize.css/"&gt;Normalize.css Site&lt;/a&gt;&lt;/div&gt; &lt;div&gt; - &lt;a href="http://www.modernizr.com/"&gt;Modernizr Site&lt;/a&gt;&lt;/div&gt;&lt;div&gt; - &lt;a href="http://yepnopejs.com/"&gt;YepNope Site&lt;/a&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;&lt;b&gt;Step 3: HTML5 != Just put a Canvas in it, bro&lt;/b&gt;&lt;/div&gt;&lt;p /&gt; &lt;div&gt;I&amp;#39;ve worked on a couple HTML5 sites... err applications, and I&amp;#39;ve never once found it helpful to use a canvas element in something that is not a game.  There are so many other cool things in the HTML5 spec that aren&amp;#39;t a canvas element that people don&amp;#39;t even know about.  The best parts of HTML5 are the things that make you write less code that is more readable.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;&lt;p&gt;&lt;a href="https://gist.github.com/1294650.js?file=html5_semantic_page.html"&gt;&lt;/script&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;Isn&amp;#39;t that cleaner than a bunch of div&amp;#39;s?  And, not pictured, but equally as important is the cleaner CSS that results from not having class pollution everywhere.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;I could go on about all the new API&amp;#39;s but the point I want to make is that it&amp;#39;s no longer acceptable to say &amp;quot;All HTML5 adds is just a canvas and audio element, right?&amp;quot;. No,  HTML5 is a collection of state of the art browser API&amp;#39;s and semantic markup elements built to let you make the next generation of applications that make use of native resources without the native application walled garden.&lt;/div&gt; &lt;p /&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"&gt; HTML5 is a collection of state of the art browser API&amp;#39;s and semantic markup elements built to let you make the next generation of applications that make use of native resources without the native application walled garden.&lt;/blockquote&gt; &lt;p /&gt;&lt;div&gt;HTML5 Resources&lt;/div&gt;&lt;div&gt; - &lt;a href="http://www.html5rocks.com/en/"&gt;HTML5 Rocks&lt;/a&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;&lt;b&gt;Step 4: Javascript: with great power comes great responsibility&lt;/b&gt;&lt;/div&gt;&lt;p /&gt; &lt;div&gt;It&amp;#39;s amazing how intimidating javascript is to the new comer.  I think when faced with the intricacies and inconsistencies of javascript people often fall back to a mess of procedural code with the caveat that &amp;quot;Hey, it works, so I don&amp;#39;t want to change it&amp;quot;.  This is lazy, and not the good kind of lazy either.  We need to, and can, write javascript code that is object oriented, loosely coupled and efficient.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;Here are some signs that your javascript code is starting to suck:&lt;/div&gt;&lt;div&gt; - You have one long javascript file&lt;/div&gt;&lt;div&gt; - You have everything in the global namespace&lt;/div&gt;&lt;p /&gt;&lt;div&gt;If you find yourself with a long javascript file and wish you could separate things out into nice manageable chunks, try using a framework like &lt;a href="http://www.codethinked.com/squishit-the-friendly-aspnet-javascript-and-css-squisher"&gt;SquishIt&lt;/a&gt; to combine and minify your javascript files for you as part of the build process.  Complicated &lt;a href="https://github.com/jquery/jquery/tree/master/src"&gt;open source projects like jQuery&lt;/a&gt; use a similar process to break things down into smaller, more manageable chunks.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;Cluttering the global namespace is like having all your variables in an application be shared with everything else.  Information hiding is a core principle of object oriented programming and to that end you should know how to write code that protects it&amp;#39;s private data and exposes a nice clean API for you, or someone else, to take advantage of.  One way of doing this is by taking advantage of the Module (or Module-Export) pattern.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;&lt;script src="https://gist.github.com/1294650.js?file=module_export"&gt;https://gist.github.com/1294650.js?file=html5_semantic_page.html"&gt;&lt;/script&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;Isn&amp;#39;t that cleaner than a bunch of div&amp;#39;s?  And, not pictured, but equally as important is the cleaner CSS that results from not having class pollution everywhere.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;I could go on about all the new API&amp;#39;s but the point I want to make is that it&amp;#39;s no longer acceptable to say &amp;quot;All HTML5 adds is just a canvas and audio element, right?&amp;quot;. No,  HTML5 is a collection of state of the art browser API&amp;#39;s and semantic markup elements built to let you make the next generation of applications that make use of native resources without the native application walled garden.&lt;/div&gt; &lt;p /&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"&gt; HTML5 is a collection of state of the art browser API&amp;#39;s and semantic markup elements built to let you make the next generation of applications that make use of native resources without the native application walled garden.&lt;/blockquote&gt; &lt;p /&gt;&lt;div&gt;HTML5 Resources&lt;/div&gt;&lt;div&gt; - &lt;a href="http://www.html5rocks.com/en/"&gt;HTML5 Rocks&lt;/a&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;&lt;b&gt;Step 4: Javascript: with great power comes great responsibility&lt;/b&gt;&lt;/div&gt;&lt;p /&gt; &lt;div&gt;It&amp;#39;s amazing how intimidating javascript is to the new comer.  I think when faced with the intricacies and inconsistencies of javascript people often fall back to a mess of procedural code with the caveat that &amp;quot;Hey, it works, so I don&amp;#39;t want to change it&amp;quot;.  This is lazy, and not the good kind of lazy either.  We need to, and can, write javascript code that is object oriented, loosely coupled and efficient.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;Here are some signs that your javascript code is starting to suck:&lt;/div&gt;&lt;div&gt; - You have one long javascript file&lt;/div&gt;&lt;div&gt; - You have everything in the global namespace&lt;/div&gt;&lt;p /&gt;&lt;div&gt;If you find yourself with a long javascript file and wish you could separate things out into nice manageable chunks, try using a framework like &lt;a href="http://www.codethinked.com/squishit-the-friendly-aspnet-javascript-and-css-squisher"&gt;SquishIt&lt;/a&gt; to combine and minify your javascript files for you as part of the build process.  Complicated &lt;a href="https://github.com/jquery/jquery/tree/master/src"&gt;open source projects like jQuery&lt;/a&gt; use a similar process to break things down into smaller, more manageable chunks.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;Cluttering the global namespace is like having all your variables in an application be shared with everything else.  Information hiding is a core principle of object oriented programming and to that end you should know how to write code that protects it&amp;#39;s private data and exposes a nice clean API for you, or someone else, to take advantage of.  One way of doing this is by taking advantage of the Module (or Module-Export) pattern.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;&lt;script src="https://gist.github.com/1294650.js?file=module_export&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;These two tips amplify their awesomeness when used together.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;&lt;b&gt;Step 5: jQuery... I mean YAYQUERY!!!&lt;/b&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;Now, all the purist code snobs out there are going to tell you that you should know how to get elements, modify attributes and animate things with pure javascript.  Well, I think that&amp;#39;s crap.  If I want to build a deck I&amp;#39;m going to use a damn circular saw because it&amp;#39;s fast and I&amp;#39;m trying to build a deck, not learn all about the art of building decks or the inner workings of wood cutting devices.  Just to drive this metaphor home; jQuery is a damn fine circular saw.  And &lt;a href="http://jacob4u2.posterous.com/2008/06/deck-plans-using-google-sketchup.html"&gt;I like to build decks&lt;/a&gt;.&lt;/div&gt; &lt;p /&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"&gt; If I want to build a deck I&amp;#39;m going to use a damn circular saw because it&amp;#39;s fast and I&amp;#39;m trying to build a deck, not learn all about the art of building decks or the inner workings of wood cutting devices.  Just to drive this metaphor home; jQuery is a damn fine circular saw.&lt;/blockquote&gt; &lt;p /&gt;&lt;div&gt;There are lots of other javascript frameworks out there, but they all do pretty much the same thing and with about the same amount of performance.  Most of us are never going to need much better performance than what jQuery can provide to us, so the easy learning curve and vast amount of plugins available make it a superior choice in my opinion.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;Here are some of my favorite jQuery Gems I&amp;#39;ll share with you:&lt;/div&gt;&lt;p /&gt;&lt;div&gt;&lt;p&gt;&lt;a href="https://gist.github.com/1294650.js?file=j_query_gems"&gt;https://gist.github.com/1294650.js?file=j_query_gems&lt;/a&gt;&lt;/p&gt;&lt;/div&gt; &lt;p /&gt;&lt;div&gt;jQuery Resources&lt;/div&gt;&lt;div&gt; - &lt;a href="http://www.futurecolors.ru/jquery/"&gt;jQuery Cheatsheet by Future Colors&lt;/a&gt;&lt;/div&gt;&lt;div&gt; - &lt;a href="http://yayquery.com/"&gt;YayQuery Podcast&lt;/a&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt; &lt;b&gt;Wrapping it up&lt;/b&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;That ought to get most people up to speed on what I use for Modern Web Projects.  Maybe next time we can talk about taking a site from design file to HTML.&lt;/div&gt;&lt;p /&gt;&lt;div&gt;&lt;b&gt;Now Playing: &lt;/b&gt;&lt;a href="http://www.youtube.com/watch?v=-DSVDcw6iW8"&gt;A Real Hero - College feat. Electric Youth&lt;/a&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;_&lt;/div&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Jacob4U2/~4/oaudFhZEraY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jacob4u2.blogspot.com/feeds/6625814510744240579/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jacob4u2.blogspot.com/2011/10/modern-web-projects-with-html5-and.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/6625814510744240579?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/6625814510744240579?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Jacob4U2/~3/oaudFhZEraY/modern-web-projects-with-html5-and.html" title="Modern Web Projects with HTML5 and Javascript" /><author><name>Jacob Gable</name><uri>http://www.blogger.com/profile/06143537581139815312</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="27" src="http://2.bp.blogspot.com/_V6SpmG8I6qw/TJoxZU9swWI/AAAAAAAAANs/FKLAJ7MEDpw/S220/babyProfilePic1.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://jacob4u2.blogspot.com/2011/10/modern-web-projects-with-html5-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0cFRXw4fip7ImA9WhdUGUg.&quot;"><id>tag:blogger.com,1999:blog-7763566905460067738.post-7125689174916640106</id><published>2011-10-06T21:30:00.001-04:00</published><updated>2011-10-06T21:30:14.236-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-06T21:30:14.236-04:00</app:edited><title>Programmer Values</title><content type="html">&lt;div class='posterous_autopost'&gt;&lt;a href="/"&gt;&lt;/a&gt;Tonight I&amp;#39;ve been thinking a lot about my career.  Every now and then I like to get back to &amp;quot;&lt;a href="http://en.wikipedia.org/wiki/First_principle"&gt;First Principles&lt;/a&gt;&amp;quot; and re-evaluate my core values.&lt;p /&gt;&lt;div&gt;To that end, here is what I think I value as a software developer.&lt;p /&gt;&lt;div&gt;1.  A consistent working location.&lt;/div&gt;&lt;div&gt;  - see &lt;a href="http://www.slate.com/articles/business/moneybox/2011/05/your_commute_is_killing_you.html"&gt;Your Commute is Killing You&lt;/a&gt;&lt;/div&gt; &lt;div&gt;  - Part of a community that I can contribute to&lt;/div&gt;&lt;p /&gt;&lt;div&gt;2.  Solving interesting problems that help people be more productive and prosperous.&lt;/div&gt;&lt;div&gt;  - Challenging work&lt;/div&gt;&lt;div&gt;  - Not micro-managed&lt;/div&gt; &lt;div&gt;  - Do no evil&lt;/div&gt;&lt;p /&gt;&lt;div&gt;3.  Working with people who I can learn from and hang out with&lt;/div&gt;&lt;div&gt;  - Continuous learning&lt;/div&gt;&lt;div&gt;  - see &lt;a href="http://blogs.hbr.org/bregman/2010/07/why-friends-matter-at-work-and.html"&gt;Why Friends Matter at Work&lt;/a&gt;&lt;/div&gt; &lt;p /&gt;&lt;div&gt;4.  Sharing my knowledge with other people.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;  - Presentations, discussions&lt;/div&gt;&lt;div&gt;  - Grow your people&lt;/div&gt;&lt;div&gt;  - New business from new ideas&lt;/div&gt;&lt;p /&gt;&lt;div&gt;All this is sprinkled with most of the stuff you see in the &lt;a href="http://www.youtube.com/watch?v=u6XAPnuFjJc"&gt;RSA Animate - Drive&lt;/a&gt; video:&lt;/div&gt; &lt;p /&gt;&lt;div&gt;&lt;iframe src="http://www.youtube.com/embed/u6XAPnuFjJc?wmode=transparent" allowfullscreen frameborder="0" height="417" width="500"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;That&amp;#39;s it for now, maybe some future me will look back at this and re-evaluate.  Next time I&amp;#39;ll talk about my career as a consultant and how that meshes with these values.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;&lt;b&gt;Now Playing&lt;/b&gt; - &lt;a href="http://www.youtube.com/watch?v=p2qLTsYr39c"&gt;Drake - I&amp;#39;m On One&lt;/a&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;_&lt;/div&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Jacob4U2/~4/SUFOonDrPKg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jacob4u2.blogspot.com/feeds/7125689174916640106/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jacob4u2.blogspot.com/2011/10/programmer-values.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/7125689174916640106?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/7125689174916640106?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Jacob4U2/~3/SUFOonDrPKg/programmer-values.html" title="Programmer Values" /><author><name>Jacob Gable</name><uri>http://www.blogger.com/profile/06143537581139815312</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="27" src="http://2.bp.blogspot.com/_V6SpmG8I6qw/TJoxZU9swWI/AAAAAAAAANs/FKLAJ7MEDpw/S220/babyProfilePic1.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://img.youtube.com/vi/u6XAPnuFjJc/default.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://jacob4u2.blogspot.com/2011/10/programmer-values.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEEGR38_fSp7ImA9WhdUEUo.&quot;"><id>tag:blogger.com,1999:blog-7763566905460067738.post-3937553958486121554</id><published>2011-09-27T22:23:00.001-04:00</published><updated>2011-09-27T22:23:46.145-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-27T22:23:46.145-04:00</app:edited><title>document.ready with jQuery Mobile</title><content type="html">&lt;div class='posterous_autopost'&gt;One of the first hurdles I had with creating sites with jQuery Mobile was figuring out how to run my code when a page loads.  Since navigating to a new page no longer requires a postback, the standard $(document).ready approach isn&amp;#39;t going to cut it.  I&amp;#39;ve come up with a solution that I think helps you modularize and isolate your code to prevent having one large unmaintainable lump of a javascript file.&lt;p /&gt;&lt;div&gt;&lt;b&gt;Creating a Namespace&lt;/b&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;Now when I work on javascript heavy applications, I take care to &lt;a href="http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth" target="_blank"&gt;modularize my javascript&lt;/a&gt; but I don&amp;#39;t necessarily follow the pattern exactly.  I start out by &lt;a href="http://elegantcode.com/2011/01/26/basic-javascript-part-8-namespaces/"&gt;creating a namespace&lt;/a&gt; object, and I usually place this in a file called core.js.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;&lt;p&gt;&lt;a href="https://gist.github.com/1246402.js?file=ready.core"&gt;https://gist.github.com/1246402.js?file=ready.core&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;So, what we&amp;#39;re doing here is creating a blank object (MYAPP) to &amp;quot;scope&amp;quot; our application objects.  We &lt;a href="http://api.jquery.com/jQuery.extend/"&gt;extend&lt;/a&gt; that object with some new objects to hold our pages and maybe even some options.  We would also maybe put some other stuff in here, but for this example we&amp;#39;ll keep it mostly clean.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;&lt;b&gt;The Page Event Mapper&lt;/b&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;Now it&amp;#39;s time to do some plumbing work to hook the new page objects we are going to create up to the jQuery Mobile navigation framework.  We want to pass the &lt;a href="http://jquerymobile.com/test/docs/api/events.html"&gt;page events from jQuery Mobile&lt;/a&gt; to a page class that will handle the events.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;&lt;p&gt;&lt;a href="https://gist.github.com/1246402.js?file=ready.navigation"&gt;https://gist.github.com/1246402.js?file=ready.navigation&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;Every page in jQuery mobile is wrapped in a div with a data-role attribute set to &amp;quot;page&amp;quot;, so what we&amp;#39;re doing here is handling the jQuery Mobile page events and passing them to our corresponding page.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;&lt;b&gt;A Page Class Example&lt;/b&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;Speaking of pages, let&amp;#39;s take a look at what an example page looks like in my code.&lt;/div&gt;&lt;p /&gt;&lt;div&gt;&lt;p&gt;&lt;a href="https://gist.github.com/1246402.js?file=ready.homepage"&gt;https://gist.github.com/1246402.js?file=ready.homepage&lt;/a&gt;&lt;/p&gt;&lt;/div&gt; &lt;p /&gt;&lt;div&gt;As you can see, I&amp;#39;ve kept the code pretty simple.  This class will now be able to respond to init events (which get fired before the page is modified by jQuery Mobile) and the show event which gets fired every time the page is navigated to (even when it&amp;#39;s cached and navigated back to).&lt;/div&gt; &lt;p /&gt;&lt;div&gt;&lt;b&gt;But Don&amp;#39;t Take My Word For It&lt;/b&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;If you want to give a try for yourself, head on over to the &lt;a href="http://jsfiddle.net/8EF6F/2/"&gt;jsFiddle I set up with this example code&lt;/a&gt; already set up.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;&lt;b&gt;Now Playing&lt;/b&gt;: &lt;a href="http://www.youtube.com/watch?v=dyYRtOM71uw"&gt;Nas - It Ain&amp;#39;t Hard to Tell (Reading Rainbow Remix)&lt;/a&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;_&lt;/div&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Jacob4U2/~4/q7Q-xD4-H88" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jacob4u2.blogspot.com/feeds/3937553958486121554/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jacob4u2.blogspot.com/2011/09/documentready-with-jquery-mobile.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/3937553958486121554?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/3937553958486121554?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Jacob4U2/~3/q7Q-xD4-H88/documentready-with-jquery-mobile.html" title="document.ready with jQuery Mobile" /><author><name>Jacob Gable</name><uri>http://www.blogger.com/profile/06143537581139815312</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="27" src="http://2.bp.blogspot.com/_V6SpmG8I6qw/TJoxZU9swWI/AAAAAAAAANs/FKLAJ7MEDpw/S220/babyProfilePic1.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://jacob4u2.blogspot.com/2011/09/documentready-with-jquery-mobile.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUYERX4yfyp7ImA9WhdVFE0.&quot;"><id>tag:blogger.com,1999:blog-7763566905460067738.post-6766777203370374191</id><published>2011-09-18T23:31:00.001-04:00</published><updated>2011-09-18T23:31:44.097-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-18T23:31:44.097-04:00</app:edited><title>On Windows 8 Metro HTML Apps and the Web Developer Ethos</title><content type="html">&lt;div class='posterous_autopost'&gt;&lt;div&gt; &lt;/div&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"&gt; &lt;b&gt;Ethos&lt;/b&gt; (&lt;i&gt;noun&lt;/i&gt;): The characteristic spirit of a culture, era or community as seen in its beliefs and aspirations.&lt;/blockquote&gt;&lt;p /&gt;&lt;div&gt;&lt;b&gt;TL&lt;/b&gt;;&lt;b&gt;DR&lt;/b&gt;: I hear a lot of people talk about the what the value of offering a way to create &amp;quot;Metro&amp;quot; style apps for Windows 8 using HTML and Javascript is, and I disagree.  I believe the common web developer has a different value system than what the Win 8 &amp;quot;Metro&amp;quot; environment encourages and as a result not many people will end up using the HTML options for creating &amp;quot;Metro&amp;quot; apps on Windows 8.&lt;/div&gt; &lt;p /&gt;&lt;b&gt;Current Web Development Values&lt;/b&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;div&gt; - Optimized javascript and css for fast page loading.&lt;/div&gt;&lt;div&gt;     - Combined, Minified JS and CSS&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style=""&gt;	&lt;/span&gt; - Load from CDN, fallback to local&lt;/div&gt; &lt;div&gt; - Simple, short javascript code&lt;/div&gt;&lt;div&gt; - Reactive and Responsive to different devices.&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;I&amp;#39;ll take some liberties and really just boil these down to the following:&lt;/div&gt;&lt;div&gt; - &lt;b&gt;Fast Page Loading&lt;/b&gt;&lt;/div&gt; &lt;div&gt; - &lt;b&gt;Simple Code&lt;/b&gt;&lt;/div&gt;&lt;div&gt; - &lt;b&gt;Platform Agnostic&lt;/b&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;&lt;b&gt;Fast Page Loading &lt;/b&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;As a web developer I have certain performance implications in mind when I organize my site and its resources.  I like to minify and combine all my script and css files for quicker loading along with loading certain libraries from CDN rather than locally to take advantage of Caching.  The examples I&amp;#39;ve seen so far tend to have about 87 obscure scripts loading in the head of the page and it makes my face twitch every time I see it.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;&lt;b&gt;Simple Code&lt;/b&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;The WinJS and WinRT namespaces are insanely long and ugly to use.  Again, the average to elite js developer has it ingrained to limit the size of their javascript files for performance.  Using something like WinJS.Class.define(...) or some of the other longer examples for subscribing to certain app events like startup is going to turn off developers to creating apps.  The good thing is that this could be fixed by someone just wrapping all that stuff up in a shorter namespace utility library ($win sounds good).&lt;/div&gt; &lt;p /&gt;&lt;div&gt;The javascript examples I&amp;#39;ve seen so far tend to degrade into this monolithic amount of JS in one file.  There needs to be a better story for architecting javascript heavy solutions.  I think the .Net world isn&amp;#39;t used to this type of project yet and it would have been nice to see MS give some guidance about managing them in a responsible way.  I&amp;#39;d like to see a convention based solution that encourages a module + export pattern for managing the complexity of javascript code.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;&lt;b&gt;Platform Agnostic&lt;/b&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;I&amp;#39;ll start out by saying that it&amp;#39;s unfair when I see people comparing the Metro app development with developing a website.  This is a native app and as such will have a heavy reliance on the underlying platform.  The better comparison for development is that of a ChromeOS application.  On the other hand ChromeOS application doesn&amp;#39;t have the same heavy importance on a radical theme/styling for apps like Metro apps will.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;Host enforcement rules add an extra layer of security for &amp;quot;Metro&amp;quot; HTML apps by only allowing &amp;quot;safe&amp;quot; html and javascript references.  Host enforcement rules add an extra layer of security at the expense of clean and easy to implement javascript.  The fact is that most web sources are going to not have &amp;quot;safe&amp;quot; html (especially since most data- attributes are considered harmful).&lt;/div&gt; &lt;/div&gt;&lt;p /&gt;&lt;div&gt;That&amp;#39;s all I have for now as far as notes, I&amp;#39;m sure I&amp;#39;ll tidy this up a bit for a more official review later on when I&amp;#39;ve made a couple apps.&lt;/div&gt;&lt;p /&gt;&lt;div&gt;&lt;b&gt;Now Playing&lt;/b&gt;: &lt;a href="http://www.youtube.com/watch?v=66B46E_hrrk"&gt;Mt Eden - Gambler&lt;/a&gt;&lt;/div&gt; &lt;p /&gt;&lt;div&gt;_&lt;/div&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Jacob4U2/~4/dwVpS9srQuI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jacob4u2.blogspot.com/feeds/6766777203370374191/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jacob4u2.blogspot.com/2011/09/on-windows-8-metro-html-apps-and-web.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/6766777203370374191?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/6766777203370374191?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Jacob4U2/~3/dwVpS9srQuI/on-windows-8-metro-html-apps-and-web.html" title="On Windows 8 Metro HTML Apps and the Web Developer Ethos" /><author><name>Jacob Gable</name><uri>http://www.blogger.com/profile/06143537581139815312</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="27" src="http://2.bp.blogspot.com/_V6SpmG8I6qw/TJoxZU9swWI/AAAAAAAAANs/FKLAJ7MEDpw/S220/babyProfilePic1.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://jacob4u2.blogspot.com/2011/09/on-windows-8-metro-html-apps-and-web.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkQDQn48eSp7ImA9WhdTF0Q.&quot;"><id>tag:blogger.com,1999:blog-7763566905460067738.post-5657085253589783292</id><published>2011-07-16T00:26:00.003-04:00</published><updated>2011-07-16T00:26:13.071-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-16T00:26:13.071-04:00</app:edited><title>MVC 3 jQuery Mobile Site Template</title><content type="html">&lt;div class='posterous_autopost'&gt;I spent most of the night creating a basic &lt;a href="http://visualstudiogallery.msdn.microsoft.com/eb8d369a-9397-4042-a9d7-f1c57148c717"&gt;jQuery Mobile Site Template for .Net&lt;/a&gt; MVC 3 Razor sites.&lt;p /&gt;&lt;div&gt;The source for this project can be found over at the &lt;a href="https://github.com/jgable/MVC3-jQuery-Mobile-Site-Template"&gt;MVC 3 jQuery Mobile Site Template&lt;/a&gt; project on GitHub.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;Nothing much to say really about the template.  It&amp;#39;s very similar to my previous &lt;a href="http://visualstudiogallery.msdn.microsoft.com/2b462e2e-5215-4d07-a4de-4c31c432c12b"&gt;MotherEffin HTML5 Template&lt;/a&gt; but I kept it a little bit more bare bones this time.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;Most people will want to check out the &lt;a href="http://jquerymobile.com/"&gt;jQuery Mobile&lt;/a&gt; site and &lt;a href="http://jquerymobile.com/test/"&gt;Demo / Documentation&lt;/a&gt; before the template will be that useful.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;Now Playing - &lt;a href="http://www.youtube.com/watch?v=dfF4t9-wpCM"&gt;AudioSlave - Shadow on the Sun&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Jacob4U2/~4/UAyNY6TeY-U" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jacob4u2.blogspot.com/feeds/5657085253589783292/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jacob4u2.blogspot.com/2011/07/mvc-3-jquery-mobile-site-template_16.html#comment-form" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/5657085253589783292?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/5657085253589783292?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Jacob4U2/~3/UAyNY6TeY-U/mvc-3-jquery-mobile-site-template_16.html" title="MVC 3 jQuery Mobile Site Template" /><author><name>Jacob Gable</name><uri>http://www.blogger.com/profile/06143537581139815312</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="27" src="http://2.bp.blogspot.com/_V6SpmG8I6qw/TJoxZU9swWI/AAAAAAAAANs/FKLAJ7MEDpw/S220/babyProfilePic1.jpg" /></author><thr:total>4</thr:total><feedburner:origLink>http://jacob4u2.blogspot.com/2011/07/mvc-3-jquery-mobile-site-template_16.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkQDQHc_eyp7ImA9WhdTF0Q.&quot;"><id>tag:blogger.com,1999:blog-7763566905460067738.post-2691391899279567277</id><published>2011-07-16T00:26:00.001-04:00</published><updated>2011-07-16T00:26:11.943-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-16T00:26:11.943-04:00</app:edited><title>MVC 3 jQuery Mobile Site Template</title><content type="html">&lt;div class='posterous_autopost'&gt;I spent most of the night creating a basic &lt;a href="http://visualstudiogallery.msdn.microsoft.com/eb8d369a-9397-4042-a9d7-f1c57148c717"&gt;jQuery Mobile Site Template for .Net&lt;/a&gt; MVC 3 Razor sites.&lt;p /&gt;&lt;div&gt;The source for this project can be found over at the &lt;a href="https://github.com/jgable/MVC3-jQuery-Mobile-Site-Template"&gt;MVC 3 jQuery Mobile Site Template&lt;/a&gt; project on GitHub.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;Nothing much to say really about the template.  It&amp;#39;s very similar to my previous &lt;a href="http://visualstudiogallery.msdn.microsoft.com/2b462e2e-5215-4d07-a4de-4c31c432c12b"&gt;MotherEffin HTML5 Template&lt;/a&gt; but I kept it a little bit more bare bones this time.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;Most people will want to check out the &lt;a href="http://jquerymobile.com/"&gt;jQuery Mobile&lt;/a&gt; site and &lt;a href="http://jquerymobile.com/test/"&gt;Demo / Documentation&lt;/a&gt; before the template will be that useful.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;Now Playing - &lt;a href="http://www.youtube.com/watch?v=dfF4t9-wpCM"&gt;AudioSlave - Shadow on the Sun&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Jacob4U2/~4/X44sBWBx1SA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jacob4u2.blogspot.com/feeds/2691391899279567277/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jacob4u2.blogspot.com/2011/07/mvc-3-jquery-mobile-site-template.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/2691391899279567277?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/2691391899279567277?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Jacob4U2/~3/X44sBWBx1SA/mvc-3-jquery-mobile-site-template.html" title="MVC 3 jQuery Mobile Site Template" /><author><name>Jacob Gable</name><uri>http://www.blogger.com/profile/06143537581139815312</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="27" src="http://2.bp.blogspot.com/_V6SpmG8I6qw/TJoxZU9swWI/AAAAAAAAANs/FKLAJ7MEDpw/S220/babyProfilePic1.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://jacob4u2.blogspot.com/2011/07/mvc-3-jquery-mobile-site-template.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEEFSX4yeyp7ImA9WhZbFkQ.&quot;"><id>tag:blogger.com,1999:blog-7763566905460067738.post-9117839420096183145</id><published>2011-06-21T18:43:00.007-04:00</published><updated>2011-06-21T18:50:18.093-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-21T18:50:18.093-04:00</app:edited><title>Anatomy of an HTML5 Page Transition</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="posterous_autopost"&gt;One of the sexy new trends in &lt;b&gt;HTML5&lt;/b&gt; development right now is &lt;b&gt;Page Transitions&lt;/b&gt;. &amp;nbsp;One of the first places I noticed Page Transitions in use was the &lt;a href="https://github.com/jgable/HTML5BuildTasks" target="_blank"&gt;GitHub Repository Explorer&lt;/a&gt;; as you click around to different directories and files, the content slides in and out without reloading the page.&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;While most of this functionality can be achieved through Javascript alone, the actual URL &lt;a href="http://diveintohtml5.org/history.html" target="_blank"&gt;History manipulation&lt;/a&gt; has only been available in the (relatively) recent incarnations of HTML5. &amp;nbsp;When you add in the ability to take advantage of &lt;b&gt;CSS3&lt;/b&gt; transitions for sliding pages in and out, you end up with a pretty modern example of HTML5 capabilities.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;b&gt;Overview&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Here is a pretty typical scenario; two pages with identical layout, but different content.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;div class="p_embed p_image_embed"&gt;&lt;a href="http://posterous.com/getfile/files.posterous.com/jacob4u2/00CeE6eNhBxRhvKoGQnxYmwR0r0jdPCwUctKbYUoUiaQX6IzK6plTfo9DPH4/second.png.scaled.1000.jpg"&gt;&lt;img alt="Second" height="259" src="http://posterous.com/getfile/files.posterous.com/jacob4u2/gDlaao5K3xE5OVVmhbo4cXDarluDBZY6lrUxQRmVRtNzVq6xSC4ol583u0jg/second.png.scaled.500.jpg" width="500" /&gt;&lt;/a&gt; &lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;User clicks a link that has the transition-link attribute&lt;/li&gt;
&lt;li&gt;Download the page with $.ajax call and grab content (&amp;lt;div&amp;gt; with role="main" attribute)&lt;/li&gt;
&lt;li&gt;Slide out the old content, slide in our new content.&lt;/li&gt;
&lt;li&gt;Change the menu button highlight and URL.&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Page HTML Structure&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Setting up your pages to use transitions requires some plumbing hookup to specify what parts of the page are content and what links should load new content in. &amp;nbsp;In our case, we attach handlers for any link elements with a transition-link attribute, and we look for a div element with a role="main" attribute as our content area.&lt;/div&gt;&lt;br /&gt;
&lt;script src="https://gist.github.com/1039060.js"&gt;
 
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;&lt;b&gt;Retrieving The Other Page With jQuery&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;/div&gt;&lt;div&gt;When our page loads, we attach to all our transition links click events so we can load our other page with ajax instead of with a browser refresh.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;script src="https://gist.github.com/1039079.js"&gt;
 
&lt;/script&gt;&lt;br /&gt;
&lt;div&gt;You may notice that we are taking advantage of jQuery's new &lt;a href="http://api.jquery.com/category/deferred-object"&gt;$.Deferred object&lt;/a&gt; for the loadPage function. &amp;nbsp;This lets us specify callbacks for when the page is done loading, or if there is an error loading the other page.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;b&gt;Transitioning The Page Contents Out and In&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Once we've loaded the new page's contents, we're ready to start transitioning the old content out and slide the new content in. &amp;nbsp;To do this, I took advantage of the &lt;a href="http://jqueryui.com/docs/show/"&gt;jQuery UI Effects&lt;/a&gt; library and chained some call backs to insert the new content after we finish hiding the current content.&lt;/div&gt;&lt;br /&gt;
&lt;script src="https://gist.github.com/1039106.js"&gt;
 
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="gmail_quote" style="border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; margin-bottom: 0px; margin-left: 0.8ex; margin-right: 0px; margin-top: 0px; padding-left: 1ex;"&gt;&lt;b&gt;Bonus Points:&amp;nbsp;&lt;/b&gt;We get some bonus points here at the bottom for detecting CSS Transitions and using those instead. &amp;nbsp;The&amp;nbsp;&lt;a href="https://github.com/jquery/jquery-mobile/blob/master/themes/default/jquery.mobile.transitions.css"&gt;style for the CSS3 Transitions&lt;/a&gt;&amp;nbsp;can be found in the&amp;nbsp;&lt;a href="https://github.com/jquery/jquery-mobile"&gt;jQuery Mobile source on GitHub&lt;/a&gt;.&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;
A more styled fleshed out version of this concept can be found &lt;a href="http://dl.dropbox.com/u/9590085/demo/transitions/index.html"&gt;live on my DropBox account&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Now Playing&lt;/b&gt; - &lt;a href="http://www.youtube.com/watch?v=Ty0u1PzXfTo" target="_blank"&gt;Lupe Fiasco - Superstar&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Jacob4U2/~4/PWJWBhTQ20o" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jacob4u2.blogspot.com/feeds/9117839420096183145/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jacob4u2.blogspot.com/2011/06/anatomy-of-html5-page-transition.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/9117839420096183145?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/9117839420096183145?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Jacob4U2/~3/PWJWBhTQ20o/anatomy-of-html5-page-transition.html" title="Anatomy of an HTML5 Page Transition" /><author><name>Jacob Gable</name><uri>http://www.blogger.com/profile/06143537581139815312</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="27" src="http://2.bp.blogspot.com/_V6SpmG8I6qw/TJoxZU9swWI/AAAAAAAAANs/FKLAJ7MEDpw/S220/babyProfilePic1.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://jacob4u2.blogspot.com/2011/06/anatomy-of-html5-page-transition.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMGQXk4fCp7ImA9WhZWE0w.&quot;"><id>tag:blogger.com,1999:blog-7763566905460067738.post-6546977615713971354</id><published>2011-05-12T14:56:00.000-04:00</published><updated>2011-05-13T16:27:00.734-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-13T16:27:00.734-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="html5" /><title>HTML5 Dialog Element Styling For Pleasure and Profit</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="posterous_autopost"&gt;Recently I had a great opportunity to work on a small part of a Lync Powered Expert Question Answer Service. &amp;nbsp;My portion of the code was a simple one page HTML popup that allowed a person to chat with an expert.&lt;br /&gt;
&lt;div&gt;&lt;div&gt;One of the cool things I found out about during the project was the &lt;b&gt;&lt;a href="http://html5doctor.com/a-little-more-conversation-with-dialog/"&gt;HTML5 Dialog Element&lt;/a&gt;&lt;/b&gt;&lt;/div&gt;&lt;blockquote class="gmail_quote" style="border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; margin-bottom: 0px; margin-left: 0.8ex; margin-right: 0px; margin-top: 0px; padding-left: 1ex;"&gt;The&amp;nbsp;dialog&amp;nbsp;element&amp;nbsp;represents a conversation, meeting minutes, a chat transcript, a&amp;nbsp;dialog&amp;nbsp;in a screenplay, an instant message log, or some other construct in which different players take turns in discourse.&lt;/blockquote&gt;&lt;div&gt;Nifty, eh? &amp;nbsp;I use jquery to insert the root dialog element, then whenever a message is sent or received I inject the dt and dd elements. &amp;nbsp;Here is an example of what the conversation looks like in HTML&lt;/div&gt;&lt;br /&gt;
&lt;script src="https://gist.github.com/969169.js"&gt; &lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;By default, the browser will display this like this:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="p_embed p_image_embed"&gt;&lt;img alt="Defaultstyle" height="609" src="http://posterous.com/getfile/files.posterous.com/jacob4u2/PuH2ojvKYqwbVdC1tcJkKgpsQ8iZ6bR8vm2XNiIqthduuRoPkdkAQ5ZLzdEn/defaultstyle.png" width="386" /&gt; &lt;/div&gt;&lt;/div&gt;&lt;div&gt;Now that's kinda lame, I want it to look like a real chat screen (with some slick Metro UI Styling), so I added some CSS (take a look at the JSSFiddle CSS Tab for my styles) to hide the dt element and give it a nice blue bubble look. &amp;nbsp;I even added some nice CSS triangles into the mix for some minor speaker perspective.&lt;/div&gt;&lt;div&gt;&lt;div class="p_embed p_image_embed"&gt;&lt;img alt="Webchat" height="609" src="http://posterous.com/getfile/files.posterous.com/jacob4u2/J5RBVwfvVSzYiWRWNLzQYCTJoKgEulCpYfAiEp8cKurvJLFo8EbLIBHoCLCy/webchat.png" width="463" /&gt; &lt;/div&gt;&lt;/div&gt;&lt;div&gt;I've put up a &lt;a href="http://jsfiddle.net/jacob4u2/Q4EeR/"&gt;fully coded example with a boring chat bot&lt;/a&gt;&amp;nbsp;over at jsFiddle for you to enjoy and mess around with.&lt;/div&gt;&lt;div&gt;&lt;iframe style="width: 100%; height: 300px" src="http://jsfiddle.net/jacob4u2/Q4EeR/embedded/"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;b&gt;Now Playing&lt;/b&gt; - &lt;a href="http://www.youtube.com/watch?v=2omb_4O5DkQ"&gt;La Roux - In For The Kill (Skream Remix) [WTC Mashup]&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Jacob&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Jacob4U2/~4/MW44mFC1abQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jacob4u2.blogspot.com/feeds/6546977615713971354/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jacob4u2.blogspot.com/2011/05/html5-dialog-element-styling-for.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/6546977615713971354?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/6546977615713971354?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Jacob4U2/~3/MW44mFC1abQ/html5-dialog-element-styling-for.html" title="HTML5 Dialog Element Styling For Pleasure and Profit" /><author><name>Jacob Gable</name><uri>http://www.blogger.com/profile/06143537581139815312</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="27" src="http://2.bp.blogspot.com/_V6SpmG8I6qw/TJoxZU9swWI/AAAAAAAAANs/FKLAJ7MEDpw/S220/babyProfilePic1.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://jacob4u2.blogspot.com/2011/05/html5-dialog-element-styling-for.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMCSXs5eCp7ImA9WhZQFko.&quot;"><id>tag:blogger.com,1999:blog-7763566905460067738.post-197949877797012185</id><published>2011-04-24T16:33:00.008-04:00</published><updated>2011-04-24T16:37:48.520-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-24T16:37:48.520-04:00</app:edited><title>Roll your own Text Messaging Apps with Twilio and MVC 3</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="posterous_autopost"&gt;I've been messing around with &lt;a href="http://www.twilio.com/" target="_blank"&gt;Twilio&lt;/a&gt; and their awesome set of &lt;a href="http://www.twilio.com/docs/api/twiml/" target="_blank"&gt;TwiML API&lt;/a&gt;'s this weekend and made a fun little &lt;a href="https://github.com/jgable/TwilioSharp" target="_blank"&gt;C# Twilio library&lt;/a&gt; for creating simple text (and voice) based applications from MVC 3 sites.&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;&lt;b&gt;How Twilio's TwiML API Works&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="p_embed p_image_embed"&gt;&lt;br /&gt;
&lt;a href="http://posterous.com/getfile/files.posterous.com/jacob4u2/TZB7hwdo8xSPyq0SyZVlIm6BkWgNgqmhGImEN60mLIsx83Ymp4aFc1eIrxNT/Twilio-Overview.png"&gt;&lt;img alt="Twilio-overview" height="203" src="http://posterous.com/getfile/files.posterous.com/jacob4u2/J9lJ00bEpC2RZqT8pl876ZwDPOR3IT4sA7BcA6yM4ZqxmbuwWFS8WTHUauRU/Twilio-Overview.png.scaled.500.jpg" width="500" /&gt;&lt;/a&gt; &lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;An SMS comes in to one of your Twilio Phone Numbers.&lt;/div&gt;&lt;div&gt;Twilio Makes a POST or GET call to a URL you set up.&lt;/div&gt;&lt;div&gt;Your site provides a TwiML Response that Twilio parses and executes.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
(See Twilio's own&amp;nbsp;&lt;a href="http://www.twilio.com/how-twilio-works" target="_blank"&gt;how it works&lt;/a&gt;&amp;nbsp;page for a way better explanation.)&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Using TwilioSharp to Send TwiML Responses From MVC&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;script src="https://gist.github.com/939852.js"&gt;
 
&lt;/script&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
As part of my handy dandy &lt;a href="https://github.com/jgable/TwilioSharp#readme" target="_blank"&gt;TwilioSharp helper library&lt;/a&gt; I've created a base &lt;a href="https://github.com/jgable/TwilioSharp/blob/master/TwilioSharp.MVC3/Controllers/TwiMLController.cs" target="_blank"&gt;TwiML Controller&lt;/a&gt; for easily creating TwiML Responses with a &lt;a href="https://github.com/jgable/TwilioSharp/blob/master/TwilioSharp/TwiML/Builder.cs" target="_blank"&gt;Fluent TwiMLBuilder Class&lt;/a&gt;. &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
The TwiML Controller exposes a TwiML method that is meant to emulate the ease of use of the Json method available in all MVC Controllers. &amp;nbsp;The TwiML method takes a Func&amp;lt;TwiMLBuilder, TwiMLBuilder&amp;gt; that acts as your Response Factory method; this makes building complex responses easier by allowing for in line fluent declarations.&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Full Fledged Example&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
You can view a full fledged &lt;a href="https://github.com/jgable/8Ball-MVC-3-TwilioSharp-Example" target="_blank"&gt;Magic 8-Ball Answerizer 3000 example on GitHub&lt;/a&gt;&amp;nbsp;(which is also &lt;a href="http://8ball.apphb.com/" target="_blank"&gt;live on AppHarbor&lt;/a&gt; until I run out of money in my Twilio Account). &amp;nbsp;Including a more in depth example of &lt;a href="https://github.com/jgable/8Ball-MVC-3-TwilioSharp-Example/blob/master/8Ball/Controllers/CallController.cs" target="_blank"&gt;using the Fluent TwiMLBuilder for answering phone calls&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;script src="https://gist.github.com/939855.js"&gt;
 
&lt;/script&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="p_embed p_image_embed"&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://posterous.com/getfile/files.posterous.com/jacob4u2/MnZJgl2afYOR8G7jzyTqTpiMNHQqtr2wXwVCaBiSB4LzZrjGZdYpGqIWU8Lb/8BallApp.png"&gt;&lt;img alt="8ballapp" height="297" src="http://posterous.com/getfile/files.posterous.com/jacob4u2/dR0ukEDGb7eJMJOoZWUU7izd8APfV73ulmi5lDYfC6j1oy0DSR9iUj5KxhrK/8BallApp.png.scaled.500.jpg" width="500" /&gt;&lt;/a&gt; &lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;(&lt;a href="http://8ball.apphb.com/"&gt;The Magical 8-Ball Answerizer 3000 on AppHarbor&lt;/a&gt;)&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Now Playing&lt;/b&gt; - &lt;a href="http://www.youtube.com/watch?v=axLRUszuu9I" target="_blank"&gt;Tommy Tutone - 867-5309 / Jenny&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Jacob4U2/~4/AMY7stvDAPA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jacob4u2.blogspot.com/feeds/197949877797012185/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jacob4u2.blogspot.com/2011/04/roll-your-own-text-messaging-apps-with.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/197949877797012185?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/197949877797012185?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Jacob4U2/~3/AMY7stvDAPA/roll-your-own-text-messaging-apps-with.html" title="Roll your own Text Messaging Apps with Twilio and MVC 3" /><author><name>Jacob Gable</name><uri>http://www.blogger.com/profile/06143537581139815312</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="27" src="http://2.bp.blogspot.com/_V6SpmG8I6qw/TJoxZU9swWI/AAAAAAAAANs/FKLAJ7MEDpw/S220/babyProfilePic1.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://jacob4u2.blogspot.com/2011/04/roll-your-own-text-messaging-apps-with.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0YGRHcycCp7ImA9WhZRFkk.&quot;"><id>tag:blogger.com,1999:blog-7763566905460067738.post-7770059110470327730</id><published>2011-04-12T18:47:00.009-04:00</published><updated>2011-04-12T18:58:45.998-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-12T18:58:45.998-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mvc3" /><category scheme="http://www.blogger.com/atom/ns#" term="MVC" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="chat" /><category scheme="http://www.blogger.com/atom/ns#" term="push" /><category scheme="http://www.blogger.com/atom/ns#" term="longpoll" /><title>MVC 3 Long Polling / "Comet" Chat Example</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="posterous_autopost"&gt;I recently read a &lt;a href="http://clay.lenharts.net/blog/2010/10/19/websockets-is-cool-but-what-can-you-do-today/" target="_blank"&gt;great article on WebSocket alternatives in MVC&lt;/a&gt;&amp;nbsp;by &lt;a href="http://clay.lenharts.net/blog/" target="_blank"&gt;Clay Lenhart&lt;/a&gt;&amp;nbsp;and decided to write up a quick proof of concept &lt;b&gt;Chat Server Example&lt;/b&gt; for &lt;b&gt;.Net MVC&lt;/b&gt;. &amp;nbsp;Here is a quick run-down of what I did.&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
First, read up on &lt;a href="http://en.wikipedia.org/wiki/Comet_%28programming%29" target="_blank"&gt;Comet&lt;/a&gt;; a basic way to have real-time notifications sent to a browser (like push notifications). &amp;nbsp;One common Comet technique involves "Long Polling" an http connection. &amp;nbsp;What this means is that we call out to a URL that expects to wait around for a long time before something happens.&lt;/div&gt;&lt;div class="p_embed p_image_embed"&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;img alt="Pubsub_poll" height="232" src="http://posterous.com/getfile/files.posterous.com/jacob4u2/KDmSSWbJRuyITNSsKlbmMgSlhj39SBLpe8NkcxyOeLpqqQZx09p9OChfz9k4/PubSub_poll.jpg" width="496" /&gt; &lt;/div&gt;&lt;div class="p_embed p_image_embed"&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;img alt="Pubsub_longpoll" height="232" src="http://posterous.com/getfile/files.posterous.com/jacob4u2/Cahq0NruhhbcULrTTnuapobj2egqMjqDYf4B22fpxqdyvKn9VO84DTEHqiuo/PubSub_longpoll.jpg" width="496" /&gt; &lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
(images via &lt;a href="http://publib.boulder.ibm.com/infocenter/wasinfo/v6r1/index.jsp?topic=/com.ibm.websphere.ajax.devguide.help/docs/PureAjax_pubsub_clients.html" target="_blank"&gt;IBM WebSphere Ajax Dev Guide&lt;/a&gt;)&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;The Long Poll Chat Async Controller&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
The first step for the chat server was to create a new Async Controller (Async what? Check out this great introduction to &lt;a href="http://www.aaronstannard.com/post/2011/01/06/asynchonrous-controllers-ASPNET-mvc.aspx" target="_blank"&gt;Async Controllers&lt;/a&gt;) to handle our Long Poll requests. &amp;nbsp;Here is the ChatController I created:&lt;/div&gt;&lt;script src="https://gist.github.com/916519.js"&gt;
 
&lt;/script&gt;&lt;br /&gt;
&lt;div&gt;You can see that we've created our Index action as an Async that calls our to our ChatServer and checks for a message to arrive. &amp;nbsp;By default, I've specified a 60 second time limit before returning an empty list of messages, but you could theoretically let this go on for hours waiting for a response. &amp;nbsp;Once a response comes back from the ChatServer, we tell the AsyncManager we are done and return our messages in JSON form.&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;The ChatServer&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
I chose to use Observables and the Reactive (Rx) Framework to have a synchronized way of notifying all interested parties when a new message comes in. &amp;nbsp;To do this, I took advantage of the Subject&amp;lt;T&amp;gt; class that wraps a lot of the Observable and Observer implementation details. &amp;nbsp;To handle persisting my chat history, I use a simple Queue to keep the last 100 or so by default. &amp;nbsp;Whenever a new message comes in, I check the history length and pop off anything over the limit, then push in my new messages. &amp;nbsp;Yes, eventually I'd have to figure out a strategy for pushing this back to a database or &lt;a href="http://redis.io/"&gt;Redis&lt;/a&gt; cache server thingy but this is just a demo, so relax.&lt;/div&gt;&lt;script src="https://gist.github.com/916526.js"&gt;
 
&lt;/script&gt;&lt;br /&gt;
&lt;div&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;The Client Side (HTML and JS)&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
On the client side, we need to take advantage of some of jQuery's helper methods for POSTing to an MVC Action (the Index Action on the Chat Controller in our case). &amp;nbsp;We are going to make a POST call to /Chat that will sit around until a new message arrives, or our 60 second timeout is reached. &amp;nbsp;If a new message comes in, our POST call will return immediately with the new message(s). &amp;nbsp;From there, we just insert them into our current chat history.&lt;/div&gt;&lt;script src="https://gist.github.com/916560.js?file=ChatView.cshtml"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;div&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;See It In Action&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;/b&gt;&lt;br /&gt;
&lt;div class="p_embed p_image_embed"&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;a href="http://posterous.com/getfile/files.posterous.com/jacob4u2/19PYNi7WMh6cWdVokq2FOYjSIlIbIYll4FLb3TEVTC2mNUuUHBKdfoEZzbMh/Example.png"&gt;&lt;img alt="Example" height="480" src="http://posterous.com/getfile/files.posterous.com/jacob4u2/RcVeBiwT3ZALWwejzW3X2RP5moT6SDpcX3l0W9wNwYcG8N281ku1KKcnvcoc/Example.png.scaled.500.jpg" width="500" /&gt;&lt;/a&gt; &lt;/b&gt;&lt;/div&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
I've uploaded the &lt;a href="http://mvcchatsite.apphb.com/"&gt;MVC Chat Example&lt;/a&gt; to &lt;a href="http://www.appharbor.com/"&gt;AppHarbor&lt;/a&gt; for people to play around with. &amp;nbsp;You can also &lt;a href="http://dl.dropbox.com/u/9590085/BlogFiles/MVCChatSite.zip"&gt;download the sample project&lt;/a&gt; from my dropbox account, or &lt;a href="https://bitbucket.org/jacob4u2/mvcchatsite/src/b86a384d8bef/MVCChatSite/"&gt;view the source&lt;/a&gt; at the &lt;a href="https://bitbucket.org/jacob4u2/mvcchatsite"&gt;MVCChatSite&lt;/a&gt; Project page on BitBucket.&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Now Playing&lt;/b&gt; - &lt;a href="http://www.youtube.com/watch?v=d6mN-GaTNUM&amp;amp;NR=1"&gt;The Glitch Mob - Drive It Like You Stole It&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Jacob4U2/~4/_HsdY6cWW1A" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jacob4u2.blogspot.com/feeds/7770059110470327730/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jacob4u2.blogspot.com/2011/04/mvc-3-long-polling-chat-example.html#comment-form" title="9 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/7770059110470327730?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/7770059110470327730?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Jacob4U2/~3/_HsdY6cWW1A/mvc-3-long-polling-chat-example.html" title="MVC 3 Long Polling / &amp;quot;Comet&amp;quot; Chat Example" /><author><name>Jacob Gable</name><uri>http://www.blogger.com/profile/06143537581139815312</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="27" src="http://2.bp.blogspot.com/_V6SpmG8I6qw/TJoxZU9swWI/AAAAAAAAANs/FKLAJ7MEDpw/S220/babyProfilePic1.jpg" /></author><thr:total>9</thr:total><feedburner:origLink>http://jacob4u2.blogspot.com/2011/04/mvc-3-long-polling-chat-example.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU4EQnc_cCp7ImA9WhZSEEs.&quot;"><id>tag:blogger.com,1999:blog-7763566905460067738.post-9138088313742138630</id><published>2011-03-25T09:48:00.002-04:00</published><updated>2011-03-25T10:38:23.948-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-25T10:38:23.948-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="WinPhone7" /><category scheme="http://www.blogger.com/atom/ns#" term="mvc3" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="Hackatopia" /><title>Hackatopia - MVC 3 JSON Services &amp; WP7</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="posterous_autopost"&gt;Here's a list of resources for my talk at &lt;a href="http://hackatopia.com/Events/Windows-Phone-7"&gt;Hackatopia on March 26&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;Sample Project - &lt;a href="http://dl.dropbox.com/u/9590085/BlogFiles/Hackatopia-JSONPhoneApp1.zip"&gt;JSONPhoneApp1&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Links&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;a href="https://gist.github.com/883267"&gt;TeamRepository&lt;/a&gt; - For Some Test Data&lt;/div&gt;&lt;div&gt;&lt;a href="https://gist.github.com/884284"&gt;TeamController&lt;/a&gt;&amp;nbsp;- For return our test data in JSON&lt;/div&gt;&lt;div&gt;&lt;a href="https://gist.github.com/881673"&gt;JsonService&lt;/a&gt; - For consuming/serializing JSON objects in Win Phone 7&lt;/div&gt;&lt;div&gt;&lt;a href="https://gist.github.com/883810"&gt;MVVMCommon&lt;/a&gt; - A set of common MVVM Classes&lt;/div&gt;&lt;div&gt;&lt;a href="https://gist.github.com/886012"&gt;TeamWP7&lt;/a&gt; - All the VM's and Services for Consuming our test data&lt;/div&gt;&lt;div&gt;&lt;a href="https://gist.github.com/881700"&gt;Postifier&lt;/a&gt; - Turn an object into a URL Encoded string&lt;/div&gt;&lt;div&gt;&lt;a href="https://chrome.google.com/extensions/detail/chklaanhfefbnpoihckbnefhakgolnmc"&gt;JSONView&lt;/a&gt; - A Chrome Extension for pretty printing JSON.&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;iframe frameborder="0" height="560px" src="https://docs.google.com/viewer?a=v&amp;amp;pid=explorer&amp;amp;chrome=false&amp;amp;embedded=true&amp;amp;srcid=0B3I6x2xajNzSNzJjMDQ4OTMtOWFlMS00MDNmLTgxZjQtOWI2ZmMyZWFkZGJl&amp;amp;hl=en" width="100%"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Jacob4U2/~4/Z2FtXWl3ikY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jacob4u2.blogspot.com/feeds/9138088313742138630/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jacob4u2.blogspot.com/2011/03/hackatopia-mvc-3-json-services-wp7.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/9138088313742138630?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/9138088313742138630?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Jacob4U2/~3/Z2FtXWl3ikY/hackatopia-mvc-3-json-services-wp7.html" title="Hackatopia - MVC 3 JSON Services &amp;amp; WP7" /><author><name>Jacob Gable</name><uri>http://www.blogger.com/profile/06143537581139815312</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="27" src="http://2.bp.blogspot.com/_V6SpmG8I6qw/TJoxZU9swWI/AAAAAAAAANs/FKLAJ7MEDpw/S220/babyProfilePic1.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://jacob4u2.blogspot.com/2011/03/hackatopia-mvc-3-json-services-wp7.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0YNQno6fSp7ImA9WhZTGU8.&quot;"><id>tag:blogger.com,1999:blog-7763566905460067738.post-7843732776566990394</id><published>2011-03-23T21:13:00.001-04:00</published><updated>2011-03-23T21:13:13.415-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-23T21:13:13.415-04:00</app:edited><title>Gist4u2 - NuGet Console Utilities for Gists</title><content type="html">&lt;div class='posterous_autopost'&gt;Not many people know this, but I&amp;#39;m actually a &lt;a href="http://thepowershellguy.com/blogs/posh/archive/2007/02/19/scripting-games-2007-advanced-powershell-scores-list.aspx"&gt;powershell ninja from waaayyyy back&lt;/a&gt; &lt;p /&gt;&lt;div&gt;&lt;div class='p_embed p_image_embed'&gt; &lt;a href="http://posterous.com/getfile/files.posterous.com/jacob4u2/oikBJvZzmU8xgn4ePPCPyLTBQfQ9T0lBDJSw2dw8W2YmvwlEJvmlEbKlwks9/ScriptingGames2007.png"&gt;&lt;img alt="Scriptinggames2007" height="193" src="http://posterous.com/getfile/files.posterous.com/jacob4u2/zPKKYUY3n52Pt4bamC5RQXnWZbsJ3JMp9N2pLaERG8WzPAGqQkLKqzZG7lwL/ScriptingGames2007.png.scaled.500.jpg" width="500" /&gt;&lt;/a&gt; &lt;/div&gt; &lt;br /&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;(that&amp;#39;s me in the scoring list, third from the top)&lt;/div&gt;&lt;p /&gt;&lt;div&gt;So when I first started &lt;a href="http://jalpesh.blogspot.com/2011/01/installing-nuget-package-with-package.html"&gt;playing around with the NuGet Package Manager Console&lt;/a&gt; I was quite impressed with the opportunities it presented.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;Flash forward to today and I&amp;#39;m preparing for a presentation in an upcoming &lt;a href="http://hackatopia.com/Events/Windows-Phone-7"&gt;Chicago Hackatopia Win Phone 7 event&lt;/a&gt; where I find myself storing a lot of my code snippets for my presentation in &lt;a href="http://gist.github.com"&gt;Gists&lt;/a&gt;.  That&amp;#39;s when I got the idea for &lt;a href="http://nuget.org/List/Packages/Gist4u2"&gt;Gist4u2&lt;/a&gt;; a handy way to insert gists into your code.  &lt;/div&gt; &lt;p /&gt;&lt;div&gt;So far, it&amp;#39;s been pretty useful for my demonstrations.  Here is a quick example of how I use it.  Let&amp;#39;s say I&amp;#39;m starting a new Windows Phone 7 project and I want to add some basic MVVM fundamental code like a ViewModelBase and Commanding classes (DelegateCommand, EventToCommand behavior).&lt;/div&gt; &lt;p /&gt;&lt;div&gt;Start a new Win Phone 7 Project, Open the Package Manager Console from the Tools -&amp;gt; Library Package Manager Menu (if you don&amp;#39;t have it, Install &lt;a href="http://visualstudiogallery.msdn.microsoft.com/27077b70-9dad-4c64-adcf-c7cf6bc9970c"&gt;NuGet through the extension manager&lt;/a&gt;)&lt;/div&gt; &lt;p /&gt;&lt;div&gt;&lt;div class='p_embed p_image_embed'&gt; &lt;a href="http://posterous.com/getfile/files.posterous.com/jacob4u2/XEYv5SVRzQrgmGY9FviHQatK67vBukaCv5gfSXu2oJ9ZRoMKN1zdhJzkITz2/PackagerManagerConsole.png"&gt;&lt;img alt="Packagermanagerconsole" height="331" src="http://posterous.com/getfile/files.posterous.com/jacob4u2/AXjWWS7P92PXBCi5yLzKS1ryvDmkwIWAJiASoIiwGHqn8qBwEqwabZXAjtSx/PackagerManagerConsole.png.scaled.500.jpg" width="500" /&gt;&lt;/a&gt; &lt;/div&gt; &lt;/div&gt;&lt;p /&gt;&lt;div&gt;Next, install the Gist4u2 package to add the helper commands into the Console&lt;/div&gt; &lt;p /&gt;&lt;div&gt;&lt;div class='p_embed p_image_embed'&gt; &lt;a href="http://posterous.com/getfile/files.posterous.com/jacob4u2/4JK3jwiAlFI97dffr9l86C9o7tyQii8iSezEXhFMuZ3CmMwZFsDooBgts4zf/Install-List-Gists.png"&gt;&lt;img alt="Install-list-gists" height="219" src="http://posterous.com/getfile/files.posterous.com/jacob4u2/L0fhigfgVYQhnmldEEsjQIzAhS38ZbjChLobtjIu18RvLwP46xLPxvyjr0L6/Install-List-Gists.png.scaled.500.jpg" width="500" /&gt;&lt;/a&gt; &lt;/div&gt; &lt;br /&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;Notice the last Gist there, the 883810, that&amp;#39;s what I want.  So I create a new file (hopefully in the future I can create them for you in the project) called MVVMCommon and type &lt;b&gt;Gist-Insert &amp;#39;883810&amp;#39;&lt;/b&gt; to insert the &lt;a href="https://gist.github.com/883810"&gt;contents of my MVVMCommon Gist&lt;/a&gt;.&lt;/div&gt; &lt;p /&gt;&lt;div&gt;&lt;div class='p_embed p_image_embed'&gt; &lt;a href="http://posterous.com/getfile/files.posterous.com/jacob4u2/03QgRUKSNu8gkeeg93fTh6LsD55qnMOHZBE99h3VgzP9fihsWHZBQT43mFwQ/Gist-Insert.png"&gt;&lt;img alt="Gist-insert" height="287" src="http://posterous.com/getfile/files.posterous.com/jacob4u2/a1Roxvn2fFKIQCxjpva7Sa72v6CIMwM3vR2G05X98c9oJMlxW4ZB0Dgeahwl/Gist-Insert.png.scaled.500.jpg" width="500" /&gt;&lt;/a&gt; &lt;/div&gt; &lt;br /&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;Bam!  That&amp;#39;s it.  Now we have a &lt;a href="https://gist.github.com/883810"&gt;ViewModelBase and DelegateCommand&lt;/a&gt; ready to use in our Windows Phone 7 project.  Now my presentation is going to be much quicker.&lt;/div&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Jacob4U2/~4/5DOVCwj9jKA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jacob4u2.blogspot.com/feeds/7843732776566990394/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jacob4u2.blogspot.com/2011/03/gist4u2-nuget-console-utilities-for.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/7843732776566990394?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/7843732776566990394?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Jacob4U2/~3/5DOVCwj9jKA/gist4u2-nuget-console-utilities-for.html" title="Gist4u2 - NuGet Console Utilities for Gists" /><author><name>Jacob Gable</name><uri>http://www.blogger.com/profile/06143537581139815312</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="27" src="http://2.bp.blogspot.com/_V6SpmG8I6qw/TJoxZU9swWI/AAAAAAAAANs/FKLAJ7MEDpw/S220/babyProfilePic1.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://jacob4u2.blogspot.com/2011/03/gist4u2-nuget-console-utilities-for.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkADSXk6eip7ImA9WhZTF08.&quot;"><id>tag:blogger.com,1999:blog-7763566905460067738.post-5123239111429787679</id><published>2011-03-21T13:19:00.002-04:00</published><updated>2011-03-21T13:32:58.712-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-21T13:32:58.712-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mvc3" /><category scheme="http://www.blogger.com/atom/ns#" term="MVC" /><category scheme="http://www.blogger.com/atom/ns#" term="html5" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="boilerplate" /><title>HTML5 Boilerplate MVC 3 Site with AppHarbor in 3 Easy Steps</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="posterous_autopost"&gt;Here's a quick way to get a new &lt;a href="http://www.asp.net/mvc/mvc3"&gt;.Net MVC 3&lt;/a&gt; site up quickly that incorporates &lt;a href="http://html5boilerplate.com/"&gt;HTML5 Boilerplate&lt;/a&gt; patterns and practices.&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;&lt;b&gt;Step 0: Get Git (If you don't have it)&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
Git for Windows is available from the &lt;a href="http://code.google.com/p/msysgit/downloads/list" target="_blank"&gt;msysgit repository on Google Code&lt;/a&gt;; this guide was written for the &lt;a href="http://code.google.com/p/msysgit/downloads/detail?name=Git-1.7.4-preview20110204.exe&amp;amp;can=2&amp;amp;q=" target="_blank"&gt;1.7.4 preview version&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
There's even a &lt;a href="http://www.geekgumbo.com/2010/04/09/installing-git-on-windows/"&gt;guide for installing on windows&lt;/a&gt; if you need some help.&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Step 1: &amp;nbsp;Create Your AppHarbor Project&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
Go the the &lt;a href="http://appharbor.com/"&gt;AppHarbor&lt;/a&gt; home page and &lt;a href="https://appharbor.com/account/new"&gt;create a new account&lt;/a&gt; if you haven't done so yet. &amp;nbsp;Then click the &lt;a href="https://appharbor.com/application/new"&gt;Create New&lt;/a&gt;&amp;nbsp;link on the &lt;a href="https://appharbor.com/application"&gt;Applications&lt;/a&gt; tab to get started.&lt;/div&gt;&lt;div&gt;&lt;div class="p_embed p_image_embed"&gt;&lt;br /&gt;
&lt;img alt="Newapp" height="331" src="http://posterous.com/getfile/files.posterous.com/jacob4u2/iszMTLusvfgZZeuiWDl7WcKhooTrTSWMEvcHeHv6aL7qFHcCa8hP6vVmslAS/NewApp.png" width="462" /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
Once you've got your application created, copy the Repository URL so you can push your source up to your new site.&lt;/div&gt;&lt;div&gt;&lt;div class="p_embed p_image_embed"&gt;&lt;br /&gt;
&lt;a href="http://posterous.com/getfile/files.posterous.com/jacob4u2/OyzzwThGP8J7BUFDFo7f4ny9382uzN8bzks6xn7802LPqV0L4QrM9zjyeZbs/GitLink.png"&gt;&lt;img alt="Gitlink" height="238" src="http://posterous.com/getfile/files.posterous.com/jacob4u2/5QfwkKxuZryJBAsG5PRfRGXOknyHlyuaONSpBSU2NewwCjfX8KEtDYytIL0i/GitLink.png.scaled.500.jpg" width="500" /&gt;&lt;/a&gt; &lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;b&gt;Step 2: &amp;nbsp;Create Your MotherEffin HTML5 MVC 3 Site Project&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
I've created a super easy HTML5 Boilerplate MVC 3 template project that can deploy to AppHarbor with no modifications. &amp;nbsp;You can get it from the Visual Studio Extension gallery, or through the new project dialog by clicking the Online tab item on the left and searching for "HTML5".&lt;/div&gt;&lt;div&gt;&lt;div class="p_embed p_image_embed"&gt;&lt;br /&gt;
&lt;a href="http://posterous.com/getfile/files.posterous.com/jacob4u2/NuXZobIDkUrMmgXn3dxGr6aUBzwFNVOI3imKWPnuqMtpDqd5pZdEyvqdIO4f/HTML5ProjectTemplate.png.scaled.1000.jpg"&gt;&lt;img alt="Html5projecttemplate" height="305" src="http://posterous.com/getfile/files.posterous.com/jacob4u2/T8hj9WSNu5wQI5flIIcVoiGJPfgWFkHz4zpWJpA3OMp4g5AIVTveDxGW91vF/HTML5ProjectTemplate.png.scaled.500.jpg" width="500" /&gt;&lt;/a&gt; &lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Make a note of your project location so we can use the Git Bash shell to push our source.&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;
Step 3: Push it to AppHarbor with Git&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
Once you've got your project all set up and ready to deploy, navigate to your project's location, right click on the root directory and select "Git Bash Here".&lt;/div&gt;&lt;div&gt;Enter the following commands to initialize your new Git Repository&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;span style="color: #444444; font-family: Calibri, sans-serif; font-size: 16px; line-height: 19px;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;ol style="background-color: transparent; border-bottom-width: 0px; border-color: initial; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; font-size: 16px; margin-bottom: 0px; margin-left: 30px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;li style="background-color: transparent; border-bottom-width: 0px; border-color: initial; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; font-size: 16px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;span style="color: #444444; font-family: Calibri, sans-serif; font-size: 16px; line-height: 19px;"&gt; &lt;code style="background-color: transparent; border-bottom-width: 0px; border-color: initial; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; font-family: Consolas, monospace, sans-serif; font-size: 16px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;git init&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;span style="color: #444444; font-size: 16px; line-height: 19px;"&gt;
&lt;li style="background-color: transparent; border-bottom-width: 0px; border-color: initial; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; font-family: Calibri, sans-serif; font-size: 16px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt; &lt;code style="background-color: transparent; border-bottom-width: 0px; border-color: initial; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; font-family: Consolas, monospace, sans-serif; font-size: 16px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;git add .&lt;/code&gt;&lt;/li&gt;
&lt;li style="background-color: transparent; border-bottom-width: 0px; border-color: initial; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; font-family: Calibri, sans-serif; font-size: 16px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt; &lt;code style="background-color: transparent; border-bottom-width: 0px; border-color: initial; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; font-family: Consolas, monospace, sans-serif; font-size: 16px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;git commit -m "initial check in"&lt;/code&gt;&lt;/li&gt;
&lt;/span&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;
Once you have your files committed locally, you are ready to push up to the AppHarbor Git Repository Url. &lt;br /&gt;
&lt;br /&gt;
Here are examples of the commands to do that:&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="color: #444444; font-family: Calibri, sans-serif; font-size: 16px; line-height: 19px;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;ol style="background-color: transparent; border-bottom-width: 0px; border-color: initial; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; font-size: 16px; margin-bottom: 0px; margin-left: 30px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;li style="background-color: transparent; border-bottom-width: 0px; border-color: initial; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; font-size: 16px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;span style="color: #444444; font-family: Calibri, sans-serif; font-size: 16px; line-height: 19px;"&gt; &lt;code style="background-color: transparent; border-bottom-width: 0px; border-color: initial; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; font-family: Consolas, monospace, sans-serif; font-size: 16px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;git remote add appharbor [YourSiteRepositoryUrl]&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;span style="color: #444444; font-family: Calibri, sans-serif; font-size: 16px; line-height: 19px;"&gt;
&lt;li style="background-color: transparent; border-bottom-width: 0px; border-color: initial; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; font-size: 16px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt; &lt;code style="background-color: transparent; border-bottom-width: 0px; border-color: initial; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; font-family: Consolas, monospace, sans-serif; font-size: 16px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;git push appharbor master&lt;/code&gt;&lt;/li&gt;
&lt;/span&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div class="p_embed p_image_embed"&gt;&lt;br /&gt;
&lt;a href="http://posterous.com/getfile/files.posterous.com/jacob4u2/qBv6ACwkViNg5kwY4SAqUX4tKeStY7FvmtctUiNMKBlMXezKzaAzMKsWl5Vp/GitBashHere.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img alt="Gitbashhere" height="251" src="http://posterous.com/getfile/files.posterous.com/jacob4u2/Ch4rud6Q2A7S8CXfoBobEBB04fcTlOsVrSdjjMsipXmmvrqDFdpzQm0NXoWZ/GitBashHere.png.scaled.500.jpg" width="500" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://posterous.com/getfile/files.posterous.com/jacob4u2/L76CgcgShdVhV6kNKpCly6vR0OdHfGZ9NEFdJ1jeTbfOV0luSiAxfLfS2M9J/GitInitApp.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img alt="Gitinitapp" height="294" src="http://posterous.com/getfile/files.posterous.com/jacob4u2/F580sIrC9NYLOA0LhvFKs0gqoBOXXJl1WUPvBZFtqEmdeMfslOPirgaAJt9S/GitInitApp.png.scaled.500.jpg" width="500" /&gt;&lt;/a&gt;&lt;a href="http://posterous.com/getfile/files.posterous.com/jacob4u2/wsshqiczhak52KshYKQj629s27KGqFy5VvkHgVyxokBX7cbRuPbSJJn7IyB5/GitPushApp.png"&gt;&lt;img alt="Gitpushapp" height="291" src="http://posterous.com/getfile/files.posterous.com/jacob4u2/MSjlIObJx6jgJes7lM2E7byrysh7aCOs03Ho7cToH0g5uRUaCZhPGu56XjDb/GitPushApp.png.scaled.500.jpg" width="500" /&gt;&lt;/a&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;b&gt;Enjoy Your Site&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
Congratulations, you've just deployed your first HTML5 website.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
Now all you have to do is navigate to your app's url; i.e&amp;nbsp;&lt;a href="http://best-site-evar.apphb.com/" target="_blank"&gt;http://best-site-evar.apphb.com&lt;/a&gt;. &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
Next step, add a database and add the code first entity framework NuGet package for fast database scaffolding. &amp;nbsp;Hopefully I'll get a tutorial up for that soon.&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Now Playing&lt;/b&gt; - &lt;a href="http://www.youtube.com/watch?v=pBUxuyYC96o"&gt;Kanye West ft. Rihanna - All of the Lights&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="p_see_full_gallery"&gt;&lt;a href="http://jacob4u2.posterous.com/html5-boilerplate-mvc-3-site-with-appharbor-i"&gt;See the full gallery on Posterous&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Jacob4U2/~4/-XBz_ixEAwE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jacob4u2.blogspot.com/feeds/5123239111429787679/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jacob4u2.blogspot.com/2011/03/html5-boilerplate-mvc-3-site-with.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/5123239111429787679?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/5123239111429787679?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Jacob4U2/~3/-XBz_ixEAwE/html5-boilerplate-mvc-3-site-with.html" title="HTML5 Boilerplate MVC 3 Site with AppHarbor in 3 Easy Steps" /><author><name>Jacob Gable</name><uri>http://www.blogger.com/profile/06143537581139815312</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="27" src="http://2.bp.blogspot.com/_V6SpmG8I6qw/TJoxZU9swWI/AAAAAAAAANs/FKLAJ7MEDpw/S220/babyProfilePic1.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://jacob4u2.blogspot.com/2011/03/html5-boilerplate-mvc-3-site-with.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0YHR388fyp7ImA9Wx9aFUk.&quot;"><id>tag:blogger.com,1999:blog-7763566905460067738.post-1412050069268970083</id><published>2011-03-07T20:50:00.002-05:00</published><updated>2011-03-07T20:52:16.177-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-07T20:52:16.177-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="WPF" /><category scheme="http://www.blogger.com/atom/ns#" term="silverlight" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><title>DataGrid Column Header Binding Behavior</title><content type="html">&lt;div class='posterous_autopost'&gt;&lt;p&gt;I ran into a problem binding a &lt;b&gt;localized string&lt;/b&gt; to a &lt;b&gt;Silverlight 4 DataGrid Column Header&lt;/b&gt;, it turns out the Header property on a &lt;b&gt;DataGridTextColumn&lt;/b&gt; isn&amp;#39;t a dependency property and so it doesn&amp;#39;t support binding.  This behavior will let you bind a value to the header.&lt;/p&gt;&lt;p /&gt;&lt;script src="https://gist.github.com/859686.js"&gt; &lt;/script&gt;&lt;br /&gt;
&lt;div&gt;Hope that helps someone else out who may be trying to localize their application.&lt;/div&gt;&lt;p /&gt;&lt;div&gt;Jacob &lt;/div&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Jacob4U2/~4/deXxpV8-Exg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jacob4u2.blogspot.com/feeds/1412050069268970083/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jacob4u2.blogspot.com/2011/03/datagrid-column-header-binding-behavior.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/1412050069268970083?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/1412050069268970083?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Jacob4U2/~3/deXxpV8-Exg/datagrid-column-header-binding-behavior.html" title="DataGrid Column Header Binding Behavior" /><author><name>Jacob Gable</name><uri>http://www.blogger.com/profile/06143537581139815312</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="27" src="http://2.bp.blogspot.com/_V6SpmG8I6qw/TJoxZU9swWI/AAAAAAAAANs/FKLAJ7MEDpw/S220/babyProfilePic1.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://jacob4u2.blogspot.com/2011/03/datagrid-column-header-binding-behavior.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0ENSX85cCp7ImA9Wx9bGUw.&quot;"><id>tag:blogger.com,1999:blog-7763566905460067738.post-3588261035967380156</id><published>2011-02-28T11:46:00.002-05:00</published><updated>2011-02-28T11:48:18.128-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-28T11:48:18.128-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="xaml" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="behaviors" /><title>Silverlight 4 TextBox Update Source on Text Changed Behavior</title><content type="html">&lt;div class='posterous_autopost'&gt;Here is a simple little behavior for updating a &lt;b&gt;TextBox&lt;/b&gt;&amp;#39;s &lt;b&gt;Text&lt;/b&gt; property in &lt;b&gt;Silverlight &lt;/b&gt;when the text changes instead of when it loses focus.&lt;p /&gt;&lt;script src="https://gist.github.com/847504.js"&gt; &lt;/script&gt;&lt;br /&gt;
&lt;div&gt;Quick and Easy.  Gotta Love Behaviors.&lt;/div&gt;&lt;p /&gt;&lt;div&gt;Jacob&lt;/div&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Jacob4U2/~4/phGaQWjVry8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jacob4u2.blogspot.com/feeds/3588261035967380156/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jacob4u2.blogspot.com/2011/02/silverlight-4-textbox-update-source-on.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/3588261035967380156?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/3588261035967380156?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Jacob4U2/~3/phGaQWjVry8/silverlight-4-textbox-update-source-on.html" title="Silverlight 4 TextBox Update Source on Text Changed Behavior" /><author><name>Jacob Gable</name><uri>http://www.blogger.com/profile/06143537581139815312</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="27" src="http://2.bp.blogspot.com/_V6SpmG8I6qw/TJoxZU9swWI/AAAAAAAAANs/FKLAJ7MEDpw/S220/babyProfilePic1.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://jacob4u2.blogspot.com/2011/02/silverlight-4-textbox-update-source-on.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0EMSX4_fCp7ImA9Wx9bFUU.&quot;"><id>tag:blogger.com,1999:blog-7763566905460067738.post-8749689160185644556</id><published>2011-02-24T16:05:00.002-05:00</published><updated>2011-02-24T16:08:08.044-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-24T16:08:08.044-05:00</app:edited><title>Silverlight 4 DropDropBehavior and FileDragDropBehavior with Command Binding</title><content type="html">&lt;div class='posterous_autopost'&gt;Here is an easy to use &lt;b&gt;FileDragDropBehavior&lt;/b&gt; that you can use in your &lt;b&gt;XAML&lt;/b&gt; to implement dragging and dropping of files in your &lt;b&gt;Silverlight 4&lt;/b&gt; Application&lt;p /&gt;&lt;script src="https://gist.github.com/842877.js"&gt; &lt;/script&gt;&lt;br /&gt;
&lt;p /&gt;&lt;div&gt;Just put the class in your project, reference the namespace in your XAML file and add the behavior to where you want to drop a file.&lt;/div&gt;&lt;p /&gt;&lt;div&gt;Jacob&lt;/div&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Jacob4U2/~4/2TsRQ17TrgM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jacob4u2.blogspot.com/feeds/8749689160185644556/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jacob4u2.blogspot.com/2011/02/silverlight-4-dropdropbehavior-and.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/8749689160185644556?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/8749689160185644556?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Jacob4U2/~3/2TsRQ17TrgM/silverlight-4-dropdropbehavior-and.html" title="Silverlight 4 DropDropBehavior and FileDragDropBehavior with Command Binding" /><author><name>Jacob Gable</name><uri>http://www.blogger.com/profile/06143537581139815312</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="27" src="http://2.bp.blogspot.com/_V6SpmG8I6qw/TJoxZU9swWI/AAAAAAAAANs/FKLAJ7MEDpw/S220/babyProfilePic1.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://jacob4u2.blogspot.com/2011/02/silverlight-4-dropdropbehavior-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMCRnY7eSp7ImA9Wx9bFUo.&quot;"><id>tag:blogger.com,1999:blog-7763566905460067738.post-4174633806142312956</id><published>2011-02-24T14:38:00.002-05:00</published><updated>2011-02-24T14:41:07.801-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-24T14:41:07.801-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="WPF" /><category scheme="http://www.blogger.com/atom/ns#" term="silverlight" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><title>CheckedItemCollection for Silverlight and WPF CheckBox List or RadioButton List</title><content type="html">&lt;div class='posterous_autopost'&gt;Here is a simple class for wrapping a list of items so they can be checked from a list.  There are some helper methods like &lt;b&gt;CheckAll&lt;/b&gt;,&lt;b&gt; UnCheckAll&lt;/b&gt;, and &lt;b&gt;CheckWhere&lt;/b&gt; that I&amp;#39;ve found useful in my projects.&lt;p /&gt;&lt;script src="https://gist.github.com/842689.js?file=CheckedItemCollection.cs"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;p /&gt;&lt;div&gt;Then when you are done and need to get the checked items you can use the handy &lt;b&gt;CheckedItems &lt;/b&gt;property.&lt;/div&gt;&lt;p /&gt;&lt;p /&gt;&lt;div&gt;Jacob&lt;/div&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Jacob4U2/~4/jycHVQMa7VQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jacob4u2.blogspot.com/feeds/4174633806142312956/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jacob4u2.blogspot.com/2011/02/checkeditemcollection-for-silverlight.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/4174633806142312956?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/4174633806142312956?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Jacob4U2/~3/jycHVQMa7VQ/checkeditemcollection-for-silverlight.html" title="CheckedItemCollection for Silverlight and WPF CheckBox List or RadioButton List" /><author><name>Jacob Gable</name><uri>http://www.blogger.com/profile/06143537581139815312</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="27" src="http://2.bp.blogspot.com/_V6SpmG8I6qw/TJoxZU9swWI/AAAAAAAAANs/FKLAJ7MEDpw/S220/babyProfilePic1.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://jacob4u2.blogspot.com/2011/02/checkeditemcollection-for-silverlight.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE4DRHc9cSp7ImA9Wx9bFE0.&quot;"><id>tag:blogger.com,1999:blog-7763566905460067738.post-6525711978460741284</id><published>2011-02-22T14:21:00.002-05:00</published><updated>2011-02-22T14:29:35.969-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-22T14:29:35.969-05:00</app:edited><title>ClickCommandTrigger based on MVVMLight EventToCommand TriggerAction</title><content type="html">&lt;div class='posterous_autopost'&gt;Here is a simple &lt;b&gt;ClickCommandTrigger&lt;/b&gt; based on the &lt;a href="http://mvvmlight.codeplex.com"&gt;MVVMLight&lt;/a&gt; &lt;b&gt;EventToCommand&lt;/b&gt; &lt;b&gt;TriggerAction&lt;/b&gt;.  This will make it a little easier to run an MVVMLight command trigger for a simple button click.&lt;br /&gt;
&lt;p /&gt;&lt;div&gt;&lt;script src="https://gist.github.com/839154.js?file=EventToCommandTrigger.cs"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Gotta love triggers.&lt;/div&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Jacob4U2/~4/3_QfnqDRXcc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jacob4u2.blogspot.com/feeds/6525711978460741284/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jacob4u2.blogspot.com/2011/02/clickcommandtrigger-based-on-mvvmlight.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/6525711978460741284?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/6525711978460741284?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Jacob4U2/~3/3_QfnqDRXcc/clickcommandtrigger-based-on-mvvmlight.html" title="ClickCommandTrigger based on MVVMLight EventToCommand TriggerAction" /><author><name>Jacob Gable</name><uri>http://www.blogger.com/profile/06143537581139815312</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="27" src="http://2.bp.blogspot.com/_V6SpmG8I6qw/TJoxZU9swWI/AAAAAAAAANs/FKLAJ7MEDpw/S220/babyProfilePic1.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://jacob4u2.blogspot.com/2011/02/clickcommandtrigger-based-on-mvvmlight.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEQDQXk5eip7ImA9Wx9bEkk.&quot;"><id>tag:blogger.com,1999:blog-7763566905460067738.post-6535971477017692418</id><published>2011-02-20T18:59:00.000-05:00</published><updated>2011-02-20T18:59:30.722-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-20T18:59:30.722-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="mvvm" /><category scheme="http://www.blogger.com/atom/ns#" term="MVC" /><category scheme="http://www.blogger.com/atom/ns#" term="html5" /><category scheme="http://www.blogger.com/atom/ns#" term="knockoutjs" /><title /><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;br /&gt;
&lt;div style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; font: normal normal normal 13px/19px Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0.6em; padding-left: 0.6em; padding-right: 0.6em; padding-top: 0.6em;"&gt;While working on a recent&amp;nbsp;&lt;span class="Apple-style-span" mce_name="strong" mce_style="font-weight: bold;" style="font-weight: bold;"&gt;HTML5&lt;/span&gt;&amp;nbsp;project I found myself wishing for the convenience of data binding. &amp;nbsp;I was building a timer and was adding a lot of callbacks to update the UI elements on the page. &amp;nbsp;I figured there was a better way and after a little searching I came across&amp;nbsp;&lt;a href="http://knockoutjs.com/" mce_href="http://knockoutjs.com" target="_blank" title="Knockout data binding library"&gt;Knockout&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Our Goal&lt;/b&gt;&lt;/div&gt;&lt;div style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; font: normal normal normal 13px/19px Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0.6em; padding-left: 0.6em; padding-right: 0.6em; padding-top: 0.6em;"&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-H_SZD0kqBDo/TWGqpo8_dXI/AAAAAAAAAQg/b7eZYgV5uMg/s1600/DemoScreenshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="275" src="http://2.bp.blogspot.com/-H_SZD0kqBDo/TWGqpo8_dXI/AAAAAAAAAQg/b7eZYgV5uMg/s320/DemoScreenshot.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; font: normal normal normal 13px/19px Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0.6em; padding-left: 0.6em; padding-right: 0.6em; padding-top: 0.6em;"&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://knockoutjs.com/" mce_href="http://knockoutjs.com" target="_blank" title="KnockoutJS"&gt;Knockout&lt;/a&gt;&amp;nbsp;is a great combination of&amp;nbsp;&lt;span class="Apple-style-span" mce_name="strong" mce_style="font-weight: bold;" style="font-weight: bold;"&gt;&lt;a href="http://api.jquery.com/category/plugins/templates/" mce_href="http://api.jquery.com/category/plugins/templates/" target="_blank" title="jQuery Templates Plugin"&gt;jQuery templates&lt;/a&gt;&lt;/span&gt;&amp;nbsp;and data binding that allows for one-way and two-way binding back to a Javascript object. &amp;nbsp;I've put together an example project with an ugly looking stopwatch, and we'll go through some parts of it in this blog post (just want the code, bro?&amp;nbsp;&lt;a href="http://dl.dropbox.com/u/9590085/BlogFiles/MVVMJavascript-MotherEffinClock.zip" mce_href="http://dl.dropbox.com/u/9590085/BlogFiles/MVVMJavascript-MotherEffinClock.zip" title="MVVM DataBinding javascript example project"&gt;get it here&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" mce_name="strong" mce_style="font-weight: bold;" style="font-weight: bold;"&gt;The&amp;nbsp;&lt;span class="Apple-style-span" mce_name="em" mce_style="font-style: italic;" style="font-style: italic;"&gt;timer()&lt;/span&gt;&amp;nbsp;class with Knockout Observables&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: javascript"&gt;/// The timer class.
var timer = function () {
    this.started = new ko.observable(false);
    this.totalSeconds = new ko.observable(0);

    this.seconds = new ko.dependentObservable(function () {
        return (this.totalSeconds() % 60).toFixed(0);
    }, this);

    this.secondsDisplay = new ko.dependentObservable(function () {
        var secs = this.seconds();
        var display = '' + secs;
        if (secs &amp;lt; 10) { display = '0' + secs; }

        // Hack for weird edge case because of setInterval.
        if (display == '010') { display = '10'; }

        return display;
    }, this);

    this.minutes = new ko.dependentObservable(function () {
        return ((this.totalSeconds() / 60) % 60).toFixed(0);
    }, this);

    this.hours = new ko.dependentObservable(function () {
        return (((this.totalSeconds() / 60) / 60) % 60).toFixed(0);
    }, this);

    this.secondHandAngle = new ko.dependentObservable(function () {
        return this.seconds() * 6;
    }, this);

    this.minuteHandAngle = new ko.dependentObservable(function () {
        return this.minutes() * 6;
    }, this);

    this.hourHandAngle = new ko.dependentObservable(function () {
        return this.hours() * 6;
    }, this);

    this.alarm = function () {
        log('alarm fired');
    };
};

// timer.start
timer.prototype.start = function () {
    this.started(true);
    this.startTime = new Date();
    var self = this;

    this.intervalId = setInterval(function () {
        var oldTime = self.startTime;
        self.startTime = new Date();

        var diff = secondsBetween(self.startTime, oldTime);
        var currSeconds = self.totalSeconds();
        self.totalSeconds(currSeconds + diff);
    }, 100);
};

// timer.stop
timer.prototype.stop = function () {
    this.started(false);
    if (this.intervalId) {
        clearInterval(this.intervalId);
    }
};

// helper...
function secondsBetween(date1, date2) {
    return (date1.getTime() - date2.getTime()) / 1000;
};
&lt;/pre&gt;&lt;br /&gt;
From the timer class code you can see that we declare our fields as ko.observable()'s. &amp;nbsp;These are wrappers around our values that help with notifying our bound elements when the values change. &amp;nbsp;The function() syntax for accessing the fields does take a little getting used to; evidently it's necessary since IE doesn't implement property setters and getters. &amp;nbsp;Other than the new syntax, our class is pretty basic. &amp;nbsp;We have a&amp;nbsp;&lt;span class="Apple-style-span" mce_name="em" mce_style="font-style: italic;" style="font-style: italic;"&gt;&lt;span class="Apple-style-span" mce_name="strong" mce_style="font-weight: bold;" style="font-weight: bold;"&gt;started&lt;/span&gt;&lt;/span&gt;&amp;nbsp;field and a&amp;nbsp;&lt;span class="Apple-style-span" mce_name="strong" mce_style="font-weight: bold;" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" mce_name="em" mce_style="font-style: italic;" style="font-style: italic;"&gt;totalSeconds&lt;/span&gt;&lt;/span&gt;&amp;nbsp;field that drive the rest of our fields by way of the dependentObservable() functionality. &amp;nbsp;The dependentObservable() is a nifty way of declaring fields that are computed based on other observable() fields. &amp;nbsp;For us, we do some quick math to determine our seconds, minutes and hours based on the&amp;nbsp;&lt;span class="Apple-style-span" mce_name="strong" mce_style="font-weight: bold;" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" mce_name="em" mce_style="font-style: italic;" style="font-style: italic;"&gt;totalSeconds&lt;/span&gt;&lt;/span&gt;&amp;nbsp;that have passed while running the timer. &amp;nbsp;We also create some fields for the angle of our timer hands based on the computed underlying second/minute/hour values.&lt;br /&gt;
&lt;span class="Apple-style-span" mce_name="strong" mce_style="font-weight: bold;" style="font-weight: bold;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" mce_name="strong" mce_style="font-weight: bold;" style="font-weight: bold;"&gt;The ViewModel and View DataBinding&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: html"&gt;@{
 Page.Title = "Home Page";
}

@section ScriptSection {

    &amp;lt;script id="faceTemplate" type="text/x-jquery-tmpl"&amp;gt;
        @* Our SVG Code in a partial view *@
        @Html.Partial("_WatchFace")
        &amp;lt;div id="timerInfo" style="font-weight: bold; font-size: 24px; float: left;"&amp;gt;
            &amp;lt;span class="minutes" data-bind="text: minutes()"&amp;gt;&amp;lt;/span&amp;gt;
            &amp;lt;span&amp;gt;:&amp;lt;/span&amp;gt;
            &amp;lt;span class="seconds" data-bind="text: secondsDisplay()"&amp;gt;&amp;lt;/span&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/script&amp;gt;

    &amp;lt;script type="text/javascript"&amp;gt;

        // Our custom svg Rotate transform binding...
        ko.bindingHandlers.svgRotate = {
            init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
                // This will be called when the binding is first applied to an element
                // Set up any initial state, event handlers, etc. here
            },
            update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
                // This will be called once when the binding is first applied to an element,
                // and again whenever the associated observable changes value.
                // Update the DOM element based on the supplied values here.

                var value = valueAccessor(), allBindings = allBindingsAccessor();

                var rotation = ko.utils.unwrapObservable(value);
                var originX = allBindings.originX || 0;
                var originY = allBindings.originY || 0;

                var rotateText = 'rotate(' + rotation + ', ' + originX + ', ' + originY + ')';
                var id = $(element).attr('id');

                // Using the old school doc getElement because jquery's attr() is not setting the value correctly
                var elem = document.getElementById(id);
                if (!elem) { log('rotate binding element not found'); return; }

                elem.setAttribute('transform', rotateText);
            }
        };

        // Our page ViewModel
        var viewModel = {
            watch: new ko.observable(new timer()),
            start: function () {
                this.watch().start();
            },
            stop: function () {
                this.watch().stop();
            },
            toggleTimer: function () {
                this.watch().started() ? this.stop() : this.start();
            }
        };

        ko.applyBindings(viewModel);
    &amp;lt;/script&amp;gt;
}

&amp;lt;p&amp;gt;
    This is an example project using &amp;lt;a href="http://html5boilerplate.com"&amp;gt;HTML5 Boilerplate&amp;lt;/a&amp;gt; patterns, &amp;lt;a href="http://knockoutjs.com"&amp;gt;Knockout.js&amp;lt;/a&amp;gt;  MVVM Binding and Templating, &amp;lt;a href="http://docs.jquery.com/Qunit"&amp;gt;QUnit&amp;lt;/a&amp;gt; unit tests and SVG Graphics.
&amp;lt;/p&amp;gt;&amp;lt;br /&amp;gt;

&amp;lt;div id="watchContainer" style="cursor: pointer;" data-bind='template: { name: "faceTemplate", data: watch()}, click: toggleTimer'&amp;gt;

&amp;lt;/div&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
The main parts of this code are the ViewModel which we bind our HTML Elements to, and the jQuery templates that define our stopwatch and second/minute hands. &amp;nbsp;At the top, I declare my&amp;nbsp;&lt;span class="Apple-style-span" mce_name="strong" mce_style="font-weight: bold;" style="font-weight: bold;"&gt;SVG&lt;/span&gt;&amp;nbsp;Stopwatch with a custom knockout binding (you can see the code for the special binding at lines 10-20) I created to update the transform of the path based on the angle in the timer. &lt;br /&gt;
&lt;br /&gt;
Next, the script section for our page creates a special binding that updates the transform attribute of the Path&amp;nbsp;&lt;span class="Apple-style-span" mce_name="strong" mce_style="font-weight: bold;" style="font-weight: bold;"&gt;SVG&lt;/span&gt;&amp;nbsp;Element to rotate the hands of the clock. &amp;nbsp;Also in the script section, we declare our&amp;nbsp;&lt;span class="Apple-style-span" mce_name="strong" mce_style="font-weight: bold;" style="font-weight: bold;"&gt;ViewModel&lt;/span&gt;&amp;nbsp;for the page. &amp;nbsp;The&amp;nbsp;&lt;span class="Apple-style-span" mce_name="strong" mce_style="font-weight: bold;" style="font-weight: bold;"&gt;ViewModel&lt;/span&gt;&amp;nbsp;creates a timer and some utility functions for toggling the timer between start and stop. &amp;nbsp;After declaring our ViewModel, we use Knockout's ko.applyBindings() function to setup the page's templates and apply our data bindings.&lt;br /&gt;
&lt;span class="Apple-style-span" mce_name="strong" mce_style="font-weight: bold;" style="font-weight: bold;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" mce_name="strong" mce_style="font-weight: bold;" style="font-weight: bold;"&gt;The MotherEffin Clock Demo Project&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
I've put together a&amp;nbsp;&lt;a href="http://dl.dropbox.com/u/9590085/BlogFiles/MVVMJavascript-MotherEffinClock.zip" mce_href="http://dl.dropbox.com/u/9590085/BlogFiles/MVVMJavascript-MotherEffinClock.zip" title="MVVM DataBinding Javascript example"&gt;Demo Project&amp;nbsp;for download&lt;/a&gt;&amp;nbsp;using my MotherEffin&amp;nbsp;&lt;a href="http://visualstudiogallery.msdn.microsoft.com/2b462e2e-5215-4d07-a4de-4c31c432c12b" mce_href="http://visualstudiogallery.msdn.microsoft.com/2b462e2e-5215-4d07-a4de-4c31c432c12b" target="_blank" title="Html5 Boilerplate visual studio template"&gt;HTML5 Boilerplate project template&lt;/a&gt;&amp;nbsp;for MVC3. &amp;nbsp;I highly recommend visiting the&amp;nbsp;&lt;a href="http://knockoutjs.com/documentation/introduction.html" mce_href="http://knockoutjs.com/documentation/introduction.html" target="_blank" title="KnockoutJS documentation"&gt;KnockoutJS documentation&lt;/a&gt;&amp;nbsp;for more information about&amp;nbsp;&lt;a href="http://knockoutjs.com/documentation/template-binding.html" mce_href="http://knockoutjs.com/documentation/template-binding.html" target="_blank" title="KnockoutJS template binding"&gt;templates&lt;/a&gt;,&amp;nbsp;&lt;a href="http://knockoutjs.com/documentation/custom-bindings.html" mce_href="http://knockoutjs.com/documentation/custom-bindings.html" target="_blank" title="KnockoutJS Creating Custom Bindings"&gt;custom bindings&lt;/a&gt;&amp;nbsp;and&amp;nbsp;&lt;a href="http://knockoutjs.com/documentation/observables.html" mce_href="http://knockoutjs.com/documentation/observables.html" target="_blank" title="Javascript MVVM Observables"&gt;observables&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Next time, we'll go through Unit Testing and Object Oriented Javascript with&amp;nbsp;&lt;a href="http://docs.jquery.com/Qunit" mce_href="http://docs.jquery.com/Qunit" target="_blank" title="QUnit Javascript Unit Testing Framework"&gt;QUnit&lt;/a&gt;.&lt;br /&gt;
&lt;span class="Apple-style-span" mce_name="strong" mce_style="font-weight: bold;" style="font-weight: bold;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" mce_name="strong" mce_style="font-weight: bold;" style="font-weight: bold;"&gt;Now Playing&lt;/span&gt;&amp;nbsp;-&amp;nbsp;&lt;a href="http://www.youtube.com/watch?v=JyX7dHmaRlA&amp;amp;t=0m10s" mce_href="http://www.youtube.com/watch?v=JyX7dHmaRlA&amp;amp;t=0m10s" target="_self" title="Dont call it a come back..."&gt;LL Cool J - Momma Said Knock You Out&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Jacob4U2/~4/0zkrhoa0C3w" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jacob4u2.blogspot.com/feeds/6535971477017692418/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jacob4u2.blogspot.com/2011/02/while-working-on-recent-html5-i-found.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/6535971477017692418?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/6535971477017692418?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Jacob4U2/~3/0zkrhoa0C3w/while-working-on-recent-html5-i-found.html" title="" /><author><name>Jacob Gable</name><uri>http://www.blogger.com/profile/06143537581139815312</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="27" src="http://2.bp.blogspot.com/_V6SpmG8I6qw/TJoxZU9swWI/AAAAAAAAANs/FKLAJ7MEDpw/S220/babyProfilePic1.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-H_SZD0kqBDo/TWGqpo8_dXI/AAAAAAAAAQg/b7eZYgV5uMg/s72-c/DemoScreenshot.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://jacob4u2.blogspot.com/2011/02/while-working-on-recent-html5-i-found.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0EERHo-cCp7ImA9Wx9UFUg.&quot;"><id>tag:blogger.com,1999:blog-7763566905460067738.post-3455000196201266141</id><published>2011-02-12T18:00:00.001-05:00</published><updated>2011-02-12T18:00:05.458-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-12T18:00:05.458-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="silverlight" /><category scheme="http://www.blogger.com/atom/ns#" term="xaml" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><title>Silverlight Fade Control Behavior - FadeyBehavior</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;In my last post about &lt;a href="http://jacob4u2.blogspot.com/2011/02/silverlight-4-property-triggers.html"&gt;Silverlight Property Triggers&lt;/a&gt; and Storyboard Actions I showed a way for us to fade in an element when a property on our view model was a certain value. &amp;nbsp;We used this to fade in a list of items after we loaded them, and ultimately we could fade them out while we were re-loading more items. &amp;nbsp;The code looked kind of like this;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: xml"&gt;&amp;lt;ItemsControl
    Margin=&amp;quot;0 130 0 0&amp;quot;
    HorizontalAlignment=&amp;quot;Left&amp;quot;
    VerticalAlignment=&amp;quot;Top&amp;quot;
    Opacity=&amp;quot;0.0&amp;quot;
    ItemsSource=&amp;quot;{Binding Items}&amp;quot;&amp;gt;
            &amp;lt;i:Interaction.Triggers&amp;gt;
                &amp;lt;local:BooleanPropertyTrigger
                    Binding=&amp;quot;{Binding FinishedLoading}&amp;quot;
                    TriggerValue=&amp;quot;True&amp;quot;&amp;gt;
                    &amp;lt;local:StoryboardAction&amp;gt;
                        &amp;lt;Storyboard&amp;gt;
                            &amp;lt;DoubleAnimation
                                To=&amp;quot;1.0&amp;quot;
                                Duration=&amp;quot;00:00:0.7&amp;quot;
                                Storyboard.TargetProperty=&amp;quot;Opacity&amp;quot; /&amp;gt;
                        &amp;lt;/Storyboard&amp;gt;
                    &amp;lt;/local:StoryboardAction&amp;gt;
                &amp;lt;/local:BooleanPropertyTrigger&amp;gt;
                &amp;lt;local:BooleanPropertyTrigger
                    Binding=&amp;quot;{Binding FinishedLoading}&amp;quot;
                    TriggerValue=&amp;quot;False&amp;quot;&amp;gt;
                    &amp;lt;local:StoryboardAction&amp;gt;
                        &amp;lt;Storyboard&amp;gt;
                            &amp;lt;DoubleAnimation
                                To=&amp;quot;0.0&amp;quot;
                                Duration=&amp;quot;00:00:0.4&amp;quot;
                                Storyboard.TargetProperty=&amp;quot;Opacity&amp;quot; /&amp;gt;
                        &amp;lt;/Storyboard&amp;gt;
                    &amp;lt;/local:StoryboardAction&amp;gt;
                &amp;lt;/local:BooleanPropertyTrigger&amp;gt;
            &amp;lt;/i:Interaction.Triggers&amp;gt;
                &amp;lt;ItemsControl.ItemTemplate&amp;gt;
        &amp;lt;DataTemplate&amp;gt;
            &amp;lt;Border
                Height=&amp;quot;30&amp;quot;
                Width=&amp;quot;200&amp;quot;
                Margin=&amp;quot;0 2&amp;quot;
                BorderBrush=&amp;quot;Plum&amp;quot;
                BorderThickness=&amp;quot;3&amp;quot;
                CornerRadius=&amp;quot;5&amp;quot;&amp;gt;
                &amp;lt;TextBlock
                    VerticalAlignment=&amp;quot;Center&amp;quot;
                    HorizontalAlignment=&amp;quot;Left&amp;quot;
                    Margin=&amp;quot;5 0 0 0&amp;quot;
                    Text=&amp;quot;{Binding Name}&amp;quot; /&amp;gt;
            &amp;lt;/Border&amp;gt;
        &amp;lt;/DataTemplate&amp;gt;
    &amp;lt;/ItemsControl.ItemTemplate&amp;gt;
&amp;lt;/ItemsControl&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
Now, the more I looked at all that XAML the more I thought we could make this a lot simpler. &amp;nbsp;By the end of this post we will hopefully end up having something much simpler to use; like this;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: xml"&gt;&amp;lt;ItemsControl
    Margin=&amp;quot;0 130 0 0&amp;quot;
    HorizontalAlignment=&amp;quot;Left&amp;quot;
    VerticalAlignment=&amp;quot;Top&amp;quot;
    Opacity=&amp;quot;0.0&amp;quot;
    ItemsSource=&amp;quot;{Binding Items}&amp;quot;&amp;gt;
    &amp;lt;i:Interaction.Behaviors&amp;gt;
        &amp;lt;local:FadeyBehavior
            Binding=&amp;quot;{Binding FinishedLoading}&amp;quot; /&amp;gt;
    &amp;lt;/i:Interaction.Behaviors&amp;gt;
    &amp;lt;ItemsControl.ItemTemplate&amp;gt;
        &amp;lt;DataTemplate&amp;gt;
            &amp;lt;Border
                Height=&amp;quot;30&amp;quot;
                Width=&amp;quot;200&amp;quot;
                Margin=&amp;quot;0 2&amp;quot;
                BorderBrush=&amp;quot;Plum&amp;quot;
                BorderThickness=&amp;quot;3&amp;quot;
                CornerRadius=&amp;quot;5&amp;quot;&amp;gt;
                &amp;lt;TextBlock
                    VerticalAlignment=&amp;quot;Center&amp;quot;
                    HorizontalAlignment=&amp;quot;Left&amp;quot;
                    Margin=&amp;quot;5 0 0 0&amp;quot;
                    Text=&amp;quot;{Binding Name}&amp;quot; /&amp;gt;
            &amp;lt;/Border&amp;gt;
        &amp;lt;/DataTemplate&amp;gt;
    &amp;lt;/ItemsControl.ItemTemplate&amp;gt;
&amp;lt;/ItemsControl&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
So, what we've done is encompassed our two triggers and their storyboards into a new &lt;b&gt;Behavior. &amp;nbsp;&lt;/b&gt;Our new FadeyBehavior creates and attaches our to FadeIn and FadeOut triggers along with the associated FadeInAction and FadeOutAction. &amp;nbsp;The secret sauce is in cascading the binding down to the triggers in the code behind.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: csharp"&gt;using System.Windows;
using System.Windows.Data;
using System.Windows.Interactivity;

/// &amp;lt;summary&amp;gt;
/// A behavior for fading an element based on whether a bound property is true or false.
/// &amp;lt;/summary&amp;gt;
public class FadeyBehavior : Behavior&amp;lt;FrameworkElement&amp;gt;
{
    /// &amp;lt;summary&amp;gt;
    /// The &amp;lt;see cref=&amp;quot;Binding&amp;quot; /&amp;gt; dependency property's name.
    /// &amp;lt;/summary&amp;gt;
    public const string BindingPropertyName = &amp;quot;Binding&amp;quot;;

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the value of the &amp;lt;see cref=&amp;quot;Binding&amp;quot; /&amp;gt;
    /// property. This is a dependency property.
    /// &amp;lt;/summary&amp;gt;
    public object Binding
    {
        get
        {
            return (object)GetValue(BindingProperty);
        }
        set
        {
            SetValue(BindingProperty, value);
        }
    }

    /// &amp;lt;summary&amp;gt;
    /// Identifies the &amp;lt;see cref=&amp;quot;Binding&amp;quot; /&amp;gt; dependency property.
    /// &amp;lt;/summary&amp;gt;
    public static readonly DependencyProperty BindingProperty = DependencyProperty.Register(
        BindingPropertyName,
        typeof(object),
        typeof(FadeyBehavior),
        new PropertyMetadata(null));


    protected override void OnAttached()
    {
        if (AssociatedObject.Opacity != 0.0)
            AssociatedObject.Opacity = 0.0;

        // Create our fade in/out triggers
        var triggerIn = new FadeInTrigger();
        var triggerOut = new FadeOutTrigger();

        // Bind the Binding property in this behavior to the underlying triggers.
        var b = new Binding(&amp;quot;Binding&amp;quot;) { Source = this };
        BindingOperations.SetBinding(triggerIn, BooleanPropertyTrigger.BindingProperty, b);
        BindingOperations.SetBinding(triggerOut, BooleanPropertyTrigger.BindingProperty, b);

        // Add our triggers to the associated object.
        var currTriggers = Interaction.GetTriggers(AssociatedObject);
        currTriggers.Add(triggerIn);
        currTriggers.Add(triggerOut);

        base.OnAttached();
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
    }
}
&lt;/pre&gt;&lt;br /&gt;
For the time being, I've only had to use this for a boolean property trigger, but it could be expanded into a base class for other trigger types (String, DateTime range, WidgetA, etc.).&lt;br /&gt;
&lt;br /&gt;
You can &lt;a href="http://dl.dropbox.com/u/9590085/BlogFiles/FadeyBehaviorExample.zip"&gt;download the code&lt;/a&gt; to mess around with it yourself.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Now Playing&lt;/b&gt; - &lt;a href="http://www.youtube.com/watch?v=2omb_4O5DkQ"&gt;La Roux - In For The Kill&lt;/a&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Jacob4U2/~4/YZ9uJwbwSvg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jacob4u2.blogspot.com/feeds/3455000196201266141/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jacob4u2.blogspot.com/2011/02/silverlight-fade-control-behavior.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/3455000196201266141?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/3455000196201266141?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Jacob4U2/~3/YZ9uJwbwSvg/silverlight-fade-control-behavior.html" title="Silverlight Fade Control Behavior - FadeyBehavior" /><author><name>Jacob Gable</name><uri>http://www.blogger.com/profile/06143537581139815312</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="27" src="http://2.bp.blogspot.com/_V6SpmG8I6qw/TJoxZU9swWI/AAAAAAAAANs/FKLAJ7MEDpw/S220/babyProfilePic1.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://jacob4u2.blogspot.com/2011/02/silverlight-fade-control-behavior.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D08CQXwyfip7ImA9Wx9UFEs.&quot;"><id>tag:blogger.com,1999:blog-7763566905460067738.post-6664526828253532781</id><published>2011-02-11T18:11:00.001-05:00</published><updated>2011-02-11T18:11:00.296-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-11T18:11:00.296-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="silverlight" /><category scheme="http://www.blogger.com/atom/ns#" term="xaml" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><title>Silverlight Storyboard and FadeIn FadeOut Actions</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;In my last post I talked about &lt;a href="http://jacob4u2.blogspot.com/2011/02/silverlight-4-property-triggers.html"&gt;Silverlight Property Triggers&lt;/a&gt;&amp;nbsp;and how we could use them to trigger functionality when a property on our ViewModel was a certain value. &amp;nbsp;The keen observer will have noted that I glossed over a bit of magic that was happening in the &lt;b&gt;StoryboardAction&lt;/b&gt;. &amp;nbsp;Today's post is going to cover how to create your very own &lt;b&gt;StoryboardAction&lt;/b&gt; to love and cherish for all time. &amp;nbsp;Here is a quick re-cap of what our XAML looked like in the last post;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: xml"&gt;&amp;lt;ItemsControl
    Margin=&amp;quot;0 130 0 0&amp;quot;
    HorizontalAlignment=&amp;quot;Left&amp;quot;
    VerticalAlignment=&amp;quot;Top&amp;quot;
    Opacity=&amp;quot;0.0&amp;quot;
    ItemsSource=&amp;quot;{Binding Items}&amp;quot;&amp;gt;
            &amp;lt;i:Interaction.Triggers&amp;gt;
                &amp;lt;local:BooleanPropertyTrigger
                    Binding=&amp;quot;{Binding FinishedLoading}&amp;quot;
                    TriggerValue=&amp;quot;True&amp;quot;&amp;gt;
                    &amp;lt;local:StoryboardAction&amp;gt;
                        &amp;lt;Storyboard&amp;gt;
                            &amp;lt;DoubleAnimation
                                To=&amp;quot;1.0&amp;quot;
                                Duration=&amp;quot;00:00:0.7&amp;quot;
                                Storyboard.TargetProperty=&amp;quot;Opacity&amp;quot; /&amp;gt;
                        &amp;lt;/Storyboard&amp;gt;
                    &amp;lt;/local:StoryboardAction&amp;gt;
                &amp;lt;/local:BooleanPropertyTrigger&amp;gt;
                &amp;lt;local:BooleanPropertyTrigger
                    Binding=&amp;quot;{Binding FinishedLoading}&amp;quot;
                    TriggerValue=&amp;quot;False&amp;quot;&amp;gt;
                    &amp;lt;local:StoryboardAction&amp;gt;
                        &amp;lt;Storyboard&amp;gt;
                            &amp;lt;DoubleAnimation
                                To=&amp;quot;0.0&amp;quot;
                                Duration=&amp;quot;00:00:0.4&amp;quot;
                                Storyboard.TargetProperty=&amp;quot;Opacity&amp;quot; /&amp;gt;
                        &amp;lt;/Storyboard&amp;gt;
                    &amp;lt;/local:StoryboardAction&amp;gt;
                &amp;lt;/local:BooleanPropertyTrigger&amp;gt;
            &amp;lt;/i:Interaction.Triggers&amp;gt;
                &amp;lt;ItemsControl.ItemTemplate&amp;gt;
        &amp;lt;DataTemplate&amp;gt;
            &amp;lt;Border
                Height=&amp;quot;30&amp;quot;
                Width=&amp;quot;200&amp;quot;
                Margin=&amp;quot;0 2&amp;quot;
                BorderBrush=&amp;quot;Plum&amp;quot;
                BorderThickness=&amp;quot;3&amp;quot;
                CornerRadius=&amp;quot;5&amp;quot;&amp;gt;
                &amp;lt;TextBlock
                    VerticalAlignment=&amp;quot;Center&amp;quot;
                    HorizontalAlignment=&amp;quot;Left&amp;quot;
                    Margin=&amp;quot;5 0 0 0&amp;quot;
                    Text=&amp;quot;{Binding Name}&amp;quot; /&amp;gt;
            &amp;lt;/Border&amp;gt;
        &amp;lt;/DataTemplate&amp;gt;
    &amp;lt;/ItemsControl.ItemTemplate&amp;gt;
&amp;lt;/ItemsControl&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
Today, we added another trigger to fade the items out when we re-load our items. &amp;nbsp;Then, we are going to encapsulate the fade animations in a new action that will reduce our XAML a little bit.&lt;br /&gt;
&lt;br /&gt;
First, lets take a quick look at the &lt;b&gt;StoryboardAction Source&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: csharp"&gt;using System;
using System.Windows;
using System.Windows.Interactivity;
using System.Windows.Markup;
using System.Windows.Media.Animation;

[ContentProperty(&amp;quot;Story&amp;quot;)]
public class StoryboardAction : TriggerAction&amp;lt;FrameworkElement&amp;gt;
{
    /// &amp;lt;summary&amp;gt;
    /// Holder for a target setting state.
    /// &amp;lt;/summary&amp;gt;
    private bool hasTargetSet = false;

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the storyboard for this action.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The storyboard to run when invoked.&amp;lt;/value&amp;gt;
    public Storyboard Story { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// The &amp;lt;see cref=&amp;quot;Target&amp;quot; /&amp;gt; dependency property's name.
    /// &amp;lt;/summary&amp;gt;
    public const string TargetPropertyName = &amp;quot;Target&amp;quot;;

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the value of the &amp;lt;see cref=&amp;quot;Target&amp;quot; /&amp;gt;
    /// property. This is a dependency property. 
    /// You can leave this un-set if you want to use the Trigger's 
    /// AssociatedObject as the Target.
    /// &amp;lt;/summary&amp;gt;
    public DependencyObject Target
    {
        get
        {
            return (DependencyObject)GetValue(TargetProperty);
        }
        set
        {
            SetValue(TargetProperty, value);
        }
    }

    /// &amp;lt;summary&amp;gt;
    /// Identifies the &amp;lt;see cref=&amp;quot;Target&amp;quot; /&amp;gt; dependency property.
    /// &amp;lt;/summary&amp;gt;
    public static readonly DependencyProperty TargetProperty = DependencyProperty.Register(
        TargetPropertyName,
        typeof(DependencyObject),
        typeof(StoryboardAction),
        new PropertyMetadata(null));
        

    /// &amp;lt;summary&amp;gt;
    /// Invokes the action.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;parameter&amp;quot;&amp;gt;The parameter to the action. If the action does not require a parameter, the parameter may be set to a null reference.&amp;lt;/param&amp;gt;
    protected override void Invoke(object parameter)
    {
        if (this.Story == null)
            return;

        if(!hasTargetSet)
        {
            // Fall back to the associated object if no target defined.
            var target = this.Target ?? AssociatedObject;
            if (target != null)
            {
                Storyboard.SetTarget(this.Story, target);
                hasTargetSet = true;
            }
        }

        // Stop any previously ran storyboards.
        if (this.Story.GetCurrentState() != ClockState.Stopped)
            this.Story.Stop();
            
        this.Story.Begin();            
    }
}
&lt;/pre&gt;&lt;br /&gt;
The important parts of this class are the Invoke logic. &amp;nbsp;We are doing some basic null checking, then setting the target for our animation to either the &lt;b&gt;Target&lt;/b&gt;&amp;nbsp;or the &lt;b&gt;AssociatedObject&lt;/b&gt; if no Target was found. &amp;nbsp;Finally, we make sure the animation is not currently running, then start up our animation.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;i&gt;Extra Snazzy Bonus Implementation Codez&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&lt;br /&gt;
&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
I feel like we are really connecting here, so I'm gonna throw in some extra snazzy bonus material just for you. &amp;nbsp;Here are some short hand versions of our Opacity Fade Animations that should tame the &lt;i&gt;&lt;b&gt;XAML Monster&lt;/b&gt;.&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;
&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: csharp"&gt;using System;
using System.Windows;
using System.Windows.Media.Animation;

public class FadeOutAction : FadeAction
{
    public FadeOutAction()
        : base(.2, 0.0)
    { }
}

public class FadeInAction : FadeAction
{
    public FadeInAction()
        : base(.6, 1.0)
    { }
}

public class FadeAction : StoryboardAction
{

    public FadeAction(double durationSeconds = .6, double fadeTo = 0.0)
    {
        var anim = new DoubleAnimation { Duration = new Duration(TimeSpan.FromSeconds(durationSeconds)), To = fadeTo };
        Storyboard.SetTargetProperty(anim, new PropertyPath(&amp;quot;Opacity&amp;quot;));

        this.Story = new Storyboard();
        this.Story.Children.Add(anim);
    }
}
&lt;/pre&gt;&lt;br /&gt;
Now our XAML is looking slightly better.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: xml"&gt;&amp;lt;ItemsControl
    Margin=&amp;quot;0 130 0 0&amp;quot;
    HorizontalAlignment=&amp;quot;Left&amp;quot;
    VerticalAlignment=&amp;quot;Top&amp;quot;
    Opacity=&amp;quot;0.0&amp;quot;
    ItemsSource=&amp;quot;{Binding Items}&amp;quot;&amp;gt;
            &amp;lt;i:Interaction.Triggers&amp;gt;
                &amp;lt;local:BooleanPropertyTrigger
                    Binding=&amp;quot;{Binding FinishedLoading}&amp;quot;
                    TriggerValue=&amp;quot;True&amp;quot;&amp;gt;
                    &amp;lt;local:FadeInAction /&amp;gt;
                &amp;lt;/local:BooleanPropertyTrigger&amp;gt;
                &amp;lt;local:BooleanPropertyTrigger
                    Binding=&amp;quot;{Binding FinishedLoading}&amp;quot;
                    TriggerValue=&amp;quot;False&amp;quot;&amp;gt;
                    &amp;lt;local:FadeOutAction /&amp;gt;
                &amp;lt;/local:BooleanPropertyTrigger&amp;gt;
            &amp;lt;/i:Interaction.Triggers&amp;gt;
                &amp;lt;ItemsControl.ItemTemplate&amp;gt;
        &amp;lt;DataTemplate&amp;gt;
            &amp;lt;Border
                Height=&amp;quot;30&amp;quot;
                Width=&amp;quot;200&amp;quot;
                Margin=&amp;quot;0 2&amp;quot;
                BorderBrush=&amp;quot;Plum&amp;quot;
                BorderThickness=&amp;quot;3&amp;quot;
                CornerRadius=&amp;quot;5&amp;quot;&amp;gt;
                &amp;lt;TextBlock
                    VerticalAlignment=&amp;quot;Center&amp;quot;
                    HorizontalAlignment=&amp;quot;Left&amp;quot;
                    Margin=&amp;quot;5 0 0 0&amp;quot;
                    Text=&amp;quot;{Binding Name}&amp;quot; /&amp;gt;
            &amp;lt;/Border&amp;gt;
        &amp;lt;/DataTemplate&amp;gt;
    &amp;lt;/ItemsControl.ItemTemplate&amp;gt;
&amp;lt;/ItemsControl&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
Next time, we will create a new &lt;b&gt;FadeyBehavior&lt;/b&gt;&amp;nbsp;to encapsulate our fading triggers. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Now Playing&lt;/b&gt; - &lt;a href="http://www.youtube.com/watch?v=ilEh0xbW7pI&amp;amp;t=0m35s"&gt;Jay Z, Rick Ross - Hustlin Remix&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Jacob4U2/~4/zzKiwjLvkNo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jacob4u2.blogspot.com/feeds/6664526828253532781/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jacob4u2.blogspot.com/2011/02/silverlight-storyboard-and-fadein.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/6664526828253532781?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/6664526828253532781?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Jacob4U2/~3/zzKiwjLvkNo/silverlight-storyboard-and-fadein.html" title="Silverlight Storyboard and FadeIn FadeOut Actions" /><author><name>Jacob Gable</name><uri>http://www.blogger.com/profile/06143537581139815312</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="27" src="http://2.bp.blogspot.com/_V6SpmG8I6qw/TJoxZU9swWI/AAAAAAAAANs/FKLAJ7MEDpw/S220/babyProfilePic1.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://jacob4u2.blogspot.com/2011/02/silverlight-storyboard-and-fadein.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkAFRng-eip7ImA9Wx9UEko.&quot;"><id>tag:blogger.com,1999:blog-7763566905460067738.post-4941384700058261266</id><published>2011-02-09T11:58:00.000-05:00</published><updated>2011-02-09T11:58:37.652-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-09T11:58:37.652-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="silverlight" /><category scheme="http://www.blogger.com/atom/ns#" term="xaml" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><title>Silverlight 4 Property Triggers</title><content type="html">I spent a little time this week messing around with the newly added &lt;strong&gt;Triggers&lt;/strong&gt; and &lt;strong&gt;TriggerActions&lt;/strong&gt; available through the new &lt;a href="http://www.microsoft.com/expression/products/Blend_Features.aspx"&gt;Expression Blend 4 SDK&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Triggers and Behaviors are really just ways to attach functionality to an existing element, and the base classes that are included in the newer version of Silverlight 4 really make the job easier.  I'm going to walk through adding a trigger that fires when one of the properties on my ViewModel changes to true.  Now allegedly there is an existing trigger (&lt;a title="DataStoreChangedTrigger" href="http://msdn.microsoft.com/en-us/library/ff723960(v=expression.40).aspx" target="_blank"&gt;DataStoreChangedTrigger&lt;/a&gt;) that will fire actions based on when a bound property changes, but I want to only fire my actions when my bound property becomes a specific value.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Our Goal&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: xml"&gt;&amp;lt;ItemsControl
    Margin=&amp;quot;0 130 0 0&amp;quot;
    HorizontalAlignment=&amp;quot;Left&amp;quot;
    VerticalAlignment=&amp;quot;Top&amp;quot;
    Opacity=&amp;quot;0.0&amp;quot;
    ItemsSource=&amp;quot;{Binding Items}&amp;quot;&amp;gt;
    &amp;lt;i:Interaction.Triggers&amp;gt;
        &amp;lt;local:BooleanPropertyTrigger
            Binding=&amp;quot;{Binding FinishedLoading}&amp;quot;
            TriggerValue=&amp;quot;True&amp;quot;&amp;gt;
            &amp;lt;local:StoryboardAction&amp;gt;
                &amp;lt;Storyboard&amp;gt;
                    &amp;lt;DoubleAnimation
                        To=&amp;quot;1.0&amp;quot;
                        Duration=&amp;quot;00:00:0.7&amp;quot;
                        Storyboard.TargetProperty=&amp;quot;Opacity&amp;quot; /&amp;gt;
                &amp;lt;/Storyboard&amp;gt;
            &amp;lt;/local:StoryboardAction&amp;gt;
        &amp;lt;/local:BooleanPropertyTrigger&amp;gt;
    &amp;lt;/i:Interaction.Triggers&amp;gt;
&amp;lt;/ItemsControl&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;strong&gt;The Codez&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
[Download the &lt;a title="PropertyTrigger Example Code" href="http://dl.dropbox.com/u/9590085/BlogFiles/PropertyTriggerExample.zip"&gt;PropertyTrigger Example Source Project&lt;/a&gt; and play along at home]&lt;br /&gt;
&lt;br /&gt;
To start out with, I create a base &lt;strong&gt;PropertyChangedTrigger&lt;/strong&gt; class that will do most of the heavy lifting for us.  Essentially, we want to inherit from the &lt;strong&gt;TriggerBase&lt;/strong&gt;&amp;lt;...&amp;gt; generic base class and specify that we want our Trigger to attach to a FrameworkElement (I suppose you could use another type of control class, but FrameworkElement will encompass just about any element with a DataContext, which I find useful).  Our PropertyChangedTrigger will expose a Binding property that will allow us to attach an event handler when our bound property changes so we can invoke our TriggerActions.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: csharp"&gt;/// &amp;lt;summary&amp;gt;
/// A base property changed trigger that
/// fires whenever the bound property changes.
/// &amp;lt;/summary&amp;gt;
public class PropertyChangedTrigger : TriggerBase&amp;lt;FrameworkElement&amp;gt;
{
    /// &amp;lt;summary&amp;gt;
    /// The &amp;lt;see cref=&amp;quot;Binding&amp;quot; /&amp;gt; dependency property's name.
    /// &amp;lt;/summary&amp;gt;
    public const string BindingPropertyName = &amp;quot;Binding&amp;quot;;

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the value of the &amp;lt;see cref=&amp;quot;Binding&amp;quot; /&amp;gt;
    /// property. This is a dependency property.
    /// &amp;lt;/summary&amp;gt;
    public object Binding
    {
        get
        {
            return (object)GetValue(BindingProperty);
        }
        set
        {
            SetValue(BindingProperty, value);
        }
    }

    /// &amp;lt;summary&amp;gt;
    /// Identifies the &amp;lt;see cref=&amp;quot;Binding&amp;quot; /&amp;gt; dependency property.
    /// &amp;lt;/summary&amp;gt;
    public static readonly DependencyProperty BindingProperty =
        DependencyProperty.Register(
        BindingPropertyName,
        typeof(object),
        typeof(PropertyChangedTrigger),
        new PropertyMetadata(null,
            new PropertyChangedCallback(Binding_ValueChanged)));

    /// &amp;lt;summary&amp;gt;
    /// Called after the trigger is attached to an AssociatedObject.
    /// &amp;lt;/summary&amp;gt;
    protected override void OnAttached()
    {
        base.OnAttached();
    }

    /// &amp;lt;summary&amp;gt;
    /// Called when the trigger is being detached
    /// from its AssociatedObject,
    /// but before it has actually occurred.
    /// &amp;lt;/summary&amp;gt;
    protected override void OnDetaching()
    {
        base.OnDetaching();
    }

    /// &amp;lt;summary&amp;gt;
    /// Occurs when Binding's value changes.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;obj&amp;quot;&amp;gt;The obj on which the binding changed.&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;args&amp;quot;&amp;gt;The &amp;lt;see cref=&amp;quot;System.Windows.DependencyPropertyChangedEventArgs&amp;quot;/&amp;gt; instance containing the event data.&amp;lt;/param&amp;gt;
    private static void Binding_ValueChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {
        var trig = obj as PropertyChangedTrigger;
        if (trig != null &amp;amp;&amp;amp; trig.ShouldTriggerFire(args.NewValue))
        {
            trig.OnPropertyTrigger(args.NewValue);
        }
    }

    /// &amp;lt;summary&amp;gt;
    /// Does the change logic test. By default, it will always fire on value change.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;newValue&amp;quot;&amp;gt;The new value.&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;True if the trigger should fire, otherwise false.&amp;lt;/returns&amp;gt;
    protected virtual bool ShouldTriggerFire(object newValue)
    {
        return true;
    }

    /// &amp;lt;summary&amp;gt;
    /// Called when [property trigger].
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;value&amp;quot;&amp;gt;The value of the property.&amp;lt;/param&amp;gt;
    protected virtual void OnPropertyTrigger(object value)
    {
        base.InvokeActions(value);
    }
}
&lt;/pre&gt;&lt;br /&gt;
As you can tell, our &lt;strong&gt;PropertyChangedTrigger&lt;/strong&gt; makes use of a virtual method &lt;strong&gt;ShouldTriggerFire(…)&lt;/strong&gt; that will default to just fire everytime a property changes value. Next, we will override our base class to create an &lt;strong&gt;EqualsPropertyTrigger&lt;/strong&gt; that only fires when the value changes to a specific one that we want.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: csharp"&gt;/// &amp;lt;summary&amp;gt;
/// A base class for property triggers that must be equal to fire.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;typeparam name=&amp;quot;TValue&amp;quot;&amp;gt;The type of the trigger value.&amp;lt;/typeparam&amp;gt;
/// &amp;lt;summary&amp;gt;
/// A base class for property triggers that must be equal to fire.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;typeparam name=&amp;quot;TValue&amp;quot;&amp;gt;The type of the trigger value.&amp;lt;/typeparam&amp;gt;
public class EqualsPropertyTrigger&amp;lt;TValue&amp;gt; : PropertyChangedTrigger
{
    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the trigger value to match the property value for.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The trigger value.&amp;lt;/value&amp;gt;
    public TValue TriggerValue { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Logic to check whether the trigger should fire.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;newValue&amp;quot;&amp;gt;The new value.&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;True if the trigger should fire, otherwise false.&amp;lt;/returns&amp;gt;
    protected override bool ShouldTriggerFire(object newValue)
    {
        if (newValue == null)
            return this.TriggerValue == null;

        return newValue.Equals(this.TriggerValue);
    }
}
&lt;/pre&gt;&lt;br /&gt;
So now we have a nice base class for our &lt;strong&gt;BooleanPropertyTrigger&lt;/strong&gt; that makes it's implementation really nice and clean.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: csharp"&gt;/// &amp;lt;summary&amp;gt;
/// A generic object property trigger
/// &amp;lt;/summary&amp;gt;
public class PropertyTrigger : EqualsPropertyTrigger&amp;lt;object&amp;gt;
{ }

/// &amp;lt;summary&amp;gt;
/// A Boolean value property trigger
/// &amp;lt;/summary&amp;gt;
public class BooleanPropertyTrigger : EqualsPropertyTrigger&amp;lt;bool&amp;gt;
{ }

/// &amp;lt;summary&amp;gt;
/// A string property value trigger
/// &amp;lt;/summary&amp;gt;
public class StringPropertyTrigger : EqualsPropertyTrigger&amp;lt;string&amp;gt;
{ }
&lt;/pre&gt;&lt;br /&gt;
Now, all that's left to do is hook it up in our XAML by adding the namespace to our trigger and making sure we have a reference to System.Windows.Interactivity (version 4.0.5.0).&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Next Steps&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Next, we could make a &lt;strong&gt;NotEqualsPropertyTrigger&lt;/strong&gt; that fires when a value is not a certain value.  It's implementation would be as easy as inheriting from the EqualsPropertyTrigger and negating the base ShouldFireTrigger(...) method.&lt;br /&gt;
&lt;br /&gt;
Hopefully, like me, you've learned a little about triggers and how they can be useful.  For my next blog post I'm going to incorporate the visual state manager and make a &lt;strong&gt;GoToStateAction&lt;/strong&gt; along with talking a little bit about creating the &lt;strong&gt;StoryBoardAction&lt;/strong&gt; you see in the example.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Now Playing&lt;/strong&gt; - &lt;a title="Ask around the streets man I'm certified" href="http://www.youtube.com/watch?v=62VASkbu1gw" target="_blank"&gt;Pretty Lights - Hot Like Sauce&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/Jacob4U2/~4/kiVoWIAd-Ws" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jacob4u2.blogspot.com/feeds/4941384700058261266/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jacob4u2.blogspot.com/2011/02/silverlight-4-property-triggers.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/4941384700058261266?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7763566905460067738/posts/default/4941384700058261266?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Jacob4U2/~3/kiVoWIAd-Ws/silverlight-4-property-triggers.html" title="Silverlight 4 Property Triggers" /><author><name>Jacob Gable</name><uri>http://www.blogger.com/profile/06143537581139815312</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="27" src="http://2.bp.blogspot.com/_V6SpmG8I6qw/TJoxZU9swWI/AAAAAAAAANs/FKLAJ7MEDpw/S220/babyProfilePic1.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://jacob4u2.blogspot.com/2011/02/silverlight-4-property-triggers.html</feedburner:origLink></entry></feed>
