3 Essential UX Ideas

3-essential-ux-ideas

I have had the opportunity to work with some inspiring clients during the last year. People who are ready to think outside the box and focus on delivering the best experience for their users. I want to share three simple, yet essential, ideas you should keep in mind when creating modern user interfaces.

Since I mainly work with the excellent KnockoutJS MVVM framework and the Twitter Bootstrap CSS framework I quickly saw the benefit of creating reusable plugins for dealing with these tasks. This led to a small project called KoLite that me and my good friend John Papa released on Nuget.

1. Keep it clean stupid

To be truly productive you need to minimize all distractions that are not essential to the core task. This means a user interface without hundreds of buttons and elements always visible. However, you still want quick access to your secondary tasks without requiring too much of an effort. Here is a (greatly simplified) list editor:

Instead of showing the Edit and Remove buttons at all times we show them only when hovering over an item. This makes the user interface much more clean and non-distracting, yet keeping the actions easily accessible. Also, this is implemented by some simple css styling – no JavaScript hacks that will make your code smell.

If you are targeting touch devices you might want to rethink about how to implement this since they are not as hover friendly as your regular desktop browser is.

2. What the hell is going on?

The most annoying thing as a user is to not know what is going on – am I waiting for something or has the program crashed? I usually start my clicking frenzy after 2-3 seconds if I do not see some sort of activity indicator spinning somewhere. My rule of thumb is if you are executing an action that does not finish immediately (<100 ms) then you must inform the user what is going on. Check out what happens when you remove an article from the list:

This is my preferred way of showing an activity – inside the UI element that triggered the action. This applies to buttons as well as text boxes and drop down lists. I try to avoid the use of activity indicators that blocks the whole UI unless they are needed (and they rarely are).

You should definitely check out the activity indicator in KoLite. It will make implementing your activity indicators a piece of cake.

3. Modal dialogs are so 2002

I try to avoid modal dialogs in favor of inline editing wherever possible, mainly because of the following reasons:

  1. They block the rest of the UI, which means if I want to navigate elsewhere or access some other information on the same page, I need to close the modal dialog (this usually means I lose any information entered in the dialog form).
  2. It makes it difficult to edit multiple items at the same time, something that I find more and more useful every day.
  3. Using dialogs does usually not work as seamlessly as inline editing when working with frameworks like KnockoutJS.

Try the inline editing below, together with the activity indicator I think this provides a clean and intuitive UX:

Keep in mind that allowing for multiple items to be edited at once may require you to handle cases where there are dependencies differently.

Conclusion

The key to good user interfaces is a delicate balance of design and productivity. It requires a lot of thought, iteration and testing before finding the sweet spot between a clean, responsive and and yet powerful UX.

Carry these simple rules with you at all times:

  • Keep the UX clean, do not be afraid of white space or larger font sizes.
  • Never keep your user waiting in the unknown, show what is going on – always.
  • Avoid blocking the user interface at all costs, the user will appreciate the freedom.
  • Use frameworks that will help you implement features like this without stealing your time. KoLite is one example.

Feel free to look at the jsFiddle that I made for this article. I also recommend checking out John Papa’s awesome course on Single Page Apps with HTML5, Web API, Knockout and jQuery where I helped out on some of the UX work and many of these ideas are used.

Beware of the <button>

Buttons

Doing a lot of HTML5 development with Knockout lately led me to a rather peculiar bug. One of our testers reported that in IE, for some reason, weird things happened when using the enter key in input fields.

After some debugging I found out that pressing the enter key in an input field triggered the click event on the nearest button element. This caused the Knockout click binding to trigger which, in turn, called the view-model. As you probably understand this led to some rather interesting behavior.

After some research, I found out that this is caused by so called Implicit form submission, as stated in the HTML5 specification:

A form element’s default button is the first submit button in tree order whose form owner is that form element.

If the platform supports letting the user submit a form implicitly (for example, on some platforms hitting the “enter” key while a text field is focused implicitly submits the form), then doing so must cause the form’s default button’s activation behavior, if any, to be run.

Well that is strange I thought, for two reasons.

My button is a button and not a submit button?

It turns out I have fallen victim to my own assumptions about the button element. I always thought omitting the type attribute would default to the button type since… well, it is a button?! This was not the case, again – as the HTML5 specification states:

