<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Braindonor Network</title>
	<atom:link href="http://www.braindonor.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.braindonor.net</link>
	<description>Send us your brain...let us do the thinking for you!</description>
	<lastBuildDate>Tue, 10 Apr 2012 06:13:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>A New Home For The BrainDonor Network</title>
		<link>http://www.braindonor.net/blog/a-new-home-for-the-braindonor-network/606/</link>
		<comments>http://www.braindonor.net/blog/a-new-home-for-the-braindonor-network/606/#comments</comments>
		<pubDate>Tue, 10 Apr 2012 06:12:59 +0000</pubDate>
		<dc:creator>theBraindonor</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[aws]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://23.21.65.241/?p=606</guid>
		<description><![CDATA[The BrainDonor Network has a new home in the cloud! I have moved everything from Slicehost to Amazon Web Services. With Rackspace finally pushing through the migration of server images from Slicehost to the Rackspace Cloud, I knew I had the perfect opportunity to switch. Having deployed several client sites to AWS, I also knew [...]]]></description>
			<content:encoded><![CDATA[<p>The BrainDonor Network has a new home in the cloud! I have moved everything from Slicehost to Amazon Web Services. With Rackspace finally pushing through the migration of server images from Slicehost to the Rackspace Cloud, I knew I had the perfect opportunity to switch.  Having deployed several client sites to AWS, I also knew I had the comfort level to get everything migrated and set up&#8212;so that I could start ignoring it once again.</p><span id="more-606"></span>

<h2>Wait!? Ignore It!?</h2>
<p>You heard that right! I prefer to ignore my own site as much as possible. I've learned over the years that if I have to babysit my own servers and services, then I am doing things wrong.  This is simple economics.  I don't get paid directly for operating The BrainDonor Network.  Whenever I write new posts, compose tweets, or push commits I am spending my personal time.  System administration is unfortunately not something that I enjoy&#8212;so I prefer to avoid it whenever possible and whenever I'm confident that it will not expose me to significant risks.</p>

<p>What pushed me to this attitude for my own site was the "War on Spam". There was a time when I took great pride in having the hardware that hosted The BrainDonor Network sitting in my office at home.  Everything was hosted here: web, email, chat, games, music, etc.  This was a ton of fun and a great way for me to keep up to date on how to run an online presence for other businesses.  Unfortunately, it was getting harder every year to keep in touch with those businesses.  I was spending a couple hours a month just making sure that my email would go through.  At this point, I finally had enough and decided to host my email someplace where I knew it wouldn't be blocked lightly&#8212;Google.  With email already offloaded to the cloud, I was quick to take advantage of affordable virtual private server hosting that rolling out.</p>

<h2>What Did Slicehost Do Wrong?</h2>
<p>Slicehost really didn't do anything wrong.  They're parent company&#8212;Rackspace&#8212;also didn't really do anything wrong.  No matter the hype and marketing, Rackspace excels at provided managed dedicated hosting.  Their cloud offerings have continued to be a secondary service. Up until recently, Rackspace even had separate support teams.  This caused me all kinds of professional hilarity when trying to deploy solutions to their hybrid hosting.  You literally had to demand a conference call to get everyone on the phone to get things fixed&#8212;wasting an enormous amount of everyone's time.</p>

<p>Another significant reason for me to make the switch was to refresh the infrastructure. I've replaced Apache with nginx and mod_php with FastCGI.  I've also cut out a lot of technology pieces that I wasn't using: phpmysql, postgres, mod_python, etc. Sure, all of the old data is backed-up and stored...but I'm confident that I won't need it operational any time soon.  I've always found it infinitely easier to just start fresh than to actually clean up a server.  I also wanted to switch away from Ubuntu.</p> 

<h2>Why Amazon Web Services?</h2>
<p>Amazon offers an absolutely dizzying array of services on their cloud platform and their prices are continually setting the bar for cloud computing.  I'm also not all that afraid of vendor lock-in with them.  I know I can get everything here set up and restored on a new cloud provider in just a matter of hours&#8212;even if Amazon were to go completely dark.</p>]]></content:encoded>
			<wfw:commentRss>http://www.braindonor.net/blog/a-new-home-for-the-braindonor-network/606/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting Started with MongoDB</title>
		<link>http://www.braindonor.net/projects/getting-started-with-mongodb/479/</link>
		<comments>http://www.braindonor.net/projects/getting-started-with-mongodb/479/#comments</comments>
		<pubDate>Fri, 02 Mar 2012 06:03:13 +0000</pubDate>
		<dc:creator>theBraindonor</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[FluentMongo]]></category>
		<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[MVC3]]></category>

		<guid isPermaLink="false">http://www.braindonor.net/?p=479</guid>
		<description><![CDATA[When I first got started with MongoDB in my ASP.NET development I wasn't able to find as much information as I hoped to on how to get started with MongoDB. All of the core documentation focuses on interacting with the driver and doesn't give a high-level overview of how to use the driver in an [...]]]></description>
			<content:encoded><![CDATA[<p>When I first got started with <a href="http://www.mongodb.org/" target="_blank">MongoDB</a> in my ASP.NET development I wasn't able to find as much information as I hoped to on how to get started with MongoDB.  All of the core documentation focuses on interacting with the driver and doesn't give a high-level overview of how to use the driver in an actual project.  After getting several projects up and running on MongoDB, I wanted to take a break and provide this much needed guide.</p><span id="more-479"></span>

<h3>Installing MongoDB</h3>
<p>There is no lack of information on how to get MongoDB up and running on a windows machine. The main MongoDB website has a great <a href="http://www.mongodb.org/display/DOCS/Quickstart+Windows" target="_blank">quickstart guide</a>. This guide will enable you to get MongoDB installed and running locally and provides the necessary information to run MongoDB as a service.  I prefer to start up MongoDB manually and avoid running it as a service on my development machine.</p>

<h3>Starting Your Website Project</h3>
<p>Now that you have MongoDB up and running on your machine, you can launch Visual Studio and create a new empty ASP.NET MVC3 project. Once Visual Studio has created and opened the new project, launch NuGet and install <a href="https://github.com/craiggwilson/fluent-mongo/wiki" target="_blank">FluentMongo</a>.  FluentMongo will also install the <a href="https://github.com/mongodb/mongo-csharp-driver" target="_blank">mongo-csharp-driver</a>.</p>

<p>We are installing FluentMongo because the core mongo-csharp-driver does not have LINQ support just yet. It will be coming in the next major version which should happen in a couple of months.  Once this new version is out, this guide will still be relevant&#8212;I'll just update everything to make sure that everything works with the new LINQ support. FluentMongo isn't a perfect solution, but it does give you enough of a familiar environment that you can ease into MongoDB without introducing the query language running under the hood until you are ready.</p>

<h3>Create an Initial Skeleton</h3>
<p>We can put this project together quickly with just a single model, controller and view. We'll start with the model, <code>Models\Record.cs</code>.  We're giving this object three fields: the primary key (_id), a text field, and a datetime field.  Each document of a MongoDB collection is assigned an ObjectId in the _id field.  This key will be randomly generated when a record is inserted into MongoDB.</p>

<pre class="brush: csharp">using MongoDB.Bson;

public class Record
{
    public ObjectId _id { get; set; }
    public string SomeRandomText { get; set; }
    public DateTime RecordDate { get; set; }
}</pre>

<p>Our controller initially just needs two actions: an index to list all of the records, and an action to create a new record based on text supplied by the user.  We'll fill in the details of <code>Controllers\HomeController.cs</code> later.</p>

<pre class="brush: csharp">using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using FluentMongo.Linq;

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult CreateRecord(string SomeRandomText)
    {
        return RedirectToAction("Index");
    }
}</pre>

<p>Finally, we'll add our view, <code>Views\Shared\Index.cshtml</code>.  This view will include the form to create  a new record.  As the controller will create the record and redirect back to the index action, we don't need more than this initial view.</p>

<pre class="brush: csharp">&lt;h2&gt;List of Records&lt;/h2&gt;

&lt;p&gt;placeholder&lt;/p&gt;

&lt;h2&gt;Insert New Record&lt;/h2&gt;

@using (Html.BeginForm(&quot;CreateRecord&quot;, &quot;Home&quot;))
{
    &lt;label&gt;Some Random Text:&lt;/label&gt;
    @Html.TextBox(&quot;SomeRandomText&quot;)
    &lt;input type=&quot;submit&quot; value=&quot;Create New Record&quot; /&gt;
}</pre>

<p>With that done, we can go ahead and start our web application:</p>

<img src="http://www.braindonor.net/wp-content/uploads/2012/03/Screen-Shot-2012-02-10-at-11.17.58-PM.png" alt="" title="Screen Shot 2012-02-10 at 11.17.58 PM" width="612" height="448" class="alignright size-full wp-image-595" />

<h3>Creating Data in MongoDB</h3>

<p>Our interaction with MongoDB will start with populating the <code>CreateRecord</code> action.  This method is pretty straightforward: we connect to mongo, create a new record, and save the record.  I'm sure you will notice that I have not performed two actions that would have been absolutely necessary if we were using SQL Server: create the FluentMongoExample database and the Record table.  MongoDB will create all databases and collections as they are are required by queries.  Seeing this for the first time really drives home the full impact of using a schema-less database.</p>

<pre class="brush: csharp">public ActionResult CreateRecord(string SomeRandomText)
    {
        MongoDatabase database = MongoDatabase.Create("mongodb://localhost/FluentMongoExample");
        MongoCollection<Record> collection = database.GetCollection<Record>("Record");

        Record record = new Record();

        record.SomeRandomText = SomeRandomText;
        record.RecordDate = DateTime.Now;

        collection.Save(record);

        return RedirectToAction("Index");
    }</pre>

<p>Now that we are able to create new records, we can start listing all records. Querying our records with Fluent Mongo is virtually identical to how we would normally select records using LinqToEntities or LinqToSQL.</p>

<pre class="brush: csharp">public ActionResult Index()
    {
        MongoDatabase database = MongoDatabase.Create("mongodb://localhost/FluentMongoExample");
        MongoCollection<Record> collection = database.GetCollection<Record>("Record");

        IQueryable<Record> records = from r in collection.AsQueryable() select r;

        return View(records);
    }</pre>

<p>With the controller updated, we just need to update the Index view so that it uses the <code>IQueryable&lt;Record&gt;</code> model that our index controller is passing.  I'm just using a simple for loop in a table for this example.  Most of the WebGrid are supported by FluentMongo&#8212;but not all.</p>

<pre class="brush: csharp">@model IQueryable&lt;Record&gt;

&lt;h2&gt;List of Records&lt;/h2&gt;

&lt;table cellspacing=&quot;3&quot; cellpadding=&quot;3&quot;&gt;
&lt;tr&gt;
    &lt;th&gt;_id&lt;/th&gt;
    &lt;th&gt;SomeRandomText&lt;/th&gt;
    &lt;th&gt;RecordDate&lt;/th&gt;
&lt;/tr&gt;
@foreach (Record record in Model)
{
    &lt;tr&gt;
        &lt;td&gt;@record._id&lt;/td&gt;
        &lt;td&gt;@record.SomeRandomText&lt;/td&gt;
        &lt;td&gt;@record.RecordDate&lt;/td&gt;
    &lt;/tr&gt;
}
&lt;/table&gt;</pre>

<p>With everything updated, we can rebuild or application and enter some records:</p>

<img src="http://www.braindonor.net/wp-content/uploads/2012/03/Screen-Shot-2012-02-11-at-12.08.47-AM.png" alt="" title="Screen Shot 2012-02-11 at 12.08.47 AM" width="774" height="601" class="alignright size-full wp-image-597" />

<h3>Deleting Data in MongoDB</h3>

<p>Deleting data from MongoDB gets a touch more complicated. To illustrate th issue, we'll add the stubs to delete a record from our MongoDB collection.</p>

<p>In <code>Controllers\HomeController.cs</code>:</p>

<pre class="brush: csharp">    public ActionResult DeleteRecord(ObjectId record_id)
    {
        return RedirectToAction("Index");
    }</pre>

<p>In <code>Views\Shares\Index.cshtml</code>:</p>

<pre class="brush: csharp">    &lt;tr&gt;
        &lt;td&gt;@record._id&lt;/td&gt;
        &lt;td&gt;@record.SomeRandomText&lt;/td&gt;
        &lt;td&gt;@record.RecordDate&lt;/td&gt;
        &lt;td&gt;
            @Html.ActionLink(&quot;Delete&quot;, &quot;DeleteRecord&quot;, new { record_id = record._id })
        &lt;/td&gt;
    &lt;/tr&gt;</pre>

<p>If we click our new delete button, we get the following exception:</p>

<img src="http://www.braindonor.net/wp-content/uploads/2012/03/Screen-Shot-2012-02-11-at-12.15.40-AM.png" alt="" title="Screen Shot 2012-02-11 at 12.15.40 AM" width="774" height="601" class="alignright size-full wp-image-600" />

<p>We get this exception because the ASP.NET MVC framework does not understand how to properly convert a BSON ObjectId to and from a string.  We need to provide a model binder for the ObjectId.</p>

<p>In <code>Models\Record.cs</code>:</p>

<pre class="brush: csharp">using System.Web.Mvc;

public class ObjectIdBinder : IModelBinder
{
    public object BindModel(ControllerContext controller_context, ModelBindingContext binding_context)
    {
        ValueProviderResult result = binding_context.ValueProvider.GetValue(binding_context.ModelName);
        return new ObjectId(result.AttemptedValue);
    }
}</pre>

<p>In <code>Global.asax.cs</code>:</p>

<pre class="brush: csharp">        protected void Application_Start()
        {
            ModelBinders.Binders.Add(typeof(ObjectId), new ObjectIdBinder());

            AreaRegistration.RegisterAllAreas();

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
        }</pre>

<p>With the binder added, we are able to successfully trigger our delete action and be redirected back to the index.</p>

<p>Documents are deleted from a mongo collection by providing a query that will match the documents to be deleted.  This is not something that is provided by FluentMongo&#8212;we must use a native MongoDB query.  Luckily, this is very easy to do.  The native MongoDB queries provide a much more controlled and robust means of interacting with MongoDB, but we're interested in quick and simple for this tutorial.</p>

<pre class="brush: csharp">    public ActionResult DeleteRecord(ObjectId record_id)
    {
        MongoDatabase database = MongoDatabase.Create(&quot;mongodb://localhost/FluentMongoExample&quot;);
        MongoCollection&lt;Record&gt; collection = database.GetCollection&lt;Record&gt;(&quot;Record&quot;);

        Record record = (from r in collection.AsQueryable() where r._id == record_id select r).FirstOrDefault();

        if (record != null)
        {
            collection.Remove(Query.EQ(&quot;_id&quot;, record._id));
        }

        return RedirectToAction(&quot;Index&quot;);
    }</pre>

<p>With the delete action finished, we have a working data-driven application.</p>

<p>I have added my <a href="https://github.com/theBraindonor/FluentMongoExample">project to GitHub</a> so that you can download and start tinkering yourself.  Enjoy!</p>]]></content:encoded>
			<wfw:commentRss>http://www.braindonor.net/projects/getting-started-with-mongodb/479/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jQuery Best Practices Part 2: Chaining</title>
		<link>http://www.braindonor.net/blog/thebraindonors-jquery-best-practices-part-2-chaining/427/</link>
		<comments>http://www.braindonor.net/blog/thebraindonors-jquery-best-practices-part-2-chaining/427/#comments</comments>
		<pubDate>Mon, 20 Feb 2012 16:53:13 +0000</pubDate>
		<dc:creator>theBraindonor</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.braindonor.net/?p=427</guid>
		<description><![CDATA[In Part One, I discussed managing the scope of $(document).ready(). Next comes the challenge of organizing the contents of $(document).ready() to balance efficiency and maintainability. My team accomplishes this by taking advantage of the Array behaviors of jQuery to structure our code so that function dictates form. Put into practice, these behaviors will structurally organizing [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://www.braindonor.net/coding-blog/jquery-best-practices-part-1-managing-scope/406/">Part One</a>, I discussed managing the scope of <code>$(document).ready()</code>.  Next comes the challenge of organizing the contents of <code>$(document).ready()</code> to balance efficiency and maintainability.  My team accomplishes this by taking advantage of the Array behaviors of jQuery to structure our code so that function dictates form.  Put into practice, these behaviors will structurally organizing the code without imposing rules and processes&#8212;because we all know just how effective rules and processes are.</p><span id="more-427"></span>

<h2>Is a jQuery Object an Array?</h2>

<p>For any selection that you make, such as <code>$('.button')</code>, a jQuery object is returned.  This allows you to do a variety of tasks based on what is returned in the selector.</p>
<pre class="brush: jscript">if ($('.button').length > 0) {
...
}</pre>

<p>You can also iterate through the contents of the jQuery object:</p>

<pre class="brush: jscript">var selection = $('.button');
foreach(i = 0; i < selection.length; ++i) {
    selection[i].html('button #' + (i+1));
}</pre>

<p>Despite all of this behavior, the jQuery object cannot be treated as a true JavaScript array.  It is missing the first-class functions that we expect from a true array such as <code>.push()</code> or <code>.pop()</code>. The jQuery documentation often refers to this object as the matching set. I prefer this technology as it follows the behavior of sets and functions in abstract math&#8212;that sets are immutable and functions return new sets.</p>

<h2>Starting a Chain</h2>

<p>To understand the importance of this array-like behavior, we can look at the <a href="http://api.jquery.com/addClass/" target="_blank">jQuery API documentation</a> for <code>.addClass()</code>.  This function returns a jQuery object&#8212;which contains the set of elements on which we called it.  Unless the jQuery function modifies the matched set it was called against, returning a jQuery object implies that it is returning the original set. Even functions such as <code>.first()</code> or <code>.last()</code> return a set&#8212;it just contains a single object.</p>

<p>I typically define a chain as linking two or more jQuery functions together in a single statement as defined by the semicolon. In <a href="http://www.braindonor.net/blog/jquery-best-practices-part-1-managing-scope/406/">Part 1</a>, I used this chaining to select elements from the scope I passed to my jQuery function:</p>

<pre class="brush: jscript">scope.find('.button')
    .click(function(){
        alert("You Clicked The Button!");
    });</pre>

<p>I will place any chained function on a new, indented line when one of the following conditions have been met:</p>

<ol>
<li>The function being chained has a functioned embedded as one of the arguments.</li>
<li>The function being chained would create a line that would wrap in my editor.</li>
<li>Another function in the chain is on a new, indented line.</li>
</ol>

<p>I'm sure you'll notice that I did not give an explicit number of characters to a long line of code.  I have used far too many tools and editors to give you a 'best' number.  This number should already be something that your team is aware of in the rest of the development for a project.</p>

<h2>Putting it Into Practice</h2>

<p>I am a firm believer that this can, and should be taken further.  Take this example, where the same set of selections need multiple event handlers:</p>

<pre class="brush: jscript">scope.find('div.vehicle-button a').hover(
    function(){
        $(this).parent().addClass('vehicle-button-hover');
        $(this).parent().find('div.button').addClass('button-hover');
    },
    function(){
        $(this).parent().removeClass('vehicle-button-hover');
        $(this).parent().find('div.button').removeClass('button-hover');
    }
);
scope.find('div.vehicle-button a').mousedown(function(){
    $(this).parent().find('div.button').addClass('button-click');
});
scope.find('div.vehicle-button a').mouseup(function () {
        $(this).parent().find('div.button').removeClass('button-click');
});</pre>

<p>I find the above code disorganized and inefficient.  We are making multiple calls to <code>.find()</code> and <code>$(this)</code>.  Further, you can remove any single statement from the above and alter the behavior of the code dramatically.  I can organize the above int a single, chained statement:</p>

<pre class="brush: jscript">scope.find('div.vehicle-button a')
    .hover(
        function () {
            $(this).parent()
                .addClass('vehicle-button-hover')
                .find('div.button')
                .addClass('button-hover');
        },
        function () {
            $(this).parent()
                .removeClass('vehicle-button-hover')
                .find('div.button')
                .removeClass('button-hover');
        }
    )
    .mousedown(function () {
        $(this).parent()
            .find('div.button')
            .addClass('button-click');
    })
    .mouseup(function () {
        $(this).parent()
            .find('div.button')
            .removeClass('button-click');
    });</pre>

<p>Each line after the chain begins indents to illustrate the depth and links of the chain.  Instead of 3 statements, we have a single statement with the top line furthest to the left.  If we pick any line in the code, we can quickly and easily identify what is happening and all other related events by looking up and to the left.</p>

<p>One thing I must mention is that while I find the above code much easier on the eyes, it is space-inefficient.  Properly structured JavaScript code will always be space-inefficient.  If you want space-efficient JavaScript, you had better start looking at minifiers and not trying to optimize things on your own.  As most of my web development is on the .NET platform, <a href="http://www.braindonor.net/blog/visual-studio-fun-chirpy-is-awesome/356/" target="_blank">Chirpy</a> to minify and bundle my JavaScript files.</p>

<h2>Keeping the Chain from Breaking</h2>

<p>Any time we need to perform certain operations, the chain can come to a halt.  Say for instance we want to increase the height of all of the vehicle buttons by 5 pixels.  This is where we use <code>.each()</code> to keep the chain alive.</p>

<pre class="brush: jscript">scope.find('div.vehicle-button a')
    .each(function(){
        $(this).height($(this).height() + 5);
    })
    .hover (
    ...</pre>
<p><i>For the fully informed, this could have been done with <code>.css('height', '+=5')</code>.  I just couldn't think of another example off the top of my head.</i></p>

<p>One caveat with using <code>.each()</code> is that you still must pay close attention to the scope you are working in&#8212;the same as in any other anonymous function that you pass into a jQuery function.  This could potentially be another piece of my jQuery Best Practices guide, but won't be visited again for a while.  The next chapter of my guide will be how to handle insert elements into the DOM.</p>]]></content:encoded>
			<wfw:commentRss>http://www.braindonor.net/blog/thebraindonors-jquery-best-practices-part-2-chaining/427/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New WordPress Theme</title>
		<link>http://www.braindonor.net/projects/new-wordpress-theme/530/</link>
		<comments>http://www.braindonor.net/projects/new-wordpress-theme/530/#comments</comments>
		<pubDate>Thu, 16 Feb 2012 17:13:37 +0000</pubDate>
		<dc:creator>theBraindonor</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[Bootstrap]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.braindonor.net/?p=530</guid>
		<description><![CDATA[Welcome to the new and improved Braindonor Network. As you can see, I have completely updated the WordPress theme of this site. There are still some rough edges&#8212;but I liked the new theme so much that I was not willing to wait until everything was completely polished. The new theme is a combination of the [...]]]></description>
			<content:encoded><![CDATA[<p>Welcome to the new and improved Braindonor Network.  As you can see, I have completely updated the WordPress theme of this site.  There are still some rough edges&#8212;but I liked the new theme so much that I was not willing to wait until everything was completely polished.  The new theme is a combination of the <a href="ttp://www.plaintxt.org/themes/sandbox/" target="_blank">barebones Sandbox theme</a> and <a href="http://twitter.github.com/bootstrap/">Twitter's Bootstrap</a>.</p><span id="more-530"></span>

<p>I currently have a huge crush on Twitter's Bootstrap project.  It's the first "grid system" that I have used that felt like it was created by a developer instead of a designer.  Even more importantly, it provides a very application-centered set of components that can be leveraged in a web application.  I have been leveraging that last aspect in custom back-ends for some of the websites I build during the day.  It was only natural that I begin using it in my personal projects&#8212;and now to start including it on the front-end.</p>

<p>The new look isn't just aesthetic&#8230;it is responsive as well.  This website will now reform itself to accomodate mobile devices and older browsers seamlessly!  This is yet another offering of Bootstrap&#8212;the responsive layout.  I think it does a great job except for some font issues.  I read a lot of RSS-aggregated news on my mobile devices and wanted to make sure I could read my own blog easily from my phone.  There is also the added benefit of having implemented a responsive layout and being able to do so for others.  I can't say that I understand everything that is going on under the hood&#8230;but I'm getting there.</p>

<p>There are quite a few rough edges in the theme&#8212;with the comments first-and-foremost on my mind.  I'll keep working on everything and should have everything smoothed out in a week or so.</p>]]></content:encoded>
			<wfw:commentRss>http://www.braindonor.net/projects/new-wordpress-theme/530/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I&#8217;ve Joined the NoSQL Movement&#8230;How About You?</title>
		<link>http://www.braindonor.net/blog/ive-joined-the-nosql-movement-how-about-you/403/</link>
		<comments>http://www.braindonor.net/blog/ive-joined-the-nosql-movement-how-about-you/403/#comments</comments>
		<pubDate>Fri, 10 Feb 2012 22:13:53 +0000</pubDate>
		<dc:creator>theBraindonor</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[MVC3]]></category>
		<category><![CDATA[NoSQL]]></category>

		<guid isPermaLink="false">http://www.braindonor.net/?p=403</guid>
		<description><![CDATA[Leave it to O'Rielly to give a great summary of NoSQL&#8212;and express what I have been telling other developers. NoSQL is not a technology. It's a different way of looking at large data sets and data-driven applications. I have been busy adding NoSQL to my developer's utility belt lately by introducing MongoDB into the projects [...]]]></description>
			<content:encoded><![CDATA[<p>Leave it to O'Rielly to give a <a href="http://radar.oreilly.com/2012/02/nosql-non-relational-database.html" target="_blank">great summary of NoSQL</a>&#8212;and express what I have been telling other developers.  NoSQL is <i>not a technology</i>.  It's a different way of looking at large data sets and data-driven applications.  I have been busy adding NoSQL to my developer's utility belt lately by introducing <a href="http://www.mongodb.org/" target="_blank">MongoDB</a> into the projects that I am building.  I have already referenced my <a href="https://github.com/theBraindonor/BrainDonor.Mongo" target="_blank">BrainDonor.Mongo</a> project in some of my other posts.  I like to think of it as my formal announcement that I am a card-carrying member of the NoSQL movement.  For me, the movement is about not putting all my data eggs in one basket.  When it comes to development languages and platforms, I am a true polyglot programmer&#8212;and I <i>must</i> extend that further into data.</p><span id="more-403"></span>

<p>The primary reason I started looking at NoSQL do to it being an emerging trend.  I've used 'alternative' data stores previously, such as memcached...but that was always in <a href="http://www.braindonor.net/coding-blog/sqlalchemy-and-memcached/151/" target="_blank">support of an RDBMS</a>.  All it took was the right project to come past my desk, and I knew I had to take a crack at it.  I'm just finishing up a project at my day job geared towards event messaging.  Without disclosing any real details (and I can't...sorry) I can say that the platform needs to be able to process high volume, have the ability to scale up, and even the ability to scale down.  This platform is <a href="http://www.asp.net/mvc/mvc3">ASP.NET MVC3</a> on the front-end and <a href="http://www.mongodb.org/">MongoDB</a> on the back-end.</p>

<p><b>Why MongoDB?</b><br />
I've actually been following MongoDB since version 1.4 and playing around with its interactive shell and seen it grow considerably.  The community of professionals using MongoDB has grown even more so.  Best-practices in operations and architectures have been established and documented and the commercial company behind MongoDB, <a href="http://www.10gen.com/" target="_blank">10gen</a>, is growing strong. What sealed the deal for me was the push to ensure that MongoDB was a dependable backend for almost any development language.  Just take a peek at the <a href="http://www.mongodb.org/display/DOCS/Drivers" target="_blank">Drivers</a> page.</p>

<p>Enough of the soft reasons! Those just help me sell it to my partners in crime.  Here are some of the features of MongoDB and why I find them valuable. If it's not listed, it's not that I don't care.  All features are coming from the MongoDB website.</p>

<ul>
<li><b>Document-Oriented Storage</b><br />In my development, this feature is all about code-first.  My domain objects are simply serialized and stored in MongoDB.  I don't have to worry about updating tables, constraints or relationships.  I've included the repository model I'm using in my <a href="https://github.com/theBraindonor/BrainDonor.Mongo" target="_blank">BrainDonor.Mongo</a> project.<br /><br /></li>
<li><b>Replication &amp; High Availability</b><br />For me, this feature is all about being able to scale both up and down quickly, and easily.  A replication set can actually be entirely replaced without taking the databases offline.  I'm also looking forward to trying out some of the WAN replication on AWS between different zones.<br /><br /></li>
<li><b>Fast In-Place Updates</b><br />Updating a document can be done two different ways.  You can update the entire document or you can update only a single field.  Updating a document is not an atomic operation--but updating a single field is.  The single field operation that caught my attention immediately was the increment operation and how I could use it in a data reporting application.<br /><br /></li>
<li><b>GridFS</b><br />I want to build/use a CMS that uses this!  Even better, I want to be able to sync everything with a CDN.</li>
</ul>

<p>For what I am building right now, MongoDB is a great fit.  And if trends continue, I'm confident that I will be using more NoSQL storage engines in the coming years.  They are definitely <i>not</i> one-size-fits-all solutions.</p>

<p><b>Why ASP.NET MVC3?</b><br />
I get asked this question a lot even without the addition of NoSQL.  With all my experience with Open Source tools, why am I continuing to use C#?</p>

<ul>
<li><b>Web Development is Polyglot Development</b><br />Any rich web application will have JavaScript, HTML, and CSS regardless of the underlying platform.  This is compounded when you start introducing tools such as SASS, LESS, CoffeeScript, etc.  These applications are also not running in isolation.  How many external services did your last application integrate with?  There are countless reasons to integrate with social media, ecommerce, advertising and CRM systems.  How many of those are well documented for the back-end language you are developing with?<br /><br /></li>
<li><b>ASP.NET Finally Understands Open Source</b><br />With packages such as <a href="http://nuget.org/" target="_blank">NuGet</a>, I have a rich collection of libraries and utilities at my fingertips.  Microsoft is also <i>not</i> reinventing the wheel with their MVC framework.  It is very clear that the development team has been using and following other languages and MVC frameworks.  I am constantly using new, open source utilities as I build applications.<br /><br /></li>
<li><b>I Am Not Locked In</b><br />
My application most definitely is locked into the Microsoft stack...but I am not.  I have built and launched web applications in C#, Perl, PHP, Python, C++, C, and even an old Bash CGI powered site in my history.  Java and Ruby aren't in that list...but how long would it take me to get up to speed building an MVC application with either of those?  Java maps very closely to C# and Ruby maps very closely to Python.  In fact, I have only had one job that used a single stack exclusively.<br /><br />Wait...is this a worthy business reason?  Yes!  I'm a firm believer that mono-culture web development teams are a recipe for disaster.  Teams of polyglot developers aren't just agile with how they build a single application&#8212;they are agile in how they even think about building web applications.  These teams will usually program in one stack at a time, but switching stacks is never off the table.</li>
</ul>

<p>Back to coding with me!</p>]]></content:encoded>
			<wfw:commentRss>http://www.braindonor.net/blog/ive-joined-the-nosql-movement-how-about-you/403/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jQuery Best Practices Part 1: Managing Scope</title>
		<link>http://www.braindonor.net/blog/jquery-best-practices-part-1-managing-scope/406/</link>
		<comments>http://www.braindonor.net/blog/jquery-best-practices-part-1-managing-scope/406/#comments</comments>
		<pubDate>Thu, 09 Feb 2012 03:12:40 +0000</pubDate>
		<dc:creator>theBraindonor</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.braindonor.net/?p=406</guid>
		<description><![CDATA[I've been asked by a large number of developers if I know any solid jQuery best practices. The answer is a huge YES! I'm also getting around to changing my answer to their immediate follow-up. Do you have them written down so you can share them with me? In an effort to change my answer [...]]]></description>
			<content:encoded><![CDATA[<p>I've been asked by a large number of developers if I know any solid jQuery best practices.  The answer is a huge YES!  I'm also getting around to changing my answer to their immediate follow-up.  Do you have them written down so you can share them with me?  In an effort to change my answer to another huge YES, I am starting a series on jQuery Best Practices that will continue until I run out of steam.  The first best practice that I have to share is how to properly manage the scope of your jQuery scripts.</p><span id="more-406"></span>

<p><b>The Problem of Scope</b></p>

<p>Every developer I have talked to uses the following standard $(document).ready() invocation:</p>

<pre class="brush: jscript">$(document).ready(function()
    $('.button').click(function(){
        alert("You Clicked The Button!");
    });
});</pre>

<p>This invocation assumes one very significant behavior: <i>You will only be altering your DOM at page load...ever.</i>  I cannot stress enough how nasty of an assumption this is.  In almost any modern web application, the DOM is going to be changing after the page load.  I see countless developers encounter this when they first start looking at AJAX interactions using jQuery.  Their first reaction is almost always the same: run the $(document).ready() again...and hilarity ensues.  Not the good kind of hilarity...but the kind where it honestly feels like the browser itself is laughing at you.</p>

<p>The next step that many people take is to execute the necessary jQuery as part of the AJAX success handler like so:</p>

<pre class="brush: jscript">$.ajax({
    type: 'POST',
    url: 'http://mysite.com/ajaxurl',
    success: function(data) {
        $('.data-target').html(data);
        $('.data-target .button').click(function(){
            alert("You Clicked The Button!");
        });
    }
});</pre>

<p>Everything is now behaving as expected.  Unfortunately this behavior has come at the cost of a blatant DRY(Don't Repeat Yourself) violation.</p>

<p><b>How To Manage Scope</b></p>

<p>How I manage the scope of my jQuery scripts is founded on the following jQuery statements being equivalent:</p>

<pre class="brush: jscript">$('.button').click(function(){
    alert("You Clicked The Button!");
});</pre>

<pre class="brush: jscript">$(document).find('.button').click(function(){
    alert("You Clicked The Button!");
});</pre>

<p>In the first, I added the click handler in the standard manner.  In the second, I searched for the button class in the document.  These form the basis for my best practices because the second allows you to control the scope of the DOM that is being altered.  You can explicitly focus the scope of your jQuery by wrapping your script in the a function:

<pre class="brush: jscript">function my_button_jquery(scope){
    scope.find('.button').click(function(){
        alert("You Clicked The Button!");
    });
}</pre>

<p>Given this function, we can quickly rewrite the document ready from the first example script like so:</p>

<pre class="brush: jscript">$(document).ready(function()
    my_button_jquery($(this));
});</pre>

<p>And rewrite the ajax call in a similar manner:</p>

<pre class="brush: jscript">$.ajax({
    type: 'POST',
    url: 'http://mysite.com/ajaxurl',
    success: function(data) {
        $('.data-target').html(data);
        my_button_jquery($('.data-target'));
    }
});</pre>

<p>If you are one of the dozen people or so that ready my post on <a href="http://www.braindonor.net/coding-blog/jquery-and-asp-updatepanel-integration/328/" target="_blank">jQuery and ASP UpdatePanel Integration</a> you will recognize what I am doing here.</p>

<p><b>When to Break Scope</b></p>

<p>Now that we have additional control over the primary scope of our jQuery script, we need to understand where things are going to break.  The scope variable will only be reliable within the my_button_jquery function.  You must assume that this scope will be broken any time you enter into an anonymous function.  The reason for this is the asynchronous nature of the JavaScript event model.</p>

<p>This is why the above ajax call is not written with a scope inside the success handler:</p>

<pre class="brush: jscript">    success: function(data) {
        scope.find('.ajax-form-wrapper').html(data);
        my_button_jquery(scope.find('.ajax-form-wrapper'));
    }</pre>

<p><b>Notes on Efficiency</b></p>

<p>You should always invoke the jQuery object outside of your function to improve efficiency:</p>

<pre class="brush: jscript">$(document).ready(function () {
    my_button_jquery($(this));
});</pre>

<p>Not:</p>

<pre class="brush: jscript">$(document).ready(function () {
    my_button_jquery(document);
});</pre>

<p>Invoking a variable through jQuery is an expensive task that should only be performed once.  Many other bloggers have mentioned storing the result of $(this) in a variable to avoid repeated and unnecessary calls to the jQuery object.  I'm not a strict follower of that pracitice&#8212;because I am more than willing to knowingly introduce inefficiencies into executing to improve maintainability.  Instead I go for the low-hanging fruit such as invoking jQuery outside of my scoped initializer.</p>

<p>The other area where scoping can be inefficient is in the number of jQuery selections that will not perform any action.  Consolidating all of you script into a scoped initializer means that they will all be executed if an AJAX call updates the DOM.  I will cover this in my next post&#8212;which will cover chaining and flow control.</p>]]></content:encoded>
			<wfw:commentRss>http://www.braindonor.net/blog/jquery-best-practices-part-1-managing-scope/406/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Integrating Bootstrap Error styling with MVC&#8217;s Unobtrusive Error Validation</title>
		<link>http://www.braindonor.net/blog/integrating-bootstrap-error-styling-with-mvcs-unobtrusive-error-validation/381/</link>
		<comments>http://www.braindonor.net/blog/integrating-bootstrap-error-styling-with-mvcs-unobtrusive-error-validation/381/#comments</comments>
		<pubDate>Wed, 08 Feb 2012 04:28:32 +0000</pubDate>
		<dc:creator>theBraindonor</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Bootstrap]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[MVC3]]></category>

		<guid isPermaLink="false">http://www.braindonor.net/?p=381</guid>
		<description><![CDATA[A common component of many of the websites that I build are small administrative areas where clients are able to perform tasks such as downloading leads or scheduling appointments. Until recently, most of those websites were built to run on top of a content management framework--with the CMS providing most of the back-end interface that [...]]]></description>
			<content:encoded><![CDATA[<p>A common component of many of the websites that I build are small administrative areas where clients are able to perform tasks such as downloading leads or scheduling appointments.  Until recently, most of those websites were built to run on top of a content management framework--with the CMS providing most of the back-end interface that I deliver.  I started using Twitter's Bootstrap framework to deliver a consisten look and feel with our ASP.NET MVC3 applications.  Bootstrap provided me with a clean CSS grid system, clean controls, and a host of other components.  The biggest disconnect between Bootstrap and MVC3 is the unobtrusive validation.</p><span id="more-381"></span>

<a href="http://www.braindonor.net/wp-content/uploads/2012/02/bootstrap1.png"><img src="http://www.braindonor.net/wp-content/uploads/2012/02/bootstrap1-300x284.png" alt="" title="bootstrap1" width="300" height="284" class="alignright size-medium wp-image-382" /></a>

<p>I built the example administration pages in my MongoDB membership provider project as shown here.  It is a small, three controller area in the project that uses Bootstrap for all of its look and feel.  I am using all of the standard Razor html controls for the form elements with the form styled according to the Bootstrap <a href="http://twitter.github.com/bootstrap/base-css.html#forms" target="_blank">Base CSS</a>.</p>

<p style="clear: both;">Here is the CSHTML source for the username field:</p>

<pre class="brush: plain">        &lt;div class=&quot;control-group&quot;&gt;
            @Html.LabelFor(x =&gt; x.Username)
            &lt;div class=&quot;controls&quot;&gt;
                @Html.TextBoxFor(x =&gt; x.Username)
                @Html.ValidationMessageFor(x =&gt; x.Username)
            &lt;/div&gt;
        &lt;/div&gt;</pre>

<p>And the corresponding HTML that has been generated:</p>

<pre class="brush: plain">        &lt;div class=&quot;control-group&quot;&gt;
            &lt;label for=&quot;Username&quot;&gt;Username&lt;/label&gt;
            &lt;div class=&quot;controls&quot;&gt;
                &lt;input data-val=&quot;true&quot; data-val-required=&quot;Username is required&quot; id=&quot;Username&quot; name=&quot;Username&quot; type=&quot;text&quot; value=&quot;&quot; /&gt;
                &lt;span class=&quot;field-validation-valid&quot; data-valmsg-for=&quot;Username&quot; data-valmsg-replace=&quot;true&quot;&gt;&lt;/span&gt;
            &lt;/div&gt;
        &lt;/div&gt;</pre>

<a href="http://www.braindonor.net/wp-content/uploads/2012/02/bootstrap2.png"><img src="http://www.braindonor.net/wp-content/uploads/2012/02/bootstrap2-300x228.png" alt="" title="bootstrap2" width="300" height="228" class="alignright size-medium wp-image-386" /></a>

<p>If I skip entering in a username when I submit the form, the unobtrusive validation will change the validation &lt;span&gt; class from field-validation-valid to field-validation-error.  When using the provided CSS and HTML templating in a new MVC3 project, this will style the error message so that it is clearly marked.  However, this is not the desired marking for Bootstrap.  Bootstrap expects the error class name to be added to the &lt;div class="control-group"&gt; element.  We can emulate this in the browser using Firebug, resulting in clear indication of the fields with errors.  We add the error class to the control group div and the help-inline class to the validation span.</p>

<p>The first part of the solution is to add jQuery selections to our document ready routine to add the help-inline class to all validation spans:</p>

<pre class="brush: jscript">    $('span.field-validation-valid, span.field-validation-error').each(function () {
        $(this).addClass('help-inline');
    });</pre>

<p>The next piece requires some understanding of how the jquery.validate event model works.  We actually do not need to worry about the unobtrusive portion of of the validation as it is only used to configure jquery.validate.  When you first submit the form, control passes to jquery.validate functions submitHandler and invalidHandler.  Once those are called, jquery.validate will still call any existing submit handlers for the form and prevent the form from being submitted.  Inside the submit handler you can get the validation state of the form with the valid() function.</p>

<pre class="brush: jscript">    $('form').submit(function () {
        if ($(this).valid()) {
            $(this).find('div.control-group').each(function () {
                if ($(this).find('span.field-validation-error').length == 0) {
                    $(this).removeClass('error');
                }                
            });
        }
        else {
            $(this).find('div.control-group').each(function () {
                if ($(this).find('span.field-validation-error').length > 0) {
                    $(this).addClass('error');
                }                
            });
        }
    });</pre>

<p>Now we are adding and removing the necessary classnames so Bootstrap displays the error fields perfectly!  That is until we encounter a server-side validation error.  One more update and we'll be good to go</p>

<pre class="brush: js">    $('form').each(function () {
        $(this).find('div.control-group').each(function () {
            if ($(this).find('span.field-validation-error').length > 0) {
                $(this).addClass('error');
            }
        });
    });</pre>

<p>Have fun building with MVC3 and Bootstrap!</p>]]></content:encoded>
			<wfw:commentRss>http://www.braindonor.net/blog/integrating-bootstrap-error-styling-with-mvcs-unobtrusive-error-validation/381/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Get Chirpy To Play Nice with Twitter&#8217;s Bootstrap</title>
		<link>http://www.braindonor.net/blog/get-chirpy-to-play-nice-with-twitters-bootstrap/376/</link>
		<comments>http://www.braindonor.net/blog/get-chirpy-to-play-nice-with-twitters-bootstrap/376/#comments</comments>
		<pubDate>Mon, 06 Feb 2012 04:52:23 +0000</pubDate>
		<dc:creator>theBraindonor</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Bootstrap]]></category>
		<category><![CDATA[Chirpy]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[dotless]]></category>
		<category><![CDATA[VisualStudio]]></category>

		<guid isPermaLink="false">http://www.braindonor.net/?p=376</guid>
		<description><![CDATA[I have begun using Twitter's Bootstrap framework to build administration sites for the MVC apps that I am building. Bootstrap makes it trivial to keep all of the views clean and consistent--without needing to get a graphic designer involved. You can see it in action in the example app for my MongoDB utility project, BrainDonor.Mongo. [...]]]></description>
			<content:encoded><![CDATA[<p>I have begun using Twitter's <a href="http://twitter.github.com/bootstrap/" target="_blank">Bootstrap</a> framework to build administration sites for the MVC apps that I am building.  Bootstrap makes it trivial to keep all of the views clean and consistent--without needing to get a graphic designer involved.  You can see it in action in the example app for my MongoDB utility project, <a href="https://github.com/theBraindonor/BrainDonor.Mongo" target="_blank">BrainDonor.Mongo</a>.  Unfortunately, the bootstrap source .less files refuse to play nice with <a href="http://chirpy.codeplex.com/" target="_blank">Chipry</a>!</p><span id="more-376"></span>

<p>Why is this a problem? If I wish to make a simple change such as modifying colors in Bootstrap, the most consistent way to do this is in the .less sources.  In theory, I should be able to just include the bootstrap.less file in my Chirpy bundle and let it build everything.  The .less compiler included with Chirpy just isn't able to handle it.  I'm a lazy developer who to eat his cake, so how do I get a work-around in place quickly?</p>

<p>Going back to using <a href="https://github.com/dotless/dotless" target="_blank">dotless</a> is the key.  I previously used it for some clients to parse .less files on the server as they are requested by browsers.  This dependence on server-side parsing of less files is one of the main reasons that I moved to Chirpy.</p>

<p>To solve this, I have created folders named /Content/css and /Content/less.  I have downloaded the .less source files for bootstrap and placed them in the /Content/less folder.  The top level files for Bootstrap are bootstrap.less and responsive.less. Next, I created the following pre-build task for my web project:</p>

<pre class="brush: plain">$(SolutionDir)packages\dotless.1.2.2.0\tool\dotless.compiler.exe $(ProjectDir)Content\less\bootstrap.less $(ProjectDir)Content\css\bootstrap.css
$(SolutionDir)packages\dotless.1.2.2.0\tool\dotless.compiler.exe $(ProjectDir)Content\less\responsive.less $(ProjectDir)Content\css\responsive.css</pre>

<p>Please notice that I have removed the -m option so that dotless is not attempting to minimize the less files.  I prefer to only do that only once--and Chirpy has continued to compress .css files as expected.  Unfortunately, I do have to include the dotless version in the path...so this needs to be updated anytime I upgrade dotless.</p>

<p>Now, with just a quick build, dotless will compile the css files and Chirpy will bundle the css files as needed!</p>]]></content:encoded>
			<wfw:commentRss>http://www.braindonor.net/blog/get-chirpy-to-play-nice-with-twitters-bootstrap/376/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Visual Studio Fun: Chirpy is Awesome!</title>
		<link>http://www.braindonor.net/blog/visual-studio-fun-chirpy-is-awesome/356/</link>
		<comments>http://www.braindonor.net/blog/visual-studio-fun-chirpy-is-awesome/356/#comments</comments>
		<pubDate>Fri, 20 Jan 2012 17:11:46 +0000</pubDate>
		<dc:creator>theBraindonor</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[VisualStudio]]></category>

		<guid isPermaLink="false">http://www.braindonor.net/?p=356</guid>
		<description><![CDATA[Managing the CSS and JavaScript files of a website can be an extremely frustrating, but rewarding experience. I've been introducing tools at work to help manage this experience such as SASS, LESS, CoffeeScript, etc, with mixed results. By themselves, each of these tools do a great job, but how to I leverage their power together? [...]]]></description>
			<content:encoded><![CDATA[<p>Managing the CSS and JavaScript files of a website can be an extremely frustrating, but rewarding experience.  I've been introducing tools at work to help manage this experience such as SASS, LESS, CoffeeScript, etc, with mixed results.  By themselves, each of these tools do a great job, but how to I leverage their power together?  Having fifteen JS and CSS includes in a site is still extremely inefficient.  <a href="http://chirpy.codeplex.com/" target="_blank">Chirpy</a> is a tool that helps to bring all of this together in one plugin in Visual Studio...but I see a lot of people completely missing the most powerful feature of Chirpy: <a href="http://www.weirdlover.com/2010/07/18/chirpy-attains-godlike-abilities-in-version-1-0-0-4/#mash">FileGroups</a>.</p><span id="more-356"></span>

<p>This CSS and JS on my blog is admittedly inefficient.  I'm here to write about code, not spend all my time coding so that I can write about code.  However, it is a great example of how NOT to keep your JavaScript and CSS files organized: 10 individual CSS requests and 15 individual JavaScript requests.  If all of the JavaScript files were being called at just before the end of the body tag and if all of the CSS files are part of the same media type they can be combined into a single file.  I try to follow the <a href="http://developer.yahoo.com/yslow/" target="_blank">YSlow</a> conventions where possible.</p>

<img src="http://www.braindonor.net/wp-content/uploads/2012/01/chirpy_bundle.png" alt="" title="chirpy_bundle" width="358" height="538" class="alignright size-full wp-image-357" />

<p>Chirpy allows for this to be done in a Visual Studio project at build time.  If you have already gone through the tutorial and are starting to work through adding your own chirp files into Visual Studio.  You need to start maching files together with Chirpy using *.chirp.config files.  I've included a quick screenshot that I am using on a project to illustrate how I've organized things.  This is an ASP.NET MVC3 project.  I have included folders for css and javscript inside ~/Content/.  The Bundle.chirp.config file is pulling everything from there and generating five virtual files...and that is all of the content required for the entire site!</p>

<p>I have to mention that the ~/Scripts folder has been left alone as that is where the conventions dictate that JavaScript files should go. I break this convention and say that only <i>Library</i> JavaScript files that are provided by NuGet reside. In my projects, NuGet loads script files into ~/Scripts/, I load script files into ~/Content/js/.  I also have to note that my less files are <i>not</i> *.chirp.less files.  As we are using the FileGroup to  bundle everything together, Chirpy will parse those files when it compiles the group! You can also mix-and-match CSS, LESS and SESS files to your hearts content.</p>

<p>So what does my Bundle.chirp.config look like?</p>
<pre class="brush: plain">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
&lt;root xmlns=&quot;urn:ChirpyConfig&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemaLocation=&quot;urn:ChirpyConfig http://www.weirdlover.com/chirpy/chirp.xsd&quot;&gt;
    &lt;FileGroup Name=&quot;style.css&quot;&gt;
        &lt;File Path=&quot;css/fontface.less&quot; /&gt;
        &lt;File Path=&quot;css/reset.less&quot; /&gt;
        &lt;File Path=&quot;css/base.less&quot; /&gt;
        &lt;File Path=&quot;css/fonts.less&quot; /&gt;
        &lt;File Path=&quot;css/mixins.less&quot; Minify=&quot;false&quot; /&gt;
        &lt;File Path=&quot;css/layout.less&quot; Minify=&quot;false&quot; /&gt;
        &lt;File Path=&quot;css/homepage.less&quot; Minify=&quot;false&quot; /&gt;
        &lt;File Path=&quot;css/registration.less&quot; Minify=&quot;false&quot; /&gt;
    &lt;/FileGroup&gt;
    &lt;FileGroup Name=&quot;ie.css&quot;&gt;
        &lt;File Path=&quot;css/ie.less&quot; /&gt;
    &lt;/FileGroup&gt;
    &lt;FileGroup Name=&quot;script.js&quot;&gt;
        &lt;File Path=&quot;../Scripts/jquery-1.5.1.min.js&quot; Minify=&quot;false&quot; /&gt;
        &lt;File Path=&quot;js/ui.js&quot; Minify=&quot;false&quot; /&gt;
    &lt;/FileGroup&gt;--&gt;
    &lt;FileGroup Name=&quot;ielt9.js&quot;&gt;
        &lt;File Path=&quot;js/html5.js&quot; Minify=&quot;false&quot; /&gt;
    &lt;/FileGroup&gt;
    &lt;FileGroup Name=&quot;ie.js&quot;&gt;
        &lt;File Path=&quot;js/PIE.js&quot; Minify=&quot;false&quot; /&gt;
        &lt;File Path=&quot;js/selectivizr-min.js&quot; Minify=&quot;false&quot; /&gt;
    &lt;/FileGroup&gt;
&lt;/root&gt;</pre>

<p>Now i have the 5 files that I am ready to include.  Why 5 files?  I need to support IE 7,8,9.  The labels on the bundle give some hints to the logic, but looking at the HTML in the template should clear it all up.</p>

<p>Header HTML:</p>
<pre class="brush: plain">    &lt;link rel=&quot;stylesheet&quot; media=&quot;all&quot; href=&quot;/Content/style.css&quot; /&gt;
    &lt;!--[if lt IE 9]&gt;
        &lt;script src=&quot;/content/ielt9.js&quot;&gt;&lt;/script&gt;
    &lt;![endif]--&gt;
    &lt;!--[if lte IE 9]&gt;
        &lt;link rel=&quot;stylesheet&quot; media=&quot;all&quot; href=&quot;/Content/ie.min.css&quot; /&gt;
    &lt;![endif]--&gt;
&lt;/head&gt;</pre>

<p>Footer HTML:</p>
<pre class="brush: plain">    &lt;script src=&quot;/Content/script.js&quot;&gt;&lt;/script&gt;
    &lt;!--[if lte IE 9]&gt;
        &lt;script type=&quot;/Content/ie.js&quot;&gt;&lt;/script&gt;
    &lt;![endif]--&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>

<p>Now I have 13 files being reduced to 5.  I'm confident that I will be adding more files as I complete the project&#8212;and I am even more confident that 5 files are all that I will be including in my HTML pages.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.braindonor.net/blog/visual-studio-fun-chirpy-is-awesome/356/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>jQuery and ASP UpdatePanel Integration</title>
		<link>http://www.braindonor.net/blog/jquery-and-asp-updatepanel-integration/328/</link>
		<comments>http://www.braindonor.net/blog/jquery-and-asp-updatepanel-integration/328/#comments</comments>
		<pubDate>Tue, 01 Jun 2010 17:42:10 +0000</pubDate>
		<dc:creator>theBraindonor</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.braindonor.net/?p=328</guid>
		<description><![CDATA[With my latest gig sending me back into the .NET world, I have been busy migrating quite a few of my tools and experience to play nice with ASP.NET sites. One of my favorite open-source tools that is gaining popularity in .NET is jQuery. For several years now, I have been using jQuery heavily to [...]]]></description>
			<content:encoded><![CDATA[<p>With my latest gig sending me back into the .NET world, I have been busy migrating quite a few of my tools and experience to play nice with ASP.NET sites. One of my favorite open-source tools that is gaining popularity in .NET is <a href="http://jquery.com/" target="_blank">jQuery</a>. For several years now, I have been using jQuery heavily to provide rich interaction on websites. When faced with the basic UpdatePanel in ASP.NET, I was presented with a challenge. I wanted a solution that would automatically call jQuery so that new content was properly parsed and updated. Because I had been managing all the AJAX calls in my other development, this was trivially easy to do. UpdatePanel hides all of this inside the ASP AJAX libraries and scripts—making it difficult to figure out where and how to structure my jQuery code. After some research and experimentation, I have a solution up and running on multiple sites now that integrates everything in a very clean manner.</p><span id="more-328"></span>

<p><strong>Scoping jQuery Rewrites</strong><br />
The first step is to scope all of the jQuery rewrites. The typical method of integrating jQuery rewrites into a website is to add a document.ready function like so:</p>

<pre class="brush: js">$(document).ready(function() {
    $('.content_tab_button').click(function(){
        $('.content_tab_container').load('/newcontent.html');
    });
});</pre>

<p>Because the rewrites are only called when the document.ready event fires, integrating with new content pulled in from AJAX needs to be done differently. By placing our rewrites in a new function that recieves the scope being updated, we can have a single initialization handle all of the updating:</p>

<pre class="brush: js">function my_initializer(data){
    data.find('.content_tab_button').click(function(){
        $('.content_tab_container').load('/newcontent.html');
        my_initializer($('.content_tab_container').html());
    });
}
$(document).ready(function() {
    my_initializer($(document));
});</pre>

<p>Everything is now scoped cleanly. The rewrites are applied to the document when the page is loaded, and the new content when the tab button is clicked. Even if you are not an ASP.NET developer, please take the above scoping strategy with you!</p>

<p><strong>How The UpdatePanel Works</strong><br />
At the highest level, an UpdatePanel refreshes its entire contents when a specificied event occurs within the panel. Server-side, the event triggering the refresh is processed, and the entire page-stae is regenerated. Then, only the content inside the UpdatePanel is pushed out. This is important for any developer using UpdatePanel to understand: UpdatePanel is much more convenient than it is efficient. As a result, our solution must follow that model.</p>

<p>With that in mind, we look to javascript class that is already managing the UpdatePanel, the <a href="http://msdn.microsoft.com/en-us/library/bb311028.aspx" target="_blank">Sys.WebForms.PageRequestManager</a> class. In this class, we see an event handler for the <a href="http://msdn.microsoft.com/en-us/library/bb397523.aspx" target="_blank">pageLoad event</a>. In the documentation, you can see that we are able to fetch the update panels that were just updated. In the example, they are looking for a panel with a specific ID. In our case, we are looking at having our rewrites applied to any panel that was updated:</p>

<pre class="brush: js">var panels = args.get_panelsUpdated();
if (panels.length &gt; 0) {
    for (i = 0; i &lt; panels.length; i++) {
        my_initializer($(panels[i]));
    }
}</pre>

<p>Because we have already scoped our jQuery code, this will work like a charm.</p>

<p><strong>Putting It All Together</strong><br />
We can put all of the code together now, and we'll have a script that will play cleanly with the UpdatePanel:</p>

<pre class="brush: js">function my_initializer(data){
    data.find('.content_tab_button').click(function(){
        $('.content_tab_container').load('/newcontent.html');
        my_initializer($('.content_tab_container').html());
    });
}
function my_pageloaded_initializer(sender, args) {
    var panels = args.get_panelsUpdated();
    if (panels.length &gt; 0) {
        for (i = 0; i &lt; panels.length; i++) {
            my_initializer($(panels[i]));
        }
    }
}
$(document).ready(function() {
    my_initializer($(document));
    Sys.WebForms.PageRequestManager.getInstance()
        .add_pageLoaded(my_pageloaded_initializer);
});</pre>

<p>All of our rewrites are called once—and only once—during page load and UpdatePanel refresh. Enjoy!</p>]]></content:encoded>
			<wfw:commentRss>http://www.braindonor.net/blog/jquery-and-asp-updatepanel-integration/328/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

