Friday, June 30, 2006

Ordering Category in CodeSmith

When I worked on a CodeSmith template (*.cst), I came into a small problem to order categories in a property grid. The template I created has several categories and I want it to be displayed in a specific order, not ordered alphabetically as per default.

I came across this discussion that gave me a nice trick to order the categories. We need to prefix the category name with a special character that does not get displayed by Property Grid. Aab character (\t) will do the trick. Multiple tab characters might also be used. So for example if I want to order my categories in the following order:

Context
Persister
BusinessEntity
UnitTests

Then in CodeSmith template I need to write like:

<%@ Property Name="SourceTable" Type="SchemaExplorer.TableSchema" Category="\t\t\tContext" %>
<%@ Property Name="CreateBusinessEntity" Type="System.Boolean" Category="\t\tBusinessEntity" Default="True" %>
<%@ Property Name="CreatePersister" Type="System.Boolean" Category="\tPersister" Default="True" %>
<%@ Property Name="CreatePersisterUnitTest" Type="System.Boolean" Category="UnitTest" Default="True" %>

Thursday, June 15, 2006

Ajax and Auto Save

The following article summaries our experience in working with auto save feature in the web application. New technology and new features always bring fresh challenges to developers and also good things for users, but they may also raise new issues that have never come up before. I hope by sharing this experience with you, you will be more aware with the issues while working on similar feature.


One of the recent challenge that my team had was to handle session timeout issue when our users spend too much time on a web form. As a background, a user session will time out when there is no communication (client request) with the server for a certain period. When time out happens, the user has to log in again and this action potentially destroys any unsaved changes the user has made on the web form.


We don't favor to increase the session time out, since this solution imposes a greater risk to our application. What we need is a feature or two that can handle session time out gracefully.


We come up with the idea of auto save after experiencing GMail for a while. The auto save feature has been in Microsoft Word as long as I can remember, so we often take it for granted, but it is a new and sexy feature for the web application.


In case you haven't seen how auto save works in GMail, this feature runs silently in the background. It will detect changes in the email content and periodically send the content to the server for saving. A short, non obstructive message will appear to indicate that the auto save is done.


So we made our mind to implement auto save in our web form. The web form is much more complex that Gmail's form. In the form, we have about 25 fields (textbox, dropdownlist, textarea) and a rich text box that can contains HTML.


Briefly this is what we did:


  1. A timer in set in Javascript that will invoke a function called saveData() every n-minutes.

  2. saveData() calls a home-grown Javascript form utility to extract the values of all fields into XML.

  3. We use AJAX to send the XML to the server.

  4. The server receives the XML and based on the status of the data does either one of the following:

    1. If the user does not explicitly save the data, we save the XML into a table that is created for the sole purpose of saving data temporarily.

    2. If the user has explicitly save the data before (for example, by clicking on the save button), we deserialize the XML into business object, and use the data access layer (DAL) class to save the data into proper tables.


  5. Upon completing the operation, the server returns a return status and the javascript displays the auto save message.


In my observation, it is important that the auto save message does not distract from the user's focus. We don't want the user to lose focus on the fields he/she is working only for the sake of auto save. The auto save feature should be made as transparent as possible.


Point 1-5 above is what we did initially with the auto save. When we used this feature for a while, we noticed that the audit log was filling up fast. This is because we always save to the database regardless whether the data has been changed.


We have two options to solve the problem. First option is to compare the values of the fields in the client side and send the XML only if we find differences. The second option is to compare the values in the server side. While the second option requires less effort, we find that this solution has potential issues. As the value comparison is done in the server side, the client needs to constantly send the XML data to the server side. This will increase the traffic and make the server busy unnecessarily. It will also make the user session never expires, opening the application for further exploitation. The first option is indeed more challenging but it will create a more efficient traffic and the user session still works properly.


Let's see the beauty of auto save in the following mini case study:


A user logs in to the application, enters data in the form, but he hasn't press the save button. After n-minutes, the auto save triggers and saves the data to the temporary table. Suddenly, there is a network disruption and the user loses his session.


After the network disruption is over, the user logs in to the application again and revisit the same form. This time the application checks the temporary table and finds the auto save data that belongs to the user. The application pops up a message, informing the user whether he/she want to recover the data or continue with the blank form. If the user chooses to recover the data, the auto save data is loaded and populated to the form. However, if he chooses to start with blank form, the auto save data is deleted.


Giving options to recover data or to start with a blank form is a nice to have feature, because in some cases the lost data is not worth to recover.


Does auto save solve session timeout issues? I can say partially. The session will still time out if the user does nothing, but with auto save the user will not lose all data. I have been thinking of another feature that can warn the user when the session is about to time out. This feature will complement auto save to make a really user friend form.