A button element with no type attribute specified represents the same thing as a button element with its type attribute set to “submit”.

Oh well, that explains alot. Just  declare the button type attribute on all button elements and you will be fine, no big deal.

My input field is not even placed inside a form?

If I am not reading the HTML specification above completely wrong it clearly states form element’s default button is the first submit button. So if a button is inside a form element, it should automatically trigger the first submit button inside the form. Let us confirm this directly:

Works like a charm, looks like the specification was correct. As I said this strange behavior only occurred in IE (say what? IE behaving strange?!) and not in Chrome or Firefox. Let us try the same code, but without the form:

If you try this out in IE you will notice the button still gets triggered. After some quick research I cannot find anywhere where this behavior is documented, so – does IE have an implicit form somewhere that does not show in the DOM? I am out of ideas.

Conclusion

The important lesson here is not to avoid the submit behavior when doing clientside developement, but to know that SUBMIT is the default behavior and that IE, for some reason, works differently than the other browsers (and the HTML specification) by making it submit even without a form.

Lost in Context

Lost In Context

The more time I spend with JavaScript and its rich ecosystem of frameworks the more I find myself looking back at the strongly typed Silverlight/C# horizon with a smirk on my face.

The dynamically, loosely typed nature of JavaScript excells in GUI development where binding from DOM elements, doing Ajax requests with JSON and extending functionality in third-party frameworks is an everyday task.

It has been a long path from the bias and naive developer judging JavaScript as a necessary evil whose sole existence was justified by being the only cross browser language. After reading the excellent and mind-opening book JavaScript – The Good Parts I started to realize the potential of the language and since then my expectations have been far exceeded.

There are a few quirks though..

The sparse native API can sometimes remind you that you are working with a language that was created in ten days. Fortunately, the dynamic typing comes to the rescue once again and allows for third-party frameworks to fill many voids and extend features you have got used to in other, more well-designed, languages. Sugar is an excellent testament to this.

… and I can live with that, but not this

This, also known as the scope, is the execution context of which the current function is executed in. In most object-oriented languages this usually refers to the object instance in which the function is declared. In JavaScript however, this can be anything. This often confuses people, like me for example, who comes from a background programming in languages where you never have to worry about what the current scope is.

If you have done any programming in JavaScript, how often haven’t you lost track of this? I do it all the time, in Ajax callbacks:

$.ajax({
    url: 'getorders/',
    success: function(result) {
        this.orders = result;
    }
});

and in event subscriptions:

this.articleName.subscribe(function(name) {
    this.articleSlug(name.toLowerCase());
});

even in for each loops:

this.callbacks.forEach(function(callback) {
    callback(this.sammy);
});

The problem with this is that no third-party framework can *fix* it. It’s part of the core language itself and therefore not subject to the same extension or modification methods that the API, the native objects, are.

If you are working mostly with the DOM using jQuery for example, you probably don’t have to worry about this that much. But if you’re like me, creating business applications with a great deal of data binding using view models and POJSOs (is that what you call them? plain old javascript objects?), then you will run into scope problems sooner or later.

OK, so how to make this suck a little less?

I have tried a few different approaches to make work with my Knockout view models simpler. One approach was inheriting from a view model base class, using the simple inheritance technique from John Resig. The base class would provide functions to its subclasses letting them do Ajax calls, subscribing to events and more with the scope always refering the to view model instance.

This worked somewhat well, what I didn’t like about this was that it only solved the problem when you used the functions provided by the base class. If you wanted to do something else, like subscribing to an Knockout observable in your subclass, you’re back to square one again.

The solution that I’ve never had any scoping problems with is when you copy a reference to this in your view model’s constructor. Then you’re always certain that self refers to the actual view model instance.

function MyViewModel() {
    var self = this;

    self.articleName = ko.observable();
    self.articleSlug = ko.observable();
    self.callbacks = [];
    self.orders = ko.observableArray();
    self.sammy = new Sammy.Application();

    $.ajax({
        url: 'getorders/',
        success: function(result) {
            self.orders(result);
        }
    });

    self.articleName.subscribe(function(name) {
        self.articleSlug(name.toLowerCase());
    });

    self.callbacks.forEach(function(callback) {
        callback(self.sammy);
    });
}

Some people say it’s a code smell to declare a self variable and I can agree to some extent but my experience is that it’s easily worth it.