Natural selection

July 2016

Building a usable finder.

Every company has one — the ubiquitous database of stuff. Storing somewhat vast swaths of information, ordered in a disorderly fashion, an organised mess of data never to be replaced and the result of years of maintenance.

Unless the product by which this data is retrieved is provided externally, organising that data is often the job of the technical staff. Usually provided by way of an intranet — or if you’re lucky enough, an extranet, accessible from outside the office.

It is within that system many colleagues of mine enter their daily working hours. We have three different methods for this: A traditional logging page, on which jobs are listed and hours can be inputted; An estimated logging page, which I developed to allow people to give a rough guess as to how much of their day was spent on any number of predefined jobs; and a job timer, which is designed to run from within the Fluid framework as an MacOS app.

Job timer

The job timer is where most of my development focus lays. I am a firm believer in timing as you go, and keeping an accurate record of what any sensible agency considers to be one of its most valuable assets.

How many jobs?!

Of course, with any internal system used many employees, the quantity of data can be overwhelming. The current method we use to ensure the timer doesn’t show hundereds of items is to predetermine a list of “local” jobs which are only relevant to the user.

This is done beforehand on the extranet system itself, and has been in use long before the timer existed. It was crucial to ensure that existing workflows were not interrupted.

The problem

When showing someone a limited subset of data, it is almost a certainty that at some point, that person will want to see data not in the list. This is the nature of limiting data, and we do it only for the efficiency of our servers and to avoid overwhelming users. It’s mostly for our servers, though.

When using the timer myself, I realised that the workflow for adding new jobs to it was flawed. The interface for the timer has been thought through to provide as little friction as possible, to be presented in a friendly, coherent manner, and above all, to be consistently user friendly.

When showing someone a limited subset of data, it is almost a certainty that at some point, that person will want to see data not in the list.

Unfortunately, the extranet was not. This system has been built over the past 10 years by many different developers, all with different motivations and priorities. When the workflow for a streamlined system suddenly forces you to interact with an older, more chaotic system, the experience is jarring at best, and utterly productivity draining at worst.

It was clear I needed a method of adding jobs to the timer without going anywhere near the existing systems.

The solution

Due to the minamilist nature of the timer, adding more interface elemnents on page risked detracting from the pure nature of the current function – to time jobs easily, quickly and clearly. Adding cruft to the visible interface would easily confuse users.

Enter the finder

Many operating systems and apps provide an opening dialog for quickly. MacOS itself has the Spotlight, which has become a crucial part of my workflow both for launching apps and running general searches.

MacOS Spotlight

Atom, my current editor of choice, also has a finder function. A quick cmd-t produces a list of all the files within a project, which can be easily filtered down to a single file.

Atom’s quick open dialog

The one thing these interfaces have in common is that neither of them are there until the moment you need them, and at which point, they appear quickly, work effectively and dissappear without much fuss. In another words, they are relatively frictionless. This was exactly the solution that would work for the job timer.

Job Timer finder

Build process

Moving to jQuery

As the timer itself was built two years ago, we have gone through a few changes since then. Foremost is the team-wide move from Prototype JS to using jQuery as our framework of choice.

Two years is also a long time for browsers to receive new features, standards and module support, and speed improvements, which meant I was not specifically constrained by the usual “older browser” issues that tend to drain time away from projects.

The move itself was fairly straight-forward. Watching out for obvious translation issues (especially with event handling) and inefficiencies by sticking to the Prototype way of doing things. Once this was done, I could work at the usual speed without having to consider the documentation for a framework we no longer officially use.

Accepting user input

Of all the interface elements on our extranet, the job timer is unique, in that it only has one form, and even that only accepts numbers. The timer interface itself is editable, which means clicking on it will convert the timing mode (in green) to an editing mode (in yellow). A quick tap of the digits and hitting enter would edit the time saved for that job.

User inputed times

Apart from that, the keyboard is relatively unused throughout the interface. This meant that I could leverage keypresses for a new feature.

I’ve never been a fan of multi-key shortcuts on web pages as a whole – they tend to override existing browser functionality or can cause confusion amongst users with inconsistent modifiers, especially across different operating systems. Cmd-space or cmd-t was out.

