blog.dogma.co.uk

Wednesday, 3 February 2010

jQuery plug-in for summing attributes

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 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.

The summing component of the plug-in was taken from a code snippet on DZone.

The complete code along with an example is listed below:

/// <reference path="jquery-1.3.2-vsdoc.js" />

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

 $.fn.sum = function (callback) {
  return this.map(callback).get().sum();
 };
})(jQuery);
var heightOfFirstElement = $(".element").height();
var combinedHeightOfAllElements = $(".element").sum(function () { return $(this).height(); });

Sunday, 31 January 2010

Graceful modals with ASP.NET MVC2 & jQuery

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.

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.

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.

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.

Shudder.

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.

Yuck.

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.

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.

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.

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.

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.

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.

Keep it DRY folks.

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.

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:

<% Html.RenderPartial("_Index2"); %>

Which I have shortened ever so slightly to:

<% Html.RenderPartial(); %>

With the following helper that assumes the underscore naming convention:

public static void RenderPartial(this HtmlHelper helper) {
  helper.RenderPartial(String.Format("_{0}", helper.ViewContext.RouteData.Values["action"].ToString()));
}

My Index2 View now looks like:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ContentPlaceHolderID="MainContent" runat="server">
  <% Html.RenderPartial(); %>
</asp:Content>

And my Index2 Partial looks like:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<p>
  content</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:

<%= Html.ActionLink("Index2", MVC.Home.Index2(), new { @class = "modal" }) %>

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.

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:

protected ActionResult AjaxView(string viewName = null, object model = null) {
  if (RouteData != null && String.IsNullOrEmpty(viewName))
   viewName = RouteData.Values["action"].ToString();
  if (Request != null && Request.IsAjaxRequest())
   return PartialView(String.Format("_{0}", viewName), model);
 return View(viewName, null, model);
}

protected ActionResult AjaxView(object model) {
  return AjaxView(null, model);
}

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.

Our Index2 Action will now look like this:

public virtual ActionResult Index2() {
  return AjaxView();
}

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!

We’re going to do this with the following jQuery click event wrapped in a document ready event:

$("a.modal").click(function(evt) {
  var $this = $(this);
  $("#modal").html("");

  evt.preventDefault();

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

    if ($.isFunction(callback))
     callback(textStatus);
   });
});

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.

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.

Related Links

Saturday, 23 January 2010

Did everyone else know this?

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.

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.

Here is a snippet from the Master Page:

<div class="<asp:ContentPlaceHolder ID="ClassName" runat="server" />">

And the corresponding View:

<asp:Content ContentPlaceHolderID="ClassName" runat="server">my-class</asp:Content>

Shazaaam! I can now tag up templated elements server side in mark up.

Sunday, 15 March 2009

AttachFile Plug-in

attachfile

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 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.

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 http://ftpclient.codeplex.com/.

Also, the icon is from FamFamFam. And yes, the link below was created using AttachFile.

AttachFile.zip

Attach To Process

Just a quick note on debugging Windows Live Writer plug-ins. I only mention it because I have not seen it discussed elsewhere, you can attach Visual Studio to the Live Writer process. Attaching to the Live Writer process enables you to step through the code line by line, as you would a Windows Forms App in Visual Studio.

If you are already developing Live Writer plug-ins, you may be aware that by adding the following line to the Post Build Event, you can import the plug-in directly into Live Writer upon completion of a successful build.

post build

XCOPY /D /Y /R "$(TargetPath)" "C:\Program Files\Windows Live\Writer\Plugins\"

On loading up Live Writer after successful build, switch back to Visual Studio and click on Debug > Attach to Process. You’ll now be presented with a window similar to the one in the screenshot below.

Attach

Double clicking on WindowsLiveWriter.exe will now provide debugging capabilities to the plug-in. Try it, create a a couple of break points and start interacting with the plug-in in Live Writer. I use this same technique for debugging Windows Services.

Wednesday, 4 March 2009

Setting Up a Windows Service Project in VS2008

Setting up, debugging and deploying a windows service can be a daunting task, but it is actually relatively straight forward. Relative to something ever so slightly more difficult to a console application.

