The Most Important Key on the Keyboard

The most popular keyboards in the US have 104 keys.  Some keyboards have more keys, some have less.  Some keyboards have numeric keypads on the right to allow you to type in long sequences of digits faster.  Some keyboard have altered layouts designed to fit on a laptop.  Despite the differences in keyboards there is a single key that can be considered the most important of all.

If you’re like me, you spend a lot of time during the day next to your keyboard hitting the keys in some prescribed manner.  Many of the common key sequences have been burned into my muscle memory so thoroughly that I don’t have to think about it.  When saving my documents I almost always use “Alf+F, S” rather than “Ctrl+S” because that’s the way my hand remembers how to save my document.

Beyond personal preference, there is one key that stands alone in both its importance, and on the keyboard itself: the “Esc” key.  It’s located in the upper left of the keyboard — the most important place on the keyboard for a left to right, top to bottom reading culture.  It’s also the easiest key to hit on the keyboard without looking. The “Esc” key has universal acceptance and intuitive functionality, although it can be difficult to put into words.

For a web browser the “Esc” key means to cancel the current request.  For a windows application, it might dismiss a dialog.  For a terminal application, it may return you to a home screen.  If you’re dragging a file from one folder to another, you can hit escape to cancel the drag operation.  Inside of a standard textbox, the “Esc” key will reset the text to its initial value.  (This particular usage is extremely useful if the application doesn’t allow you to switch focus with invalid data, and you don’t remember what was originally there.)  Essentially, it means “Stop what you’re doing and get me back to where I was”.

The “Esc” key is like a safety harness.  With it you can venture into the black depths of undocumented software and return with your data intact.  Whatever you do, wherever you go, you should always be able hit the “Esc” key and things will be alright.  The “Esc” key is comfortable and familiar.

We as developers must be mindful of the “Esc” key and how to make it work.  We should also recognize where it can work.  The “Esc” key can be used to dismiss error or information messages.  It can be used to cancel the current operation, but its operation should be ‘safe’.  You can lose some data, but not much.  (It’s okay to lose data that you just put into a dialog box.)  The user can and will hit the “Esc” key multiple times in a row in rapid succession.  Eventually, you should get to a place where the “Esc” key does nothing, or loops until the user performs a necessary action.  A good example of a loop is trying to exit a window where changes need to be saved.  “Esc” -> Exit.  Dialog, “Save Change?”  “Esc” -> Close dialog, return to window.

I think it can be easy to forget about the “Esc” key during software development.  Very often, it is a non-operation, but when appropriate, I think good handling of the “Esc” key is essential.

Escape Click/Double Click Hell in IE8 and FireFox With jQuery

While developing a control for a web page, I ran into a cross browser problem related to mouse clicks.  I offer the following guidance to hopefully help someone experiencing the same problem.

The Problem

The click and double click events are closely related. IE8 and Firefox handle them differently. If you were to double click a button on a web page, the following event timelines would occur.

IE8 Double Click Event Timeline

  1. click
  2. doubleclick

FireFox Double Click Event Timeline

  1. click
  2. click
  3. doubleclick

IE8 will fire only the double click DOM event, while Firefox will fire both the click and the double click event. You could have an argument about which method is correct, but the truth is I don’t really care. I just wished it worked a single way.

Background

I wanted a to create simple spin control.  A textbox holds a numeric value, and two buttons on the right can either increment or decrement the value.  Using jQuery, I wrote a couple of simple methods to increment and decrement the value in the textbox. Here’s my first attempt:

    <script type="text/javascript">
     $(document).ready(OnReady);
 
      function OnReady() {
         $("input.GridCellArrowUp").click(OnUpClick);
         $("input.GridCellArrowDown").click(OnDownClick);
     }
 
     function OnUpClick() {
         var query = $("input.GridViewEntryEdit", $(this).parents("table.CellTable"));
         var hours = Number(query.val());
 
         if (hours != undefined) {
            hours += 0.5;
            query.val(hours.toFixed(2));
         }
     }
 
     function OnDownClick() {
        var query = $("input.GridViewEntryEdit", $(this).parents("table.CellTable"));
        var hours = Number(query.val());
 
        if (hours != undefined) {
           hours -= 0.5;
           query.val(hours.toFixed(2));
        }
     }
 </script>

Performance Problem

This approach was fully functional, but I noticed that the click performance was bad in IE8. If I were to rapidly click a button, it would increment only every other button press. I was unsatisfied. Firefox seemed to work just fine, but I can’t ignore my IE audience.

I found a solution on the internet that would put a delay into the click handler so as to only fire a single click, or a double click. This wouldn’t work for me. I couldn’t wait to see if a double click was going to happen or not. Since I can’t change IE8, I needed to act upon either click or doubleclick events.

Since Firefox will fire both click and doubleclick events after the second click, I put a short delay (20ms) in the handler so that my code doesn’t act twice. The end result is that I can rapidly click my button, and I get a result each and every time. Here is my final result:

<script type="text/javascript">
    $(document).ready(OnReady);
 
    var okToClick = true;
 
    function OnReady() {
        //Attach to both click and dblclick events for IE/Firefox compatibility
        $("input.GridCellArrowUp").click(OnUpClick).dblclick(OnUpClick);
        $("input.GridCellArrowDown").click(OnDownClick).dblclick(OnDownClick);
    }
 
    function OnUpClick() {
        if (okToClick) {
            okToClick = false;
 
            var query = $("input.GridViewEntryEdit", $(this).parents("table.CellTable"));
            var hours = Number(query.val());
 
            if (hours != undefined) {
                hours += 0.5;
                query.val(hours.toFixed(2));
            }
            setTimeout(function() { okToClick = true; }, 20);
        }
    }
 
    function OnDownClick() {
        if (okToClick) {
            okToClick = false;
 
            var query = $("input.GridViewEntryEdit", $(this).parents("table.CellTable"));
            var hours = Number(query.val());
            if (hours != undefined) {
                hours -= 0.5;
                query.val(hours.toFixed(2));
            }
            setTimeout(function() { okToClick = true; }, 20);
        }
    }
 </script>

Notice that I have attached to both the click and doubleclick events via jQuery. Also, I put a latch around the methods so that they can’t execute twice in a very short period of time.

Binding to joined tables

Many times it is necessary to bind to a datatable which is made up of multiple database tables.  Most databases are normalized.  In Visual Studio 2005 there was a particular technique to do this.  Write your join statements in stored procedures, and create a table adapter within the dataset designer to use these stored procedures for update/delete and so forth. 

With the advent of LINQ to SQL, there is a new way.  First, create your objects, and then bind directly to a LINQ query. Note however that when binding to a LINQ query, the information is read-only. If you want a read-write binding to multiple database tables, a table adapter wired up to stored procedures for SELECT, INSERT, UPDATE, and DELETE commands is still the best way to accomplish this.

How to tell if a path is relative or absolute

There is no function or method in the .NET framework to find this out directly.  I had though that Path.IsPathRooted(string) would do the job, but it seems that paths can be both relative, and rooted.  The path "C:bin\Debug\app.exe" is perfectly valid.  So, the only thing to do is to take the input, create the absolute path, and compare them.  Like this:

private void CheckDestination(string destination)
{
   // Ensure that path is absolute.  Ignore case
   // because filesystem is case-insensitive
   if (string.Compare(destination.Trim(),
      Path.GetFullPath(destination), true) != 0)
   {
        // path is absolute
   }
}