In the end, I opted for a system whereby the user could just begin typing with the keyboard, and the finder would appear, containing the currently entered text. Searching would take place on a timeout, which meant that slow typists wouldn’t hammer their connection with excessive numbers of requests.

Keeping it fast

Due to the database software in use, and the normalised manner in which job numbers and descriptions are stored, it would have been computationally expensive to keep the search logic purely within the SQL.

For instance, a job number is formatted AA0000 where AA is a precomputed prefix for a client and 0000 is based on an index. These two values are stored separately, and to make matters more complex, the digit portion is stored as an integer, which means 0001 would be simply stored as 1.

A whole job could be named AA0001 Do a thing from the user’s perspective, but internally would be stored in three separate columns, one of which is represented in a wholly different way.

Instead of battling the SQL server to allow users to search for three fields as if they were one, I opted to fetch all ‘active’ jobs from the database (of which there are on average about 1,000), and filter them using PHP.

// used with array_filter();
function search_output($var) {
return (strstr(strtolower($var['name']), $_GET['find']) !== FALSE) ||
(strstr(strtolower($var['client']), $_GET['find']) !== FALSE);
}

On average, using a simple matching mechanism such as the one above gave me a response in on average 0.05 seconds, which was fast enough for a responsive interface.

Usability

Let’s face it – everyone except for the most pernickety of people hate logging their time. It’s a fact of life and it’s no different where I work. Any form of friction between getting your job done and logging when you’ve done it will prove frustrating and the end result will be either low quality logging or worse yet, no logging at all.

To that end, the interface had to work quickly to provide users with the information they needed, and to provide as little resistance as possible to getting that timer running. Speed was important in this, but secondary only to a usable interface.

Web interfaces, like all other interfaces, are subject to the effects of precedent. Users aren’t only using your website all day, they’re all over the place – phones, apps on their computers, tablets, even the card machines in the street.

Web interfaces, like all other interfaces, are subject to the effects of precedent.

If an interface component responds in a certain manner, you expect that same component to respond in a similar manner within other interfaces. To use a car analogy, supposing you are a licensed driver, you can get the keys to almost any modern vehicle and have a high chance of being able to drive it away. This is because manufacturers have made sure that car interfaces are as frictionless and consistent as possible.

Sure, there might be the odd moment of “so how do I actually start this?” (I’m looking at you, Audi), or “whoops, that’s wipers not the lights”, but broadly, nobody would ever attempt to turn and discover that the steering had been reversed.

The same applies to any interface element you are attempting to replicate on the web. If you do anything but a perfect job, it will not only feel shoddy, but you’re in danger of it feeling broken, and trust levels will plummet.

As such, certain steps were taken to ensure the finder responded in a consistent manner:

  • Respond to keyboard input, and contain the first pressed letter within the input field.
  • Disappear with the Escape key, or by clicking around it.
  • Begin searching as soon as characters are typed, with no requirement for pressing enter or a submit button.
  • Be navigated with the keyboard arrow keys, as well as the mouse using traditional scrolling.

Adhering to these simple rules would give an interface element for searching jobs that worked consistently with those components users are familiar with and use daily.

Testing

Testing is crucial for any interface component. The requirement to test is compounded further by the necessity to distribute this component without instructions or training to a busy team of over 90 staff.

The finder was rolled out first to a small, technical team who could provide meaningful bug reports and report back on any inconsistencies or UX issues.

When enough issues were ironed out that we felt it would operate “in the wild”, it was then rolled out to the whole company.

Outcome

It might seem like a relatively small component on a burgeoning extranet system, but individual interface elements can make the difference between an easy to use, effective system or an admin nightmare that users avoid until they have to begrudgingly put up with it.

The primary goal was to ensure that the job timer app was not adversely affected and that users could quickly and easily find new jobs to log their hours against.

All of the initial users were positive about the change and felt that it would increase productivity in that area, making finding jobs both in their local timer interface or otherwise incredibly easy.

Leave a Reply

Your email address will not be published. Required fields are marked *