<?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>Dogma/Geek</title>
	<atom:link href="http://geek.dogma.co.uk/feed/" rel="self" type="application/rss+xml" />
	<link>http://geek.dogma.co.uk</link>
	<description>Outlet for my techno babble.</description>
	<lastBuildDate>Thu, 11 Aug 2011 11:34:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Content Managing with Perch</title>
		<link>http://geek.dogma.co.uk/2011/03/content-managing-with-perch/</link>
		<comments>http://geek.dogma.co.uk/2011/03/content-managing-with-perch/#comments</comments>
		<pubDate>Fri, 04 Mar 2011 21:24:43 +0000</pubDate>
		<dc:creator>Richard Kimber</dc:creator>
				<category><![CDATA[Perch]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://geek.dogma.co.uk/?p=115</guid>
		<description><![CDATA[Perch, if you not already aware is a curious little PHP CMS by British design agency edgeofmyseat.com.  Curious because in an ecosystem dominated by feature rich, open source, free CMSs like WordPress and Drupal; Perch provides only one feature out of the box and costs about £40 per site including VAT. Curious because given this [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://grabaperch.com/">Perch</a>, if you not already aware is a curious little PHP CMS by British design agency <a href="http://edgeofmyseat.com/">edgeofmyseat.com</a>.  Curious because in an ecosystem dominated by feature rich, open source, free CMSs like WordPress and Drupal; Perch provides only one feature out of the box and costs about £40 per site including VAT. Curious because given this information, I'm still overwhelming drawn to Perch for a lot of my projects.</p>
<p>Why I'm drawn to Perch is the simplicity of the CMS itself. edgeofmyseat.com have found niche between the handful of static HTML files in a directory and site built from the ground up to be content managed.</p>
<p>WordPress for instance, makes it very easy to create a very manageable site in minutes, literally. I dropped the folder on to my server, ran the installer and two minutes later I had a fully content managed site. Amazing, and with such a large community supporting WordPress I had customised the look, feel and function of my site with some of the thousands of free themes and plugins on offer.</p>
<p>But what about the site I already have? The individual HTML pages, strung together with anchor tags and a splash of PHP or similar as the contact form required it. Or the client who is intimidated (or just disinterested) with admin screens filled with Posts, Comments, Plugins and Tools?</p>
<p>If I was to content manage that static site with WordPress, I'd have to extract a template from the many pages built by my predecessors and create a theme. Assuming that is the pages have retained a uniform appearance over time. Then I manually recreate each of the pages in the CMS and create (or find equivalent) plugins for all the little bits of bespoke functionality that WordPress doesn't quite deal with. The horrible feeling that developers get when retreading old ground.</p>
<p>Or, you install Perch. Perch is designed to let you work the way you want. You create your pages, your structure, add your images and navigation. Out of the box, Perch does one thing really well. When you're creating your pages and you come across section that needs to be edited by the client, drop in a content tag.</p>
<pre lang="php">&lt;?php perch_content("Dynamic Content"); ?&gt;</pre>
<p>You also need to tell Perch to watch the page; you do this by adding the following line to the top of the page:</p>
<pre lang="php">&lt;?php include("../perch/runtime.php"); ?&gt;</pre>
<p>What happens is this; when you subsequently load that page. Perch queries the database to see if it has any content for page X called 'Dynamic Content'. If Perch doesn't have a content region in that location, it creates one. The next time you log into Perch, you'll be provided with a content region called 'Dynamic Content' flagged as new.</p>
<p><a href="http://geek.dogma.co.uk/wp-content/uploads/2011/03/New-Content.png"><img class="aligncenter size-full wp-image-117" title="New Content" src="http://geek.dogma.co.uk/wp-content/uploads/2011/03/New-Content.png" alt="" width="500" height="87" /></a>Clicking on the region gives you the opportunity to define the content type from many built-in templates ranging from text to Google Analytics to images to blocks of code. If there isn't a template that suits your needs, create your own. You can also decide whether the content is recurring (like a list of posts) and whether content is to be shared between multiple pages.</p>
<p>So to go back to the example of that static site. Your client just wants to change the text on the front page, or update the news feed themselves. Just add a couple of PHP tags to the desired page, set the content type in the CMS and away you go. Replicating the existing news feed is as easy as copying one of the existing news items and pasting it into a new template, replacing the content with perch tags.</p>
<pre lang="html">&lt;perch:content id="heading" type="text" label="Heading" /&gt;</pre>
<p>In summary, Perch is easy to setup (install process similar to WordPress) and makes it incredibly easy to add content management to existing sites on PHP capable web servers. Perch also contains an elegant API for extending the core functionality in the form of Apps. Apps available for download from the Perch site provide blogging functionality and dynamic page creation amongst other things. Hopefully I'll get a chance to cover Apps and App development in another post. If you regularly deal with legacy sites or just want to simplify things a bit, I recommend you check Perch out.</p>
]]></content:encoded>
			<wfw:commentRss>http://geek.dogma.co.uk/2011/03/content-managing-with-perch/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing MySql on Windows 2008</title>
		<link>http://geek.dogma.co.uk/2011/02/installing-mysql-on-windows-2008/</link>
		<comments>http://geek.dogma.co.uk/2011/02/installing-mysql-on-windows-2008/#comments</comments>
		<pubDate>Thu, 24 Feb 2011 01:48:00 +0000</pubDate>
		<dc:creator>Richard Kimber</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://loserville.co.uk/?p=43</guid>
		<description><![CDATA[If you're installing MySql on a Windows box and you come up against the following error: Field `authentication-string` doesn't have a default value. It is likely that you have enabled 'Remote Access' as part of the configuration process. A bug in the installer tries to update the MySql User table with a NULL `authentication_string` value. [...]]]></description>
			<content:encoded><![CDATA[<p><strong></strong>If you're installing MySql on a Windows box and you come up against the following error:</p>
<blockquote><p>Field `authentication-string` doesn't have a default value.</p></blockquote>
<p>It is likely that you have enabled 'Remote Access' as part of the configuration process. A bug in the installer tries to update the MySql User table with a NULL `authentication_string` value.</p>
<p>I resolved this issue by running the following command in the Command Prompt:</p>
<p><code>&gt; mysql --user=root mysql<br />
&gt; alter table user modify `authentication_string` text COLLATE utf8_bin NULL;</code></p>
<p>And then continuing with the installation. Don't forget to open port 3306!</p>
<p>Rich</p>
]]></content:encoded>
			<wfw:commentRss>http://geek.dogma.co.uk/2011/02/installing-mysql-on-windows-2008/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jQuery Remote Validation with ASP.NET MVC</title>
		<link>http://geek.dogma.co.uk/2010/08/jquery-remote-validation-with-asp-net-mvc/</link>
		<comments>http://geek.dogma.co.uk/2010/08/jquery-remote-validation-with-asp-net-mvc/#comments</comments>
		<pubDate>Wed, 18 Aug 2010 23:26:00 +0000</pubDate>
		<dc:creator>Richard Kimber</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://loserville.co.uk/?p=42</guid>
		<description><![CDATA[Update 29/09/2010 I've included a sample project at the end of the post. The project can also be downloaded here: RemoteValidation.zip. Note: When I say ASP.NET MVC, this post only applies to version 2 and above, which at the time of writing includes MVC3 Preview 1. There is a bit of client-side magic that happens [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update 29/09/2010</strong></p>
<p><em>I've included a sample project at the end of the post. The project can also be downloaded here: <a href="http://dl.dropbox.com/u/12301555/Posts/RemoteValidation/RemoteValidation.zip">RemoteValidation.zip</a>.</em></p>
<hr />
<p><em>Note: When I say ASP.NET MVC, this post only applies to version 2 and above, which at the time of writing includes MVC3 Preview 1.</em></p>
<p>There is a bit of client-side magic that happens on some forms these days. You’ve probably seen it; you type in a username or an email address into a registration form and before you have finished entering the next field, the form is already telling you whether or not the username/email address has already been used. Or, maybe you’ve typed in a gift code that immediately validates (or not).</p>
<p>This magic, contrary to the belief of some posse’s of some Faygo wielding clowns, is not magic but a technique called “remote validation”. Remote Validation is providing validation on the client (using something like JavaScript, Flash or Silverlight) that can utilise server side logic by way of an Ajax request. In most cases, validating the input against your data store.</p>
<p>At this point it should be noted that I will be focusing on an implementation that relies on the jQuery Validation plug-in. If you would prefer to use the MSAJAX library, I will now point you to Brad Wilson’s excellent <a title="Remote Validation with ASP.NET MVC 2" href="http://bradwilson.typepad.com/blog/2010/01/remote-validation-with-aspnet-mvc-2.html">post</a> on the subject. My implementation is based on Brad’s, with a few differences, that I’ll mention on the way.</p>
<p>Okay to the implementation. As with a lot of things, jQuery makes our lives a lot easier. I expect <a href="http://ejohn.org/">John Resig</a> should at least take some credit for my steady marital status, I’m not getting complacent. jQuery offers a plug-in, one of not very many officially supported plug-ins, called jQuery Validate. I am sure you are already acquainted. The validation plug-in offers remote validation out of the box, the implementation is both incredibly simple and efficient. Below is an example borrowed (I’m not giving it back) from the <a title="Plugins/Validation/Methods/remote" href="http://docs.jquery.com/Plugins/Validation/Methods/remote">jQuery documentation</a>.</p>
<div>
<pre class="brush: javascript;">$("#myform").validate({
  rules: {
    email: {
      required: true,
      email: true,
      remote: "check-email.php"
    }
  }
});</pre>
</div>
<p>The above example says three things about the field called email.</p>
<ol>
<li>It’s required.</li>
<li>It’s and email address.</li>
<li>As an extra check, the browser should pass the email address to an endpoint called “check-email.php”.</li>
</ol>
<p>The remote endpoint has but one job, to return true or false (as a JSON object). It is up to you how that decision is arrived at. By default, this check is made either when the field loses focus or before the form is submitted.</p>
<p>That is fantastic if you can be bothered to write all of a long sentence each time, yeah I have better things to do like try and learn Japanese and the Ukulele simultaneously. Yeah, that’s how I roll, yo.</p>
<p>What we need to do is bake in some ASP.NET MVC wizardry. I have loved data annotations, since I first saw them in that scaffolding thing, umm Dynamic Data. Just awesome, one day I’d like to build a website with just a long string of attributes.</p>
<p>Okay, I’m going to assume that you are already familiar with how <code>Html.EnableClientValidation()</code> works for jQuery for the rest of this post. If there is any call for it, I focus on this on another post.</p>
<p>That assumed, we need to create a new Attribute to flag our property with. Our use case scenario will be a basic registration form (very basic) that requires a username, that has not already been used. Our model is below:</p>
<div>
<pre class="brush: c#;">using System.ComponentModel.DataAnnotations;

public class Reg {
 [HiddenInput(DisplayValue = false)]
 public int ID { get; set; }

 [StringLength(50), Required]
 public string Name { get; set; }

 [StringLength(250), Required]
 public string Email { get; set; }
}</pre>
</div>
<p>So our form is going to require a name and an email with maximum string lengths. Lets create an Attribute that says check me against something remote:</p>
<div>
<pre class="brush: c#;">using System;
using System.ComponentModel.DataAnnotations;
using System.Configuration;

[AttributeUsage(AttributeTargets.Property)]
public class RemoteAttribute : ValidationAttribute {
 #region Properties
 public string Key { get; set; }
 public string[] AdditionalProperties { get; set; }
 #endregion

 #region Methods
 public virtual string GetUrl() {
  return ConfigurationManager.AppSettings[Key];
 }

 public override bool IsValid(object value) {
  return true;
 }
 #endregion
}</pre>
</div>
<p>The key difference between mine and Brad’s Remote Attribute, is the way the remote URL is retrieved. Brad’s URL is baked straight into the Attribute, whereas mine is takes the URL from a Web Config <code>AppSetting</code>. I made this change because I tend to reuse models between projects and didn’t want my routing to be dictated to by my model. In the future I would like to have the option to set the URL in the Global.asax, so I can make use of <a title="T4MVC: a T4 template for ASP.NET MVC" href="http://mvccontrib.codeplex.com/wikipage?title=T4MVC">T4MVC</a>’s strongly typed ActionResults.</p>
<p>I have also added a string array called <code>AdditionalProperties</code>, this will contain a list of additional properties that I also want to pass to the remote endpoint. This is useful if you don’t want to invalidate an email address on a registration, because it already exists on the registration you’re currently editing. I’m going to infer my parameter name from the property.</p>
<p>If you haven’t read Brad’s post, I should mention that we’re returning true in <code>IsValid()</code> because this Attribute will not be performing traditional server-side validation. This is not because I’m lazy, but rather because we don’t know what that validation will be until it is implemented. I am quite lazy.</p>
<p>We’re also going to need an Adapter. An Adapter tells the compiler how to pass the Attribute to the client. Here it is:</p>
<div>
<pre class="brush: c#;">using System.Collections.Generic;
using System.Web.Mvc;

public class RemoteAttributeAdapter : DataAnnotationsModelValidator&lt;RemoteAttribute&gt; {
 public RemoteAttributeAdapter(ModelMetadata metadata, ControllerContext context, RemoteAttribute attribute) : base(metadata, context, attribute) { }

 public override IEnumerable&lt;ModelClientValidationRule&gt; GetClientValidationRules() {
  var rule = new ModelClientValidationRule {
   ErrorMessage = ErrorMessage,
   ValidationType = "remote"
  };

  rule.ValidationParameters["url"] = Attribute.GetUrl();
  rule.ValidationParameters["type"] = "post";
  rule.ValidationParameters["additionalProperties"] = Attribute.AdditionalProperties; ;

  return new[] { rule };
 }
}</pre>
</div>
<p>For the most part this Adapter is just pairing up my attribute’s properties with the parameter’s of the jQuery validation plug-in. The only property that isn’t like for like at this stage is the <code>additionalParameters</code> parameter, this will map to a jQuery parameter called <code>data</code>.</p>
<p><em>Note: I’ve also hardcoded that the request be a POST. Bad practice, possibly, but I can’t see a call of this nature legitimately being a GET. I am posting information for comparison, not to specifically get information. You may have your own take on this, in which case you are free to adjust your implementation.</em></p>
<p>Which brings to the second example provided by the jQuery documentation:</p>
<div>
<pre class="brush: javascript;">$("#myform").validate({
  rules: {
    email: {
      required: true,
      email: true,
      remote: {
        url: "check-email.php",
        type: "post",
        data: {
          username: function() {
            return $("#username").val();
          }
        }
      }
    }
  }
});</pre>
</div>
<p>In the example, additional parameters are sent to the endpoint to add context to the validation method. I will replicate this in my client-side validation. My client-side validation will not be reinventing the wheel, I will be building on the file called MicrosoftMvcJQueryValidation.js. This file was originally provided in some of the preview releases of ASP.NET MVC2, and I can now never bloody find, so will include the script in it’s entirety at the bottom of this post. For now though, lets look at the additions I have made:</p>
<div>
<pre class="brush: javascript;">function __MVC_ApplyValidator_Remote(object, validationParameters, fieldName) {
 var obj = object["remote"] = {};
 var props = validationParameters.additionalProperties;

 obj["url"] = validationParameters.url;
 obj["type"] = validationParameters.type;

 obj["beforeSend"] = function () {
  var elementName = fieldName + "_validationMessage";
  $("#" + elementName).addClass("remote");
 };

 obj["complete"] = function () {
  var elementName = fieldName + "_validationMessage";
  $("#" + elementName).removeClass("remote");
 };

 if (props) {
  var data = {};

  for (var i = 0, l = props.length; i &lt; l; ++i) {
   var param = props[i];
   data[props[i]] = function () {
    return $("#" + param).val();
   }
  }

  obj["data"] = data;
 }
}</pre>
</div>
<p>The above block of code is added at around line 32, and maps the ASP.NET MVC generated JS to a jQuery Validate object. In additional to what you might have been expecting, I have also bound to two event handlers. This allows me to provide field by field loading indications the user “Hey user, I’m doing something clever to this field.” I do this in addition to <code>ajaxStart</code> and <code>ajaxStop</code>.</p>
<p>If you focus in on the for statement, you’ll see that I’m iterating through the <code>additionalParameters</code> array to produce a data parameter exactly the same in function as in the second  jQuery example.</p>
<p>Let’s look at the second addition I’ve made:</p>
<div>
<pre class="brush: javascript;">// Line 110
function __MVC_CreateRulesForField(validationField, fieldName) {

// Line 137
   case "remote":
    __MVC_ApplyValidator_Remote(rulesObj, thisRule.ValidationParameters, fieldName);
    break;

// Line 156
  rulesObj[fieldName] = __MVC_CreateRulesForField(validationField, fieldName);</pre>
</div>
<p>In the addition above I am simply adding an extra case into the switch that determines which adapter method to fire. This was necessary because I require the field name to be passed to the adapter.</p>
<p>Right, we’re almost there. Just four more steps:</p>
<div>
<pre class="brush: c#;">DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(RemoteAttribute), typeof(RemoteAttributeAdapter));</pre>
</div>
<p>Step One: Add the above line of code to the <code>Application_Start</code> method of your Global.asax.</p>
<div>
<pre class="brush: c#;">using System.ComponentModel.DataAnnotations;

public class Reg {
 [HiddenInput(DisplayValue = false)]
 public int ID { get; set; }

 [StringLength(50), Required, Remote(Key = "name-test", AdditionalProperties = new[] { "ID" })]
 public string Name { get; set; }

 [StringLength(250), Required]
 public string Email { get; set; }
}</pre>
</div>
<p>Step Two: Adjust our model to include the new RemoteAttribute. I’m telling the attribute to look for an <code>AppSetting</code> of “name-test” in web.config.</p>
<div>
<pre class="brush: xml;">&lt;add key="name-test" value="/Home/NameTest"/&gt;</pre>
</div>
<p>Step Three: Add an <code>AppSetting</code> called “name-test” to your web.config.</p>
<div>
<pre class="brush: c#;">public virtual ActionResult NameTest() {
 return Json(true);
}</pre>
</div>
<p>Step Four: If you have not already done so, create your end point.</p>
<p>Discussing the creation of the form is beyond the scope of this post, mainly because it is dead easy and would sit better in a general post about jQuery validation with ASP.NET MVC. I will clarify that you need to reference jQuery and jQuery Validate. You will also need to add <code>Html.EnableClientValidation()</code> to the top of your form.</p>
<p>So what have we done here. We have created an Attribute and an AttributeAdapter pair that will allow you to describe a remote interaction between the server and your model. We have registered this Attribute/Adapter pair in our Global.asax file, so ASP.NET knows to look out for it. We have then transformed the interaction into a state that jQuery can the use using our modified MicrosoftMvcJQueryValidation.js file.</p>
<p>You can download a sample project at the following location: <a href="http://dl.dropbox.com/u/12301555/Posts/RemoteValidation/RemoteValidation.zip">RemoteValidation.zip</a>. If you're just interested in the amended MicrosoftMvcJQueryValidation.js file, it can be downloaded here: <a href="http://dl.dropbox.com/u/12301555/Posts/RemoteValidation/MicrosoftMvcJQueryValidation_remote.js">MicrosoftMvcJQueryValidation_remote.js</a></p>
]]></content:encoded>
			<wfw:commentRss>http://geek.dogma.co.uk/2010/08/jquery-remote-validation-with-asp-net-mvc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Request.IsAjaxRequest()</title>
		<link>http://geek.dogma.co.uk/2010/07/request-isajaxrequest/</link>
		<comments>http://geek.dogma.co.uk/2010/07/request-isajaxrequest/#comments</comments>
		<pubDate>Tue, 13 Jul 2010 22:30:00 +0000</pubDate>
		<dc:creator>Richard Kimber</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://loserville.co.uk/?p=41</guid>
		<description><![CDATA[Hi, This is just a quick post to explain how Request.IsAjaxRequest() knows that a request sent to the server is an Ajax request rather than a traditional browser request. First of all though, what is an Ajax request? Well strictly speaking, the X in the acronym AJAX stands for XMLHttpRequest. XMLHttpRequest is an object, created [...]]]></description>
			<content:encoded><![CDATA[<p>Hi,</p>
<p>This is just a quick post to explain how Request.IsAjaxRequest() knows that a request sent to the server is an Ajax request rather than a traditional browser request.</p>
<p>First of all though, what is an Ajax request? Well strictly speaking, the X in the acronym AJAX stands for XMLHttpRequest. XMLHttpRequest is an object, created by Microsoft at the turn of the century, which allows the sending of HTTP requests using JavaScript (the J). The acronym was first coined by Jesse Garrett in 2005, but has mutated, in meaning, over time. The term Ajax now encompasses a number of alternate techniques for transferring data without need of a page refresh, i.e. Flash and iframes.</p>
<p>So you could say an Ajax request is quite an elusive fish, and you'd be right, if a little odd for using the word 'fish'. Aside from the multiple techniques that encompass Ajax, you have the fact that each technique is using the HTTP protocol. They are, in sense, mimicking a traditional browser request. So, there is really no way to tell the difference between a browser request and an Ajax request.</p>
<p>Am I saying that Request.IsAjaxRequest() doesn't work then? No, it'd be a pretty crap and decidedly pointless post if that was the case. I am in fact building a sense of excitement, and now the big reveal.</p>
<p>Request.IsAjaxRequest() is a test; a method for testing a request as it hits the server for one of two things:</p>
<ol>
<li>A header called X-Requested-With with the value XMLHttpRequest.</li>
<li>The Request collection (encompassing QueryString and Form) contains a key value pair, where X-Requested-With is the key and XMLHttpRequest is the value.</li>
</ol>
<p>Be advised that in both cases ASP.NET MVC is case sensitive.</p>
<p>What is particularly great about this solution is that, the convention is already in use in both the MSAJAX and jQuery libraries, as well as others I understand. If you prefer your JavaScript vanilla, then it is a simple step to apply either of the two prerequisites above.</p>
<p>Rich</p>
]]></content:encoded>
			<wfw:commentRss>http://geek.dogma.co.uk/2010/07/request-isajaxrequest/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ajax Forms with ASP.NET MVC and jQuery</title>
		<link>http://geek.dogma.co.uk/2010/02/ajax-forms-with-asp-net-mvc-and-jquery/</link>
		<comments>http://geek.dogma.co.uk/2010/02/ajax-forms-with-asp-net-mvc-and-jquery/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 12:54:00 +0000</pubDate>
		<dc:creator>Richard Kimber</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://loserville.co.uk/?p=40</guid>
		<description><![CDATA[This post uses jQuery, jquery.form.js, jquery.validate.js, ASP.NET MVC 2 and .NET 4. I’ve been content loading my projects for a little while now using a graceful Ajax technique that combines jQuery with MVC PartialViews. Please see this post1 for more information. This technique works fine with GET requests but I recently had a requirement for [...]]]></description>
			<content:encoded><![CDATA[<p><em>This post uses jQuery, jquery.form.js, jquery.validate.js, ASP.NET MVC 2 and .NET 4.</em></p>
<p>I’ve been content loading my projects for a little while now using a graceful Ajax technique that combines jQuery with MVC PartialViews. Please see this <a title="Graceful modals with ASP.NET MVC2 &amp; jQuery" href="http://blog.dogma.co.uk/2010/01/graceful-modals-with-aspnet-mvc2-jquery.html">post</a><sup>1</sup> for more information.</p>
<p>This technique works fine with GET requests but I recently had a requirement for a form within some “content loaded” content. The whole point of content loading is that the HTML should be semantically correct and work without the need for JavaScript, so I obviously wanted to keep the form as clean as possible.</p>
<div>
<pre class="brush: html;">&lt;div class="form-wrapper"&gt;
 &lt;%= Html.ValidationSummary() %&gt;
 &lt;% using (Html.BeginForm("Edit", "Pages")) { %&gt;
 &lt;%= Html.EditorForModel() %&gt;
 &lt;input type="submit" name="submit" value="Submit" /&gt;
 &lt;%= Html.Encode(TempData["Message"]) %&gt;
 &lt;% } %&gt;
&lt;/div&gt;</pre>
</div>
<p>The example above is a very simple but incredibly scalable form thanks to EditorForModel, however notice that I’m not using any Ajax Extension Methods. I try to reduce dependence on the Microsoft JavaScript libraries whenever possible. This is not out of any particular dislike for those libraries, I just prefer jQuery and want to keep my file sizes down. The form above is placed in a PartialView, as per the fore mentioned Graceful Modals post, which is in term referenced by a parent View. We’ll call the View FormView and the PartialView _FormView.</p>
<p>We’ll also employ the Graceful Modals technique in the Controller actions, as seen below, by using AjaxView in place of View.</p>
<div>
<pre class="brush: c#;"> // Edit
 public virtual ActionResult FormView(int id) {
  return AjaxView(_modelService.Load(id));
 }

 [HttpPost]
 public virtual ActionResult FormView(ModelOfChoice model) {
  if (!ModelState.IsValid)
   return AjaxView(model);

  // Save to Database
  _modelService.Save(model);
  TempData["Message"] = "Record Saved.";

  return AjaxRedirectToAction(MVC.Something.FormView(model.ID));
 }</pre>
</div>
<p>A new method is used here called AjaxRedirectToAction, I’m still undecided on the best implementation, but a few signatures I’ve been playing around with can be seen below. You should also note that I try and create signatures to be compatible with <a title="T4MVC: a T4 template for ASP.NET MVC" href="http://aspnet.codeplex.com/wikipage?title=T4MVC">T4MVC</a><sup>2</sup> when possible.</p>
<div>
<pre class="brush: c#;"> protected ActionResult AjaxRedirectToRoute(RouteValueDictionary routeValues, Func&lt;ActionResult&gt; ajaxCallback) {
  if (Request != null &amp;&amp; Request.IsAjaxRequest())
   return ajaxCallback();

  return RedirectToRoute(routeValues);
 }

 protected ActionResult AjaxRedirectToRoute(RouteValueDictionary routeValues) {
  return AjaxRedirectToRoute(routeValues, () =&gt; { return Content("ok"); });
 }

 protected ActionResult AjaxRedirectToRoute(ActionResult result) {
  return AjaxRedirectToRoute(result.GetRouteValueDictionary(), () =&gt; { return AjaxView(); });
 }</pre>
</div>
<p>The purpose of this method is to implement the Redirect-After-Post pattern for non JavaScript requests.</p>
<p>All that is left to do now is wire up the JavaScript. Firstly, I’m going to make slight change to jquery.form.js. The change deals with the over zealous caching by all versions of Internet Explorer, whereby IE doesn’t differentiate based on headers. By default Microsoft Ajax and jQuery use a header to signify that a request originates in JavaScript. When designing a graceful solution, you must accept that within the same session a user may access Actions with either a standard request or an Ajax request. If the user is exposed to a combination, we want to make sure the browser is displaying the correct output for the right request.</p>
<p>MVC makes allowances for the fact that not all environments allow custom headers to be sent with a request, by allowing the header value to be sent as a Query String parameter. IE does differentiate on Query Strings, so the change to jquery.form.js will add this parameter. The change is added at line 62.</p>
<div>
<pre class="brush: c#;"> var ajaxified = url;
 if (ajaxified.indexOf("?") &gt;= 0)
  ajaxified += "&amp;";
 else ajaxified += "?";
 ajaxified += "X-Requested-With=XMLHttpRequest";

 url = ajaxified;</pre>
</div>
<p>The last job is the wire up itself, which is an almost out-of-the-box implantation of jquery.validate.js and jquery.form.js. The code is below.</p>
<div>
<pre class="brush: javascript;"> $("form").validate({
  submitHandler: function(form) {
   $(form).ajaxSubmit({
    target: ".form-wrapper"
   });
  }
 });</pre>
</div>
<p>At this point we should have a form that posts back to the server using Ajax or a standard page request, dependent on the existence of JavaScript. These forms should live quite happily within dynamically generated content and server rendered content.</p>
<p>A production implementation of this technique can be seen at <a href="http://21wappinglane.com">http://21wappinglane.com</a>.</p>
<ol>
<li><a title="Graceful modals with ASP.NET MVC2 &amp; jQuery" href="http://blog.dogma.co.uk/2010/01/graceful-modals-with-aspnet-mvc2-jquery.html">http://blog.dogma.co.uk/2010/01/graceful-modals-with-aspnet-mvc2-jquery.html</a></li>
<li><a title="T4MVC: a T4 template for ASP.NET MVC" href="http://aspnet.codeplex.com/wikipage?title=T4MVC">http://aspnet.codeplex.com/wikipage?title=T4MVC</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://geek.dogma.co.uk/2010/02/ajax-forms-with-asp-net-mvc-and-jquery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rolling with the Project Ball</title>
		<link>http://geek.dogma.co.uk/2010/02/rolling-with-the-project-ball/</link>
		<comments>http://geek.dogma.co.uk/2010/02/rolling-with-the-project-ball/#comments</comments>
		<pubDate>Sun, 14 Feb 2010 22:34:00 +0000</pubDate>
		<dc:creator>Richard Kimber</dc:creator>
				<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://loserville.co.uk/?p=39</guid>
		<description><![CDATA[A while ago I came across a post on Devirtuoso, on creating a 3D sphere using jQuery. There is fantastic demo on the post, but what really made it stand out was a lack of dependency on the canvas element, so it should be cross browser compatible. That is exceptional and when my colleagues found [...]]]></description>
			<content:encoded><![CDATA[<p>A while ago I came across a <a href="http://www.devirtuoso.com/2009/09/3d-sphere-using-jquery/">post</a> on <a href="http://www.devirtuoso.com/">Devirtuoso</a>, on creating a 3D sphere using <a title="jQuery" href="http://jquery.com">jQuery</a>. There is fantastic demo on the post, but what really made it stand out was a lack of dependency on the canvas element, so it should be cross browser compatible. That is exceptional and when my colleagues found out about it, it was decided, this needs to power our new portfolio page.</p>
<p>“Okay”, I said. “That should be fine.” They do know how bad my maths is, don’t they?</p>
<p>The big idea. We are currently redeveloping the <a href="http://inkdigitalagency.com">Ink Creations</a> web site, the old site had been up for a few years and little had changed. We want the new site to be a reflection of the way we work/think with each page exploring a different aspect. Like a programmers playground, but more polished. One of these pages is our <a href="http://inkdigitalagency.com/portfolio">portfolio</a>. We wanted to present our portfolio in an interesting new way while still remaining accessible. The 3D sphere gives us the interesting, but not so much the accessible. The sphere is comprised of plus signs that are generated in JavaScript, which are invisible to screen readers and search engines.</p>
<p>There are other issues with the sphere, in the context of our requirements:</p>
<ol>
<li>Each of the plus signs would need to be replaced with a unique portfolio image, but the rendering of the sphere allows for duplication of plus signs.</li>
<li>The default behaviour of the sphere is to react to the position of the mouse, but to be constantly on the move. This makes tracking a particular plus sign very difficult. We would need our project images to be easily clicked.</li>
<li>The plus signs are all the same solid colour, so there is no need to worry about the z-index of each element. With individual portfolio images, you don’t want the images at the back overlapping the ones at the front. No, no you don’t.</li>
</ol>
<p>Lets deal with accessibility first. I still want to see a portfolio with JavaScript is switched off. The 3D sphere uses an unordered list which is good enough for me. So I start off by pre-rendering a list of each of our projects as an unordered list. Within the 3DEngine.js file I need to check for this and recreate the list if it doesn’t already exist.</p>
<pre class="brush: javascript;">//if there isn't a ul than it creates a list of +'s
if (container.children("ul").length === 0) {
	var $ul = $("&lt;ul&gt;&lt;/ul&gt;").appendTo(this.container);
	for (i = 0; i &lt; this.pointsArray.length; i++) {
		var project = g_projects[idx];

		$ul.append("&lt;li&gt;&lt;img id=\"item" + i + "\" class=\"" + project.id + "\" src=\"/Image/Project/" + project.thumbnail.id + "?height=320&amp;width=390\" /&gt;&lt;/li&gt;");

		idx = nextIndex(idx, g_projects);
	}
}</pre>
<p>I have created a global array of the projects called g_projects and have referenced it directly from 3DEngine.js. Now it is just a case of creating images instead of b elements. The pre-rendered ul list contains anchor tags as well, so the images are clickable. The fact that I haven’t done it in JavaScript is probably an oversight on my part.</p>
<p>We are now accessible, with JavaScript switched off we get an unordered list of portfolio images. With JavaScript switch on the images form a spinning ball.</p>
<p>While we’re in 3DEngine.js, we’ll deal with the z-index.</p>
<div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:8ba8b033-59cb-4063-a9ef-814dc185b638" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px;">
<pre class="brush: javascript;">currItem.style.height = (37.5 * currItem.scale) + "px";
currItem.style.width = (50 * currItem.scale) + "px";

$(currItem).css({ opacity: (currItem.scale - .5), zIndex: Math.ceil((currItem.scale - .5) * 100) });</pre>
</div>
<p>Using the scale that has already been provided I’m adjusting the photo’s size, opacity and z-index. This should hopefully add to the illusion of depth.</p>
<p>Sphere.js is where I encountered some difficulty. As previously mentioned mathematics isn’t my strongest attribute. The Sphere objects constructor takes three parameters; radius, sides and numOfItems. These parameters make up the configuration of the resulting sphere and as such can’t be applied randomly, it would seem. For instance, increasing the numOfItems may well increase the number of portfolio images, but will not necessarily increase the complexity of the sphere. Additional images occupy the space of existing images leading to undesirable results.</p>
<p>I’m positive the relationship between the three parameters can be worked out mathematically, I just haven’t worked out that relationship yet. Until I do, my solution has been to control which images are created based on their coordinates. This will remove the chance of images occupying the same space, but does require a little fiddling (with radius and sides) as our portfolio increases. This isn’t a huge concern as I believe our current portfolio count is already testing the CPU usage or your average browser to it’s limits, but any help in determining the fore said relationship would be very much appreciated. The code for Sphere.js is below:</p>
<div>
<pre class="brush: javascript;">var Sphere = function (radius, sides, numOfItems) {
	var arr = new Array();
	var totalPerSide = Math.ceil(numOfItems / sides);
	var comparer = ["x", "y", "x"];

	for (var j = 1; j &lt; (sides + 1); ++j) {
		for (var i = 0; i &lt; totalPerSide; ++i) {
			if (this.pointsArray.length &gt;= numOfItems)
				break;

			var angle = i * Math.PI * 2 / totalPerSide;
			var angleB = j * Math.PI * 2 / sides;

			var x = Math.sin(angle) * Math.sin(angleB) * radius;
			var y = Math.cos(angle) * Math.sin(angleB) * radius;
			var z = Math.cos(angleB) * radius;

			x = Math.round(x * 100) / 100;
			y = Math.round(y * 100) / 100;
			z = Math.round(z * 100) / 100;

			var points = { x: x, y: y, z: z };
			if (!arr.contains(points, comparer)) {
				arr.push(points);
				this.pointsArray.push(this.make3DPoint(x, y, z));
			}
		}
	}

	delete arr;
};

Sphere.prototype = new DisplayObject3D();

Array.prototype.unique = function () {
	var r = new Array();
	o: for (var i = 0, n = this.length; i &lt; n; i++) {
		for (var x = 0, y = r.length; x &lt; y; x++) {
			if (r[x] == this[i]) {
				continue o;
			}
		}
		r[r.length] = this[i];
	}
	return r;
};

Array.prototype.contains = function (obj, properties) {
	for (var i = 0, n = this.length; i &lt; n; i++)
		if (_equals(this[i], obj, properties))
			return true;

	return false;
};

var _equals = function (a, b, properties) {
	if (!properties)
		return a == b;

	for (var i = 0; i &lt; properties.length; i++)
		if (a[properties[i]] != b[properties[i]])
			return false;

	return true;
};</pre>
</div>
<p>I believe this leaves us with the issue of actually selecting a project and clicking on the image for more information.</p>
<div>
<pre class="brush: javascript;">var g_portfolio = (function () {
	$(document).ready(function () {
		if (g_speed &amp;&amp; g_speed.isSlow())
			return;

		var camera = new Camera3D();
		camera.init(0, 0, 0, 300);

		var container = $("#item");

		container.css({
			margin: "0 auto",
			top: "46%",
			position: "absolute",
			left: "50%"
		});

		container.find("ul").css({
			position: "static"
		});

		container.find("img").css({
			position: "absolute",
			zIndex: 100
		});

		container.find("div").remove();

		var item = new Object3D(container);
		var sphere = new Sphere(175, 13, _projectCount);
		item.addChild(sphere);

		var scene = new Scene3D();
		scene.addToScene(item);

		var mouseX = 600;
		var mouseY = 0;
		var offsetX = $("#item").offset().left;
		var offsetY = $("#item").offset().top;
		var speed = 15000;
		var moving = null;

		$("#controls").click(function (evt) {
			evt.preventDefault();

			if (moving)
				stopTracking();
			else startTracking();
		});

		$("#item a").click(function (evt) { evt.preventDefault(); });

		$("#item img")
				.hover(function () {
					stopTracking();

					var $this = $(this);
					$this.data("state.3d", $.extend({}, { height: $this.height(), width: $this.width(), opacity: $this.css("opacity") }, $this.position()));
					$this.animate({ height: "+=18px", width: "+=18px", opacity: 1, top: "-=9px", left: "-=9px" });
				}, function () {
					var $this = $(this);
					var state = $this.data("state.3d");
					$this.stop(false, true).css(state);

					startTracking();
				})
				.click(function (evt) {
					location.href = "/portfolio/carousel/" + $(this).attr("class");
				});

		var animateIt = function () {
			if (!moving)
				return;

			if (mouseX != undefined) {
				axisRotation.y += (mouseX) / speed
			}

			if (mouseY != undefined) {
				axisRotation.x -= mouseY / speed;
			}

			scene.renderCamera(camera);
		};

		var mouseMove = function (evt) {
			mouseX = evt.clientX - offsetX - (container.width() / 2);
			mouseY = evt.clientY - offsetY - (container.height() / 2);
		}

		var startTracking = function () {
			$(document).mousemove(mouseMove);
			moving = setInterval(animateIt, 20);
		};

		var stopTracking = function () {
			$(document).unbind("mousemove", mouseMove);
			clearInterval(moving);
			moving = null;
		};

		startTracking();

		var $img = container.find("img");
		var imgCount = $img.length;
		var overflow = imgCount - sphere.pointsArray.length;

		if (overflow &gt; 0) {
			var offset = (imgCount - overflow);
			var margin = 20;
			var withMargin = $img.width() + margin;
			var left = -((withMargin * overflow) / 2) + (margin * 2);

			for (var i = 0; i &lt; overflow; ++i) {
				$img.eq(offset + i).css({
					left: left,
					top: 0
				});
				left += withMargin;
			}
		}
	});
})();</pre>
</div>
<p>In the code above, I have refined the initialisation of the sphere to allow for the addition of a stop/start button. The sphere pauses when the mouse moves over an image, the said image then slightly increases in size to give emphasis. The last section of the above example deals with the remaining projects that didn’t fit within the sphere. It’s not ideal, but after running a few scenarios, I’ve found that I’m not able to guarantee a sphere that will encompass all projects, sometimes there is a remainder. These projects are lined up in the centre of the sphere.</p>
<p>And that is the current incarnation of our portfolio page. The full site is still under development and I’m sure the portfolio section still has some cosmetic changes to come. My prediction is some sort of featured projects sphere with a link to a full list. Until that happens, all the code is available uncompressed on the portfolio, when finalised and we’ve optimised the performance reasons, I’ll endeavour post the source to a follow up post. Our portfolio page can be found <a title="http://inkdigitalagency.com/portfolio" href="http://inkdigitalagency.com/portfolio">http://inkdigitalagency.com/portfolio</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://geek.dogma.co.uk/2010/02/rolling-with-the-project-ball/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>jQuery plug-in for summing attributes</title>
		<link>http://geek.dogma.co.uk/2010/02/jquery-plug-in-for-summing-attributes/</link>
		<comments>http://geek.dogma.co.uk/2010/02/jquery-plug-in-for-summing-attributes/#comments</comments>
		<pubDate>Wed, 03 Feb 2010 17:31:00 +0000</pubDate>
		<dc:creator>Richard Kimber</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Plugins]]></category>

		<guid isPermaLink="false">http://loserville.co.uk/?p=38</guid>
		<description><![CDATA[I love functions like foreach() and map() as a way for quickly arrogating through jQuery objects. I had a requirement to create a similar function today. I’m sure it has been done before but I couldn’t a direct equivalent within jQuery itself. The function is called sum() and takes one parameter called “callback” and is [...]]]></description>
			<content:encoded><![CDATA[<p>I love functions like foreach() and map() as a way for quickly arrogating through jQuery objects. I had a requirement to create a similar function today. I’m sure it has been done before but I couldn’t a direct equivalent within jQuery itself.</p>
<p>The function is called sum() and takes one parameter called “callback” and is directly related to it’s namesake in the map() function. The purpose of the function is to sum an attribute of each of the given elements. The “callback” parameter is a function that allows you to select the element’s attribute to be summed.</p>
<p>The summing component of the plug-in was taken from a <a href="http://snippets.dzone.com/posts/show/769">code snippet</a> on DZone.</p>
<p>The complete code along with an example is listed below:</p>
<pre class="brush: javascript">/// &lt;reference path="jquery-1.3.2-vsdoc.js" /&gt;

(function ($) {
 if (!Array.prototype.sum)
  Array.prototype.sum = function () {
   for (var i = 0, sum = 0; i &lt; this.length; sum += this[i++]);
   return sum;
  };

 $.fn.sum = function (callback) {
  return this.map(callback).get().sum();
 };
})(jQuery);</pre>
<pre class="brush: javascript">var heightOfFirstElement = $(".element").height();
var combinedHeightOfAllElements = $(".element").sum(function () { return $(this).height(); });</pre>
]]></content:encoded>
			<wfw:commentRss>http://geek.dogma.co.uk/2010/02/jquery-plug-in-for-summing-attributes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Graceful modals with ASP.NET MVC2 &amp; jQuery</title>
		<link>http://geek.dogma.co.uk/2010/01/graceful-modals-with-asp-net-mvc2-jquery/</link>
		<comments>http://geek.dogma.co.uk/2010/01/graceful-modals-with-asp-net-mvc2-jquery/#comments</comments>
		<pubDate>Sun, 31 Jan 2010 11:38:00 +0000</pubDate>
		<dc:creator>Richard Kimber</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://loserville.co.uk/?p=37</guid>
		<description><![CDATA[Update 28/09/2010 I've included a sample project at the end of the post. The project can also be downloaded here: GracefulModals.zip. I don’t profess to understand all of what MVC2 has to offer in terms of Ajax interoperability, so I maybe off base with a technique I’ve been working on to create graceful modals with [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update 28/09/2010</strong></p>
<p><em>I've included a sample project at the end of the post. The project can also be downloaded here: <a href="http://dl.dropbox.com/u/12301555/GracefulModals.zip">GracefulModals.zip</a>.</em></p>
<hr />
<p>I don’t profess to understand all of what MVC2 has to offer in terms of Ajax interoperability, so I maybe off base with a technique I’ve been working on to create graceful modals with a minimal repetition of mark-up. So I welcome feedback inclusive of constructive criticism.</p>
<p>What do I mean by graceful modals? Well, I believe the web in general should make sense without JavaScript or CSS switched on. It won’t be brilliant or really exciting, but it should be work semantically with buttons and links that do stuff. No broken forms and no links that go nowhere.</p>
<p>Okay, but what about the modals? Well modals don’t make a lot of sense to a non JavaScript world and who wants pop-ups? The link (to the modal) has got to do something, so it might as well still link to the modal content. This is graceful, an anchor tag that opens up a modal when JavaScript is switched on but still links to content when JavaScript is switched off.</p>
<p>In the past I would have created a Web Service or a Page Method to populate the modal using XML or JSON. In the past I have even been known to pre-render the modal on the server.</p>
<p>Shudder.</p>
<p>While there is nothing wrong with Web Service/Page Method technique, it is very close to what I now use. But for me at least, the implementation involved repetition of mark-up, sometimes hard coded directly into JavaScript.</p>
<p>Yuck.</p>
<p>What do I do now? I use MVC2 exclusively for new projects. Before MVC came out I had found myself completely disillusioned with the Web Forms environment and was considering drastic steps towards Java or PHP. MVC saved me from such horrors, changing the way I think about the interaction between client and server.</p>
<p>To clarify, I found the PostBack model of Web Forms to restrictive and the Server controls full of semantically incorrect mark-up. Upset Web Form developers can just assume I’m to stupid to understand it. I was totally joking about PHP and Java, I wouldn’t have considered making the move if I didn’t have respect. But seriously after using VS2010 any other IDE would be like flints and rock. Ug-ug.</p>
<p>I’m pretty sure the technique I use works in MVC1 on .NET 3.5, but be warned any code samples will be illustrated using MVC2/.NET4.</p>
<p>The first thing I do when creating a modal window, is create a standard page (Index) that links to another very standard page (Index2). This is my foundation, it works absent of any enhancements that will be added later.</p>
<p>If you are familiar with MVC you will know that these pages are Views and the link is to an Action that returns the second of the two Views.</p>
<p>At the moment, the Action that returns the second of the two Views (Indesx2) returns a fully marked up HTML page including header and body tags, etc… This isn’t going to be any good for dynamically populating a modal, so we need to split out the mark-up that we want to display in the modal without any duplication.</p>
<p>Keep it DRY folks.</p>
<p>The best way to do this is with a Partial, so I’ll create one called _Index2. I picked up the underscore naming convention from another post (can’t remember which) and have found it very handy as you can run into problems naming your Partials the same as your Views. Especially when you start treating Views as Partials, but that is a another story.</p>
<p>I’ve put the main content portion of my Index2 View into my _Index2 Partial and now need to reference _Index2 (Partial) from Index2 (View), which is easily done with the following code:</p>
<pre class="brush: html">&lt;% Html.RenderPartial("_Index2"); %&gt;</pre>
<p>Which I have shortened ever so slightly to:</p>
<pre class="brush: html">&lt;% Html.RenderPartial(); %&gt;</pre>
<p>With the following helper that assumes the underscore naming convention:</p>
<pre class="brush: csharp">public static void RenderPartial(this HtmlHelper helper) {
  helper.RenderPartial(String.Format("_{0}", helper.ViewContext.RouteData.Values["action"].ToString()));
}</pre>
<p>My Index2 View now looks like:</p>
<pre class="brush: html">&lt;%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %&gt;

&lt;asp:Content ContentPlaceHolderID="MainContent" runat="server"&gt;
  &lt;% Html.RenderPartial(); %&gt;
&lt;/asp:Content&gt;</pre>
<p>And my Index2 Partial looks like:</p>
<pre class="brush: html">&lt;%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %&gt;
&lt;p&gt;
  content&lt;/p&gt;</pre>
<p>I want to do one more thing to my mark-up. I will add a class to the anchor on my Index View to signify that I want the content to open up in a modal, which is shown below:</p>
<pre class="brush: csharp">&lt;%= Html.ActionLink("Index2", MVC.Home.Index2(), null, new { @class = "modal" }) %&gt;</pre>
<p>If you run all this now, you’ll notice no difference, clicking on the anchor in Index will still link to the Index2 View with content still intact. What I will do now, is create my modal. For the purposes of this post, I am just going to add a div called “modal” to my Master page. The fore mentioned div will be the container for our dynamic content.</p>
<p>Before we go on to the JavaScript, we need to make sure we can retrieve the content from Index2 without all the template HTML from the Master/View. To do this, I am going to enlist the help of a method I have created in the Controller called AjaxView. It works just like the View method but with an Ajax twist. The code is below:</p>
<pre class="brush: csharp">protected ActionResult AjaxView(string viewName = null, object model = null) {
  if (RouteData != null &amp;&amp; String.IsNullOrEmpty(viewName))
   viewName = RouteData.Values["action"].ToString();
  if (Request != null &amp;&amp; Request.IsAjaxRequest())
   return PartialView(String.Format("_{0}", viewName), model);
 return View(viewName, null, model);
}

protected ActionResult AjaxView(object model) {
  return AjaxView(null, model);
}</pre>
<p>The key to AjaxView is the extension method IsAjaxRequest. You can bing IsAjaxRequest for a full explanation but essentially the magic behind this method is in the client side libraries that support it. Libraries like jQuery and MsAjax add a header to Ajax requests to identify the request as being Ajax rather than a standard page request. IsAjaxRequest checks for this header and returns true if the header is found.</p>
<p>Our Index2 Action will now look like this:</p>
<pre class="brush: csharp">public virtual ActionResult Index2() {
  return AjaxView();
}</pre>
<p>With any luck, the standard page requests to /Home/Index2 will be directed to Index2.aspx and Ajax requests will be directed to _Index2.ascx. Let’s Ajaxify that request!</p>
<p>We’re going to do this with the following jQuery click event wrapped in a document ready event:</p>
<pre class="brush: javascript">$("a.modal").click(function(evt) {
  var $this = $(this);
  $("#modal").html("");

  evt.preventDefault();

  var url = $this.attr("href");
  if (url &amp;&amp; url != "")
   $("#modal").load(url, function(responseText, textStatus, xhr) {
    if (textStatus == "error") {
     $("#modal").html("&lt;p&gt;An error has occurred, please try again later.&lt;/p&gt;");
     return;
    }

    if ($.isFunction(callback))
     callback(textStatus);
   });
});</pre>
<p>The jQuery above attaches a click event handler to every anchor with a class of “modal”. The handler over overrides the standard click behaviour of the anchor and instead makes an Ajax request based on the anchor’s href attribute. The Ajax request is made using jQuery’s load function which is pointing at our modal div. The load function makes the request and populates the modal div with the response.</p>
<p>There we have it. Now, when we click on the anchor in Index (with JavaScript switched on) the page is not refreshed but instead the content from Index2 is dynamically loaded into the modal div. Clicking on the same link with JavaScript switched off still directs the browser to Index2 as before. This have been achieved with no duplication of mark-up using C# methods and JavaScript functions that can be reused with very little effort. Graceful.</p>
<p>You can download a sample project at the following location: <a href="http://dl.dropbox.com/u/12301555/GracefulModals.zip">GracefulModals.zip</a>.</p>
<p><strong>Related Links</strong></p>
<ul>
<li><a href="http://jquery.com">jQuery</a></li>
<li><a href="http://www.asp.net/mvc/">ASP.NET MVC</a></li>
<li><a href="http://blogs.msdn.com/davidebb/">Angle Bracket Percent</a></li>
<li><a href="http://blog.dogma.co.uk/2010/02/ajax-forms-with-aspnet-mvc-and-jquery.html">Ajax Forms with ASP.NET MVC and jQuery</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://geek.dogma.co.uk/2010/01/graceful-modals-with-asp-net-mvc2-jquery/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Did everyone else know this?</title>
		<link>http://geek.dogma.co.uk/2010/01/did-everyone-else-know-this/</link>
		<comments>http://geek.dogma.co.uk/2010/01/did-everyone-else-know-this/#comments</comments>
		<pubDate>Sat, 23 Jan 2010 22:16:00 +0000</pubDate>
		<dc:creator>Richard Kimber</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>

		<guid isPermaLink="false">http://loserville.co.uk/?p=36</guid>
		<description><![CDATA[We were messing around in a MVC 2 project the other day, when we came across a need to manipulate the class name of a DIV element in a Master Page from a View. I was going to start messing around with ViewData and whatnot but I really didn’t want to put too much effort [...]]]></description>
			<content:encoded><![CDATA[<p>We were messing around in a MVC 2 project the other day, when we came across a need to manipulate the class name of a DIV element in a Master Page from a View. I was going to start messing around with ViewData and whatnot but I really didn’t want to put too much effort into it. We were only likely to change the class name a couple of times so I wanted a quick and easy solution. Laziness is the mother of workarounds.</p>
<p>What we came up with was really quick and really easy, it also freaks Intellisense out. We put a Content Placeholder in the class value of the DIV. At the time it felt crazy, wondrous and groundbreaking, now it feels a little obvious. But I wanted to share anyway.</p>
<p>Here is a snippet from the Master Page:</p>
<pre class="brush: html">&lt;div class="&lt;asp:ContentPlaceHolder ID="ClassName" runat="server" /&gt;"&gt;</pre>
<p>And the corresponding View:</p>
<pre class="brush: html">&lt;asp:Content ContentPlaceHolderID="ClassName" runat="server"&gt;my-class&lt;/asp:Content&gt;</pre>
<p>Shazaaam! I can now tag up templated elements server side in mark up.</p>
]]></content:encoded>
			<wfw:commentRss>http://geek.dogma.co.uk/2010/01/did-everyone-else-know-this/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AttachFile Plug-in</title>
		<link>http://geek.dogma.co.uk/2009/03/attachfile-plug-in/</link>
		<comments>http://geek.dogma.co.uk/2009/03/attachfile-plug-in/#comments</comments>
		<pubDate>Sun, 15 Mar 2009 22:52:00 +0000</pubDate>
		<dc:creator>Richard Kimber</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Plugins]]></category>

		<guid isPermaLink="false">http://loserville.co.uk/?p=35</guid>
		<description><![CDATA[I’m preparing a release to CodePlex and the Windows Live Gallery of my Windows Live Writer plug-in Attach File. The battery on my laptop is about to run out though so I honestly can’t be bothered with the MSI file that is a requirement of the Gallery submission. So, at the bottom of this post [...]]]></description>
			<content:encoded><![CDATA[<p><a title="attachfile" href="http://www.flickr.com/photos/33829444@N00/3358164392/"><img style="display: block; float: none; margin-left: auto; margin-right: auto;" src="http://static.flickr.com/3622/3358164392_a299ab326f.jpg" border="0" alt="attachfile" width="397" height="355" /></a></p>
<p>I’m preparing a release to <a title="CodePlex" href="http://www.codeplex.com">CodePlex</a> and the <a title="Windows Live Gallery" href="http://gallery.live.com">Windows Live Gallery</a> of my <a title="Windows Live Writer" href="http://windowslivewriter.spaces.live.com">Windows Live Writer</a> plug-in Attach File. The battery on my laptop is about to run out though so I honestly can’t be bothered with the MSI file that is a requirement of the Gallery submission. So, at the bottom of this post is a direct link to a zip containing the DLLs needed to add the plug-in functionality to Live Writer. Simply drag the two files to the Plugins folder of the Windows Live Writer installation directory.</p>
<p>I should note that the second of the two files is a third party DLL from CodePlex that provides the FTP communications layer. I will eventually do my own, but credit where it is due. The FTP project can be located at <a title="FTPClient" href="http://ftpclient.codeplex.com/">http://ftpclient.codeplex.com/</a>.</p>
<p>Also, the icon is from <a title="FamFamFam" href="http://www.famfamfam.com/lab/icons/silk/">FamFamFam</a>. And yes, the link below was created using AttachFile.</p>
<p><a href="http://www.dogma.co.uk/AttachFile.zip">AttachFile.zip</a></p>
]]></content:encoded>
			<wfw:commentRss>http://geek.dogma.co.uk/2009/03/attachfile-plug-in/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

