Pop-up Previews with Prototype
My friend Chris recently mentioned that he was looking for a way to create pop-up previews. For example, displaying an image of a product when you hover over the item in a shopping cart. It's a solved problem with things like Nick Stackenburg's ProtoTip, but as I've never built something like that before myself, I thought I'd give it a go. Armed with prototype, here's what I came up with.
I wanted it to be as simple as possible, preferably a one-liner like this:
hookUpPreviewTo( 'example1' );
Where example1 is the id of an element on the page, and there is another element with an id of example1_preview. Convention over configuration ;)
There are basically two events you need to handle in order to show and hide the preview: onmouseover, and onmouseout.
hookUpPreviewTo = function( item ) {
repositionPreviewFor( item );
$( item ).observe( 'mouseover', showPreview );
$( item ).observe( 'mouseout', hidePreview );
}
Ignoring line 2 for a moment, line 3 and 4 are prototype magic. $(item) grabs a reference to an element on the page, much the same as document.getElementById( item ), and observe assigns an event handler to the specified event.
repositionPreviewFor( item ) moves the preview for item to just underneath it on the page. It looks like this:
repositionPreviewFor = function( item ) {
var elementId = $(item).id;
var elementPreviewId = elementId + '_preview';
$(elementPreviewId).clonePosition( elementId,
{ setHeight: false, setWidth: false, offsetTop: 20 } );
}
Lines 2 and 3 get the id of the item to show the preview for, and generates the id for the matching preview element. Line 5-6 is more prototype magic. This time, it copies the position from the item element into its preview and offsetTop: 20 then moves the preview down a bit. 20 is one of those dreaded magic numbers, and really should be calculated. It'll do for a quick demo :)
hidePreview and showPreview are pretty basic and do precisely what you would expect:
showPreview = function( event ) {
var elementPreviewId = Event.element(event).id + '_preview';
$(elementPreviewId).show();
}
hidePreview is the same, it just calls .hide() instead.
For this to work, you need two things in your html: an element with a known id and another element with the same id with "_preview" tacked on the end. In order to hook up the event handlers, we can use a little more prototype magic, to attach them once the page has finished loading:
Event.observe( window, 'load', function() {
hookUpPreviewTo( 'example1' );
hookUpPreviewTo( 'example2' );
hookUpPreviewTo( 'example3' );
});
Now when you hover over the element with the id of examle1, the element with the id of example1_preview will be displayed below it. When you move your mouse away from example1, example1_preview will be hidden again.

If you'd like to try it yourself, and have a look at the code, you can download it here.
Big Refactorings!
I decided it was time to catch up with some of the to-do list items I've made for myself for this blog. On that list are some immediately useful things like integrating Alex Gorbatchev's SyntaxHighlighter, and finally getting around to implementing publsihing control so I can publish posts when they're finished, and leave them hanging around when they're not.
Behind the scenes is where the really big changes are going to happen though, as I want to use Windsor with MonoRail, which I've been having a lot of success with on other projects. This means I'm going to be changing just about every single class, removing "poor man's dependency injection" in the form of constructors like this:
public BlogPostRepository(): this( new BlogPostDao() ) {}
I also want to add notification of new comments, as I often only notice them when I read the blog myself; which isn't often, as I subscribe to my own RSS! This will also help me react more quickly to comment spam, too (of which I've had a whopping three so far!).
Ok. Enough talk; more code!
Critical Code Mass
Sounds a bit ominous, doesn't it? Well, I actually mean it in a good way: the point at which you don't have to think up more code for a particular feature for a new project; rather, you can check something out of your code repository and get on with working on the problem at hand.
That kind of "critical" code mass, I'm very happy with, and it's where I'm beginning to find myself more and more recently. For example, when a new project requires authentication (and don't they all?!) I can just check out the code I wrote when writing the MembershipProvider when I wrote the corporate Intranet.
We recently had a company come in to install a centralised printing system for us, and they needed a way to identify the owner of a print job, and also a way to associate their data with that user. After a quick dive into my code repository, I had the answer: the membership provider code for user identification, and code from where I integrated our time-and-attendance system with the Intranet. An hour later we had a tool which we used to associate network user accounts, door-entry swipe card numbers, and their system identification tokens which produced data ready for their system to use.
Because the majority of my code is now driven out with TDD, I can also easily pull small parts in isolation, along with their tests, and quickly reuse them to solve other problems. It's a very nice position to be in!
See? Critical code mass, but in a good way :)
Enum Selects in MonoRail templates
This is one of those "blogged for my own reference" posts, but it's a neat trick.
In MonoRail you use various helpers to build your template. There's one for building forms, which makes it much easier to work with objects to build your html form.
One of the things I've just been playing with is creating a HTML Select element from an Enum. In my case, I need an enum called Priority to be a drop-down list of options.
public enum Priority { Urgent, High, Medium, Low, Hold }
Which I would like to appear like this, with Medium selected by default:
The MonoRail template (using Brail syntax) is as follows:
${ Form.Select( 'project.Priority', Priority.Medium, Form.EnumToPairs( typeof( Priority ) ), { @value: @first, @text: @second } ) }
Breaking that down, the first parameter to Form.Select is the name for the html form field; the id will be generated with the dot replaced with an underline "project_Priority".
The second parameter Priority.Medium, specifies the value to select in the list.
Next is the really useful part, Form.EnumToPairs, which generates the IEnumerable data from an Enum type. It creates an array of Pair<int, string>. The int field is called "first", and the string field is called "second", which we'll need next.
The last parameter of the Form.Select is a dictionary specifying options. In the example above, this specifies the property names to use for the value and text for the option elements of the select. The format "@value: @first" defines a dictionary entry with a key of "value", and a value of "first".
Music to code to...
I'm just enjoying Torley Wong's music, especially the track In the Garden of Hopes and Dreams. I thought I'd share :)
Rails Shortcuts
I've spent the weekend writing a Ruby on Rails site in TextMate, and I've only just found out that I can use Command+Shift+R to run the unit test the cursor is in, and Control+Shift+R to run rake tasks.
Better late than never, I suppose.
I've made a note to have a look at Autotest next weekend. See if that can save me some time.
I've got to say though, I'm enjoying the new migration and fixture syntax! :)
But for now, it's back to .net for the working week... :/
HTML Tool Suggestions
I've been asked to give a training course on the basics of HTML to a couple of colleagues for which I'm just compiling a list of essential tools and plugins which will make their HTML-editing lives much easier:
The idea is not to overwhelm them with tools, so the list is kept to a minimum.
What would you put on your list of essential HTML tools?
Fluent Interfaces
Oren recently posted an article comparing a Domain Specific Language (DSL) and a Fluent Interface.
I'm still not entirely sure I understand the differences between a DSL and a fluent interface, but I didn't think that Oren really pushed the fluent interface example quite as far as he could have, so I thought I'd play with the idea and see what I could come up with.
For comparison, here's Oren's example:
new FluentTask("warn if website is not alive")
.Every( TimeSpan.FromMinutes(3) )
.StartingFrom( DateTime.Now )
.When(delegate
{
return WebSite("http://example.org")
.IsAlive == false;
})
.Execute(delegate
{
Notify(“admin@example.org”, “server down!”);
});
Here's what I came up with in about 30-45 minutes:
ITask SiteCheckTask =
Schedule.Task( "Report website down-time" ).
Repeat.Every( 3 ).Minutes.
Starting( DateTime.Now ).
If( Web.Site( "http://www.example.com" )
.IsNotResponding() ).
Notify( "admin@example.com", "Site down!" );
Although it reads quite nicely from the user's perspective, behind the scenes there are eight classes and six interfaces, which makes this small demo quite complex.
This works because most of the methods and properties are factory methods. For example, Schedule.Task( "Report website down-time" ) is a static method which returns an instance of a TaskDescriptor class:
public class Schedule
{
public static ITaskDescriptor Task( string description )
{
return new TaskDescriptor( description );
}
}
The Repeat property of the TaskDescriptor then does the same again: it creates an instance of a ScheduleDescriptor (passing itself in) and returns that. The ScheduleDescriptor describes the start and interval for the scheduled task.
public IScheduleDescriptor Repeat
{
get { return new ScheduleDescriptor( this ); }
}
And so on. The ScheduleDescriptor's Every() method sets an internal interval field and returns itself to the caller ( return this; ). The Starting method of the ScheduleDescriptor records the DateTime, and then sets itself as the ScheduleDetails on the TaskDescriptor, which it then returns.
public ITaskDescriptor Starting( DateTime start )
{
startTime = start;
descriptor.ScheduleDetails = this;
return descriptor;
}
The If() method on the TaskDescriptor does much the same as the Repeat property did, but it creates an ActionDescriptor this time. It accepts a StatusCheckDelegate as a parameter, which is built with the Web static class' Site() method. This returns an instance of a WebStateCheckDescriptor (beginning to see a pattern here?) which takes a string for the URL, and the IsNotResponding() method returns a delegate which (nearly) checks whether the specified URL is accessible.
Phew. Plenty of indirection there!! But the question is: does it add too much complexity? I think that is probably one of those questions which has to be answered on a per-project basis.
You can have a trawl through the code to see what I've done. It's certainly not anywhere near production (it doesn't even do anything) but hopefully it might be useful 
References
Anders Norås' "Behind the scenes of the planning DSL" was the inspiration for this spike.
Assembly Information Problems
I decided to upgrade the OS on my desktop PC to Vista x64, yesterday. I've tried this before, but I tripped on a problem so fundamental to me, that it actually resulted in me rejecting Vista and reinstalling Windows XP.
When I install Visual Studio on Vista x64 Ultimate and create a new project of any type, the Assembly Information always lists "Microsoft" for the Company field, and "Copyright © Microsoft 2007" in the Copyright field.
This may sound like a pretty simple thing. Just change it, and get on with writing code! The problem is, this happens for every assembly I create, every time, so I would have to remember to make the change every time -- very annoying!
The problem is that each project template has placeholders for this information, which is swapped out when you create a new project from them. The placeholder in this case is "$registeredorganization$", and this is (usually) replaced with the contents of the "RegisteredOrganization" registry key in HKLM\Software\Microsoft\Windows NT\CurrentVersion, which contains the name you entered when installing Windows.
As Vista doesn't actually ask you for a company name during setup, this key is empty by default, so I typed "MidnightCoder.net" into it, restarted Visual Studio, and created a new Class Library project. It was still showing "Microsoft" in the company and copyright assembly information fields.
I know this would have worked on 32bit Vista, as I did precisely this on my work laptop, so this seems to be something perculiar to Vista x64.
Fortunately, Microsoft, or more specifically SysInternals, gives us a tool we can use to hunt down the problem: Process Monitor.
I downloaded Process Monitor and ran it up. It instantly began filling up at a rate of knots: too much data!! The first thing I needed to do was to filter out everything but Visual Studio, so I pressed the filter shortcut (CTRL + L) and added the following:
Column: Process Name
Relation: is
Value: devenv.exe
Action: Include
This narrowed it down to Visual Studio details, so I created another Class Library and looked at Process Explorer. Amazingly, it still had too much for me to sift through, so I needed to refine my filter some more. I added this:
Column: Path
Relation: contains
Value: RegisteredOrganization
Action: Include
This time when I created (another) Class Library, I got exactly what I needed: the path Visual Studio x64 was loading the details to replace $registeredorganization$ from is:
HKLM\Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\RegisteredOrganization
Bingo. That still read "Microsoft". I changed it to "MidnightCoder.net" and created one more Class Library, and my problem was solved, thanks to Process Explorer and a simple filter.
Html Email
I mentioned earlier that I'm writing some code to send an email. The emails will be the invitations to join the family portal project I also mentioned.
One of the things I wanted to do is to make the emails a bit more interesting than just a paragraph of text and a link, so I've been looking at ways to send a HTML email.
I found two solutions. I'm using Castle MonoRail which has can use its view templates to render and send an email, and the .net framework (2.0 and later) also supports alternate views in the MailMessage so you can add a HTML version.
After some research, I decided that I wanted to embed the image into the email as externally linked images, that is, email with links back to web servers for the images, are more likely to be blocked by spam filters as it is possible to build an image URL to send information back to the web server.
This ruled out the MonoRail mail aproach as it doesn't embed the images, as far as I could tell by spelunking through the code. The .net framework MailMessage, however, does support embedded images and it's pretty easy, too.
To embed an image, you first have to create a HTML version of the mail:
AlternateView htmlView =
AlternateView
.CreateAlternateViewFromString( "<h1>Not Favourite!</h1><img src=\"cid:notfavourite\" />",
Encoding.Default, "text/html" );
If you look at the image tag in that html, you'll notice the source is cid:notfavourite. The "cid:" part tells email clients to use the linked resource called "notfavourite". Next we need to create that linked resource.
LinkedResource notFavouriteImage =
new LinkedResource(
"images\notFavourite.jpg",
"image/jpeg" );
notFavouriteImage.ContentId = "notfavourite";
This loads the image, sets the MIME type, and assigns a content id to the image. It's important to use the correct MIME type, as if it is wrong, the embedded image won't display properly. The ContentId also needs to match whatever is used in the image src property, "notfavourite" in this case.
Next, we add the linked resource to the alternate view...
htmlView.LinkedResources.Add( notFavouriteImage );
... and add the alternate view to the MailMessage.
message.AlternateViews.Add( htmlView );
That's it. Next you just send the message as usual:
new SmtpClient().Send( message );
This takes its configuration from the web/app.config file, in the configuration/system.net/mailSettings/smtp section. Here's the one I used for my testing. You would need to change the details for your own environment, of course.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.net>
<mailSettings>
<smtp from="joe.bloggs@example.com"
deliveryMethod="Network">
<network host="127.0.0.1"
port="25"
userName=""
password="" />
</smtp>
</mailSettings>
</system.net>
</configuration>
I've packaged up my quick test project, so you can get started quickly. You will need to edit the app.config before you run the test. It uses NUnit as this means I don't need to mess about with a win- or web-forms app just to test a small snippet of code.