Before I jump into the steps I have one piece of advice that has helped me side step a lot of grief. It is possible to debug a windows service using Visual Studio, by installing it on your development machine. The process can become a bit laborious though, in the early stages of development. My advice is to write all the guts of your service in a separate class library and add that library (as a reference) to a console application in the same solution. Use the console application to debug the majority of your code before adding the windows service project. You can then debug the various service state changes with the windows service itself.

Also, I have noticed that running a windows service on Vista is not exactly the same as running a service on Windows Server 2003. I don’t always do it, but I recommend some sort of internal logging so that you can work out any quirks without the aide of Visual Studio. I have my own code, that I am preparing to add to my K3R library, but I notice Live Labs have there own library on CodePlex now. The Live Labs logging library can be found here.

  1. Add a windows service project. Add references to your class libraries, if you have them.
  2. Open up Service1.cs (I’ve renamed mine to Service.cs) in design mode. This can be achieved by right clicking on Service.cs and selecting “View Designer”.
  3. Right click anywhere on the grey area of Service.cs and select “Add Installer”. This creates a new file called ProjectInstaller.cs.
  4. In the design mode of Project Installer.cs, I renamed serviceProcessInstaller1 to ServiceProcessInstaller and selected the account I would the service to run under. This is all done by selecting what was serviceProcessInstaller1 and opening the Properties window.
  5. I also renamed serviceInstaller1 to ServiceInstaller and personalised a few of the Misc properties; Description, Service Name, etc… The important property here though, is StartType. The selections you make here should be self explanatory.
  6. Add a setup project to the solution. I called mine ServiceSetup.
  7. Right click on the ServiceSetup project and click Add > Project Output. Select the windows service project from the drop down and add the project’s “Primary output” to setup project.
  8. Right click on the Service Setup project again and click View > Custom Actions. Right click on the root of Custom Actions and click Add Custom Action. Select the “Primary output” (of the Service project) from the Application Folder.
  9. Set up the properties of the new setup project, getting briefly annoyed that there isn’t a British locale.
  10. You are there. Providing your solution builds, you’re ready to install your service on a test machine. Remeber, you will have to start the service manually first of all, even if you have set the StartType to Automatic.

I should say, this post really constitutes a quick start guide and if you’re looking for more detailed information, I recommend an excellent series of posts on Arcane Code, links of which I’ve listed below.

  1. Getting Started
  2. Getting Started
  3. Adding the Installer
  4. Debugging Windows Services
  5. Controlling Your Service from Visual Studio
  6. Controlling Your Service from Another Application
  7. Sending Commands to your Windows Service
  8. Pulling in the Event Log for your Windows Service

Tuesday, 3 March 2009

Operator, can you connect me to 555 Coolsville?

I’ve admired the operator keyword from afar for some time, the ability to overload operators and conversions is pretty wicked. It wasn’t until this morning that I had a requirement, so I’ve had a little play, in order to understand the basics.

My first experiment was very basic, my intention was to create a class that I can add together using the + operator. The code is below.

public class Account {
 public int Balance { get; set; }

 public static int operator + (Account a, Account b) {
   return a.Balance + b.Balance;
 }
}

var a = new Account { Balance = 5 };
var b = new Account { Balance = 5 };

int totalBalance = a + b; // 10

Now I happen to think that is pretty smart. My example was very basic, but think of all of the calculations that could be encapsulated within an operator overload. Within this framework you could calculate multiple property values and even output to a secondary custom class representing a balance sheet.

This last example was created to understand the relationship between calculations involving more than two instances of a class. Before I continue, I realise there are already short cuts in place to quickly create Generic lists. This example overloads the % operator to allow the quick creation of Generic lists. What is particularly interesting is that you can describe the relationships between your class and any other class that it may encounter.

public class Account {
 public int Balance { get; set; };

 public static List operator %(Account a, Account b) {
  return new List {
   a,
   b
  };
 }

 public static List operator %(List a, Account b) {
  a.Add(b);
  return a;
 }
}

var a = new Account { Balance = 5 };
var b = new Account { Balance = 5 };
var c = new Account { Balance = 6 };

(a % b % c).Count; // 3

Imagine the example above returning a custom collection or another object that allowed you to query the three accounts simultaneously for balances and other financial totals.