Archive for March, 2007

37Signals Keeps Getting it Right

Friday, March 23rd, 2007

37Signals launched another product this week, and continued to show that they’re the best at product launches and immediate customer service in the business.

In the world of the Internet and its near-infinite set of possible customers, it’s impossible to get a product correct right at launch. Most Internet companies do a launch and a follow-up to that launch after quite a while (a month? a couple weeks? how ever long it takes to analyze all that usage data and customer feedback?). 37Signals ran a 36-hour follow up, trotting out a host of new features to immediately satisfy customer needs.

This is great on many levels.

  • 37Signals immediately delivered on customer experience;
  • 37Signals immediately fixed bugs and added new features;
  • and, 37Signals immediately found and created additional channels of revenue for their product.

The old launch it and wait strategy is dead in favor of the early launch and quick fix. Get the product out in the users’ hands, and, as commenters tell us in this 37Signals blog post, if you address their gripes quickly enough, adding new features and fixes right off the bat, your users will love you (and your flexibility and high level of customer service.

technorati tags:, ,

Basic Usability: Watch Your Shortcut Keys

Thursday, March 15th, 2007

I thought I broke FireFox the other day. I was browsing as usual, with a couple tabs open in the background, when I decided to open a new tab. I hit CTRL+T, the keyboard shortcut, and up popped a document layout editor. I thought I hit the wrong key, so I tried again. Same document layout editor. I figured a must have changed a setting, so I gave the “Tools” menu a scan. Nothing.

I opened a new browser. CTRL+T worked there, right off the bat. Then I realized the difference between the two browsers: one had a tab featuring normal websites, the other “broken” browser had a PDF open in a background tab. The PDF had hijacked my keyboard shortcut!

Adobe broke a cardinal rule of usability: their software altered and broke the fundamental experience of the parent software that it was supposed to enhance without giving me, the user, a choice in the matter.

Keyboard shortcuts are learned ways to navigate through a system; users have invested time and effort to learn these things, to become “power users” of the system. Designers and developers looking to enhance that system should spend time and effort to learn the same things, so that their products don’t break or alter the sytem’s fundamentals, changing it in unpredictable ways.

Perhaps, keyboard shortcuts aren’t viewed with the importance that they should be: they’re not for casual users, who might represent the biggest chunk of an audience. However, they are an important function of any system: they enable users to accomplish their tasks faster and with ease, allowing users to power through those quick, routine tasks while saving time and effort to difficult problems or more enjoyable things. Once you learned that CTRL+C copied and CTRL+V pasted, how often do you find yourself moving your mouse all the way up to the “Edit” menu to accomplish those tasks? Those seemingly unimportant keyboard shortcuts form a large part of your experience while you use many different products; they help to speed things up and make you a power user with a few simple keystrokes.

If you’re designing a piece of a system (software, a plugin for a browser, etc.) make sure that your piece of software lives and plays within the rules of that system. If CTRL+C copies, follow that rule. If CTRL+T opens a new browser tab, follow that rule, too. Don’t alter the fundamentals learned, enjoyed — and heavily invested in — by users.

And, from now on I’ll be sure to use CTRL+N to open a new window whenever I need to view a PDF.

HOWTO: Creating Column Layouts with JSTL and JSP

Saturday, March 3rd, 2007

Creating a multi-column layout in a JSP using JSTL can be a difficult concept to master. Over at my day job, we’ll see this concept occasionally. We’ll have a block of data that we’d like to present in a series of columns, with a maximum number of items in each column. Here is a quick tutorial to outline a solution to this pattern. We’ll be using Sun’s Core JSTL tag library, to do the heavy lifting, along with CSS and HTML.

The Setup
Let’s assume we’ll have at most 30 items in our set, and we’ll want a maximum of 10 items in each column, giving us a three-column layout. For this example, we’ll also put our items in an ordered list so that we can see what item number we’re working with. Let’s set that up in code.

  1. CSS — You’ll need a simple column layout that accounts for the fact that you may have any number of columns, depending on how much data you’ll be working with. I’ll use floats to make it simple, and I’ll add a border to each successive column for a little visual flair. My CSS would look like this:

            div.leftCol{
              float:left;
              width:200px;
            }
    
            div.middleCol, div.rightCol{
              border-left:1px solid #CCC;
              float:left;
              padding-left:20px;
              width:200px;
            }
          
  2. HTML — This one is up in the air. You may have three divs, you may have one. But, they’ll all look something like this:

    <div class="leftCol">[[10 items]]</div>

We know what we’ll be working with, but we’ll need some creative use of JSTL to actually get these elements to fall into place and enforce our maximum values per column rule.

The JSTL
We’ll be making use of two JSTL Core constructs: the <c:if> tag and the <c:forEach> loop.

  • <c:if> works like any standard if test. We’ll use it to test column data boundaries.
  • <c:forEach> gives us a hook called "varStatus" that lets us peek into the status of the iteration. We’ll be looking specifically at the index property of that varStatus object.

Writing the Code
Let’s start with a skeleton JSTL loop, so that we have a little scaffold to build on.

    <c:forEach items="${someItems}" var="item" varStatus="loop">

      <li>${item}</li>

    </c:forEach>
  

That’s a start. We still have to figure out where to place our starting and closing div tags and our starting and closing ol tags, which is the problem concept behind this pattern. Luckily, there’s a clever way of solving this problem.

Assume that we know that there will be at least one item to work with. (If there’s a chance for zero, use a <c:choose&gt block to react appropriately, dealing with the zero condition separately, and using this method as-is.) With at least one item, we’ll always need a left column and a start <ol> tag, no matter what. We’ll always need closing tags for our left column div and an ol, too. Knowing that these are always required, we’ll move them outside the loop, so that they’re always displayed.

    <div class="leftCol">
      <ol>
        <c:forEach items="${someItems}" var="item" varStatus="loop">

          <li>${item}</li>

        </c:forEach>
      </ol>
    </div>
  

We now have at least one column and list. We can use simple if tests to figure out when to close that first column and list and begin a second. In pseudocode, if we are at our maximum number of items, print a
close ol tag, print a close div tag, print a new open div tag with appropriate class, and print a new open ol tag.
So, if we’re at a maximum number of items (in our case, 10 and 20), we’ll close that column and start a new one. Let’s add that concept to our block of code, and finish this pattern. (Remember that loop.index gives us a count of which item we’re on.)

     <div class="leftCol">
       <ol>
         <c:forEach items="${someItems}" var="item" varStatus="loop">

           <li>${item}</li>

           &;lt;c:if test="${loop.index == 10}">
&;lt;c:if> &;lt;c:if test=”${loop.index == 20}”>
&;lt;c:if> </c:forEach> </ol> </div>

That above code may take a few seconds to sink in. The trick is that the </ol> and </div> tags after the loop will close any <ol> and <div> tags that are open at that point. It could be the left column that those tags close, or the middle column, or the right column. Let’s think about that for a second.

  • If there are 4 items in the list, we print the opening tags, enter the loop, print 4 items, exit the loop, print the close tags.
  • If there are 17 items in the list, we print the opening tags, enter the loop, print 10 items, print the close tags for the left column, print the opening tags for the middle column, print 7 items, exit the loop, print the close tags.
  • If there are 24 items in the list, we print the opening tags, enter the loop, print 10 items, print the close tags for the left column, print the opening tags for the middle column, print 10 items, print the close tags for the middle column, print the opening tags for the right column, print 4 items, exit the loop, print the close tags.

As you can see, we’re using the nature of HTML (a closing tag closes the nearest opening tag, regardless of any attributes that opening tag may have) to simplify our work and save many lines of JSTL. In the meantime, we have a simple pattern that will allow us to create as many columns as we want (simply create a generic CSS column class) with as many items in each as we want (simply change the boundary values in the JSTL). The key to the puzzle: keeping code we know we’ll always need outside of the loop so that it will always be printed and taking advantage of the nature of HTML.

technorati tags:, , , ,

I'm Reading…
Search This Site
You are currently browsing the A Modern Fable weblog archives for March, 2007.

AddThis Feed Button

Need great hosting?

Categories