Wednesday, 29 September 2010

ASP.NET: Web Application Spell Checking with jQuery and AtD (After the Deadline)

Why did I need it?
In a recent project, we had a very large form with wizard steps and several multiline text area controls. The form was submitted to senior managers, so the requirement was raised to provide some kind of automated spell checking functionality.

Given that this is a web application, it wasn't obvious which solution to choose. You can ask you users to install browser plugins which will check spelling, but this isn't really pratical since very few people would actually do it. Or you can install a full third party application on your server and use some kind of AJAX call to check spelling.

If a spell checker does not make good suggestions to fix spelling or grammar mistakes, then it becomes pointless. So we needed something with a good comprehensive dictionary and it had to be quick.

After some rooting around and consideration of third party products and also possibly somehow piggybacking on SharePoint's spell checking service, I found a product called AtD (After the Deadline).

What is AtD?
AtD is an open source solution which you can plug into your website using the wonderful jQuery (though it also offers other spell checking methods). It seems like an odd name to me, but apparently AtD is named after a similarly titled blog in the New York Times.

It's a fantastic product and only takes a short time to set up. Using the jQuery version which I chose, it runs client side and will highlight spelling and grammar errors, and provide a good set of suggestions to fix them. It's quick, user friendly and it even works in IE6. Use this link to download the source code and view a couple of tutorials, though the tutorial I found most valuable was this one:

Demo 3

Here is Demo 3 in action:

You can use that page to try out AtD for yourself, and if you view its source you can follow the simple step by step instructions to get started.

There are tutorials on the site, but basically you either link to the source code and css, or embed it in your project, use a little bit of jQuery code to assign the spell checker to each textarea on your page, do any layout customisations you need and wham bam - it works. You don't need to add any markup to your existing page, the jQuery will do the legwork for you.

It wasn't all plain sailing…
I did have a small problem in getting up and running with AtD. What's the problem I most often come up against in web development? That's right, Internet Explorer.

Basically the issue was in getting the spell checker buttons to float to the right hand side of the textarea controls (to me, this seems the most obvious place to put them), but by default AtD will add the spell checker button to the top right hand side of the textarea using a dynamically rendered span element.

I thought it'd be easy to get the spell checker button to sit where I needed it simply by modifying the css to make the spelling button float to the right of the textbox. This worked perfectly in Firefox, but in IE when you float the button, the onclick behaviour inexplicably stops working, thus rendering the whole thing useless. That was no good.

Of course, you can edit the css used to render the AtD elements. So I played around with it for a while and ended up changing the default CSS for the spelling buttons to look like this:

width: 14px;
height: 14px;
background-image: url('../images/writing.gif');
margin-left: 465px;
position: absolute;
width: 14px;
height: 14px;
background-image: url('../images/editing.gif');
margin-left: 465px;
position: absolute;

I removed the display:block property, added position: absolute and added a left margin which is roughly equivalent to the width of the textarea controls in my project. This meant that the buttons sat nicely alongside the textboxes, and the absence of a float property meant that IE and Firefox would render the whole thing nicely.

After the Deadline makes for a superbly straightforward and lightweight spell checking solution for web applications which adds real value. I'll certainly be using this in any future web project where spell checking is required.

Friday, 24 September 2010

ASP.NET: Limiting the length of a multiline textbox

ASP.NET comes with a lot of nice validator controls which save you the hassle of writing a lot of JavaScript components yourself.

The TextBox control has a MaxLength property which allows you to easily restrict the length of the input. But bizarrely, a TextBox with its TextMode property set to MultiLine does not have this property.

But of course, you still need a way to limit the amount of text input or your database operations could fail.

Previously, I was using a JavaScript function attached to these textboxes with a function which was fired on keyup or lost focus which counted the number of characters and prevented overflow of a maximum set amount.

That's the long way of doing it though: you can achieve the same validation using a RegularExpressionValidator, as highlighted on this post by Raj Kaimal.

Fundamentally, you create a RegularExpressionValidator control, point it at your multiline textbox and set this as the RegEx (300 in this example obviously being the maximum number of characters allowed):


Et Voila! A simple and elegant solution - and no custom JavaScript required!

Thursday, 16 September 2010

ASP.NET: InvalidCastException from Strongly-Typed DataSet (XSD)

This one has had me tearing my hair out for months.

In most of my ASP.NET projects I would have an XSD DataSet which models my database schema and acts as the data access layer for the application. But in several situations I would get unbelievably annoying exceptions from the designer file whenever my code attempted to get a boolean or date value from the database which was null. You would receive an exception like this:

StrongTypingException was unhandled by user code.

The value for column 'abcdefgh' in table 'tblAbcdef' is null.

My first step was to open the Properties of the column in the XSD designer and make sure that the AllowDbNull property is set to true. Then in the NullValue property I tried to change the behaviour from (Throw exception) to (Empty) or (Nothing). But Visual Studio blew up in my face and informed me that my selection was invalid.

'Fine' I thought, 'I'll just check the value for DbNull before trying to set it in my code'. But when I tried to do such an IF statement, the StrongTypingException would still occur because before my expression tried to evaluate the column value, the designer would throw the StrongTypingException, thus never allowing the evaluation to take place.

I couldn't find the answer to this, until a much smarter colleague pointed out the extremely simple answer. The designer file catches a InvalidCastException and then throws a StrongTypingException. So in my own code, I just need to catch the StrongTypingException and ignore it - assuming that ignoring it is the correct thing to do in that piece of code. I had been trying to catch the InvalidCastException which of course is incorrect because the designer had replaced that with the other exception type.

.ClientContact = dbRecord.ClientIsStudent
Catch ex As Global.System.Data.StrongTypingException
' Ignore since these are generated from the typed DataSet designer
End Try

This worked and I am delighted to finally have the answer to this problem which has been bugging me for ages!

If I had actually read the designer file code I might have spotted that it throws a different type of exception to the one I was trying to catch.

Friday, 3 September 2010

ASP.NET: Failed to access IIS metabase (IIS)

When installing everything on my new machine, came across a problem in IIS when publishing my projects there. I got the error:

Failed to access IIS metabase
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code

The error directs you to a Microsoft KB which isn't particularly helpful.

I had seen this error before when using SQL Server Reporting Services but the method I used last time works for SSRS, but not in this case. After a bit of Googling I found that this is a problem with the account permissions that ASP.NET runs under in IIS, as well as a method to solve it.

1. Gave permissions to the ASPNET account using "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis –ga machinename\ASPNET".
2. Reset IIS (iisreset on command line) and that resolved the issue for ASP.NET 2.0.
3. We registered ASP.NET 1.1 with IIS as well using command "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\aspnet_regiis –i".
4. Reset IIS again.

That did the job for me. Some other people had to go to greater lengths such as uninstalling .NET and reinstalling it, but the above steps resolved the problem in my case.