New Dojo Tree Functionality

Dojo has just accepted code from Spider Strategies into the toolkit that allows dragging and dropping hierarchical data in a tree format “between” places in the structure!

Dojo drag and drop between

Like the folder tree we’re all familiar with, we get accustomed to dragging and dropping things from one place to another.  Many of these structures, like file folders, don’t care about the order of the contents. They can sort by things like size or name, but don’t store the order of data.

For more complex data structures, like those in CMS, the order of the data is an important part of the information. Thanks to the code we sent to Dojo, data in a tree can easily be moved from anywhere to anywhere. Previously, you could only drag and drop things into a location. Now it is possible to position things before or after other items, allowing users to intuitively manage their data.

IE6, HTTPS and MS Office

In CMS we have a software feature that allows users to export any screen in the application as an MS Office file (Word, Excel or PowerPoint). Recently we found out this feature didn’t work very well for some Internet Explorer 6 users, so we had to tweak our implementation a bit.

The basic technique we use to create MS Office files is to take our existing HTML screens and instruct the user’s PC to open the files in MS Office. In the past, we told the PC to open the file in MS Office by setting the MIME type for the appropriate file type (e.g. application/ms-word for Microsoft Word). We found a technique that works better with IE6, HTTPS and MS Office is to set the Content-Type to application/x-download and set the Content-Disposition to attachment; filename=(filename here).

We learned of this technique by reading this article from ONJava. The article is written assuming a Java programming environment, but setting HTTP headers isn’t really specific to Java, so the basic technique should be applicable to any web environment. If you’ve been wrestling with IE6, HTTPS and MS Office, I hope this article is of some help to you.

Eliminating Session Timeouts

This weekend, my mother told me about the trouble she had booking train tickets from Washington, DC to New York using Amtrak’s online reservation system. She had to make the reservation three times because the first two times she took too long and the website timed out. As I listened to my mother’s story, I felt proud because I knew she wouldn’t have had the same problem if Spider Strategies wrote Amtrak’s reservation system.

The problem my mother experienced is a common one for web applications. Most web applications operate using the notion of a session which is used to store information about the user that is logged on and the activities he or she is performing in the application. The trouble is that the session is periodically erased to save memory on the server. When the session is erased, the user’s work is lost. In my mother’s case, her reservation was erased.

In CMS, we avoid this problem by using dojo to fire off a request in the background every few minutes. These requests prevent a user’s session from expiring as long as that user keeps his or her browser open. If the user closes his or her browser, the session will still be cleaned up so that the server doesn’t fill up with old, unused sessions.

In addition to benefiting the usability of the application, this technique can also decrease the amount of memory devoted to sessions on the server. Typically a web application will have a session timeout of 30 to 60 minutes. With this technique the timeout can be decreased to a smaller number (e.g. every 5 minutes) as long as background request are fired faster than sessions are expired (e.g. every 2 minutes). Faster session timeouts means sessions are in memory for less time means less total memory will be needed for sessions.

If you’re a software developer, I hope you find this technique useful and apply it to your application. If you’re a user of CMS, you can rest easy knowing this technique is already in place so that you don’t need to worry about losing your work.

Set Textarea Maxlength with JavaScript Intrinsic Events

With the wonderful implementations of AJAX, many people (myself included) tend to look first within libraries like Dojo when trying to implement a client-side solution. While this is generally a good approach, one thing that some developers tend to forget is the intrinsic events like onkeypress, onmouseout, etc.

A good example is the textarea tag. It doesn’t have any limit on the number of characters like the input tag, so it’s a great candidate for a simple JavaScript function to duplicate the maxlength functionality. The initial instinct when coding something to handle this is to check the length of the field and return a false if it’s reached the limit. This does indeed limit the size, but there’s one problem; backspace and delete trigger onkeypress. As a result, if you’re at the limit and try to delete characters, it returns false and nothing happens! Instead, I find the best solution is to truncate the field if the size is reached. For example, to limit a textarea to 255 characters:

<textarea id="maxdemo" rows="20" cols="80"
 onkeypress="maxlength(this, 255);"></textarea>
<script type="text/javascript">
<!--
/**
 * Determines if a field is exceeding the maximum size
 * and truncates the string if it is over the limit.
 */
function maxlength(field, size) {
    if (field.value.length > size) {
        field.value = field.value.substring(0, size);
    }
}
// -->
</script>

Using Chainsaw for Log Viewing

If you’re a programmer, no doubt you’ve the occasional, if not constant, need to read the logging statements generated by your application. I know that I’m constantly reading log output, which is why I’m thankful for a tool like Chainsaw v2. Despite having a not-yet-complete feel to it, Chainsaw has become an invaluable tool in my programming environment. Recently I discovered a hint that I should have known a long time ago, which increases its usability tenfold.

Configuring log4j and Chainsaw is a breeze. Once you’ve downloaded it, configure your log4j to use a SocketAppender. Here’s a snippet from my own log4j.properties:

log4j.logger.com.spider=DEBUG, CHAIN
log4j.appender.CHAIN=org.apache.log4j.net.SocketAppender
log4j.appender.CHAIN.remoteHost=localhost
log4j.appender.CHAIN.port=4238
log4j.appender.CHAIN.locationInfo=false

Here I’ve set up an appender named ‘CHAIN’ on port 4238. Its running on the same machine as my application (hence ‘localhost’), but it could just as easily point to a Chainsaw instance on another computer.

Next, add a “SocketReciever” within Chainsaw. The important property is ‘port’, which must correspond the value in your log4j.properties:

Chainsaw receiver configuration

That’s it. Your log messages should go to chainsaw, where you can navigate and search with ease. Here are a couple tips for Chainsaw use, including my own recent discovery:

  • Create an XML receiver file and configure Chainsaw to use it upon startup. This way you won’t have to redefine the receiver each time. See “View example Receiver configuration” on Chainsaw’s welcome tab.
  • Use the ‘Refine Focus’ field when you need to get at specific log statement or logger. You can use the “=~” operand for partial matches. For example, if you want to display only log messages from the Logger named “ServiceClassWithLotsOfLogging”, you can type “Logger ~= LotsOf” in refine focus. This same technique can be used for messages as well: “msg ~= some logging text”. Wish I had known this a long time ago!

If you’ve multiple monitors (or computers), I think you’ll find that 2nd monitor makes a great home for Chainsaw.

Happy coding!

~ Keith