2009-02-19

Combo box vs Button

I don't know exactly why, but I almost never use combo boxes/drop-down liste etc.

If we have an order with an order status, where order status can be cancelled, pending, approved and shipped.

I often see screens like this:

comboboxvsbutton1

The screen makes sense for most developers because that is how the data i structured in the database, usually with an Order and OrderStatus table.
In code this is mapped to an Order class and an OrderStatus enum, where the Order class has a Status property with the type of OrderStatus.

So its easy with data binding to make every property a field in the screen, and most data binding will happily make enum properties to combo boxes.

What does the user want to do

So how can we express the order status without a combo box?

Actually the question is not hard to answer, just try to understand what the user really wants.
”A user wants to be able to change the order from a status, to any status that is valid.”

In the above case, most likely not every order status is valid from all other order statuses. So its ok to go from Pending to Approved, but not from Shipped to Pending.

So the key is, to only show valid changes in order status, and to make the user able to trigger these changes.

A solution could look like this screen:

comboboxvsbutton2 

Conclusion

While simple data binding is easy to do in most platforms, it might not be the best solution – from a users perspective.

4 comments:

Anonymous said...

How about, it is most often not the best solution.

Not that there aren't valid reasons for databinding, but often it is a UI short cut for presenting data like data, as opposed to creating a UI that helps a user...which happens to have data behind the scenes.

I know this was not the point of your article, and your example was just to make a point, but…
As far as UI helpfulness goes, is the omission of choices for status OK? Using your example, below, I the user want to change the status to Shipped (for examples sake I know this is corny). I go to click the Shipped button, but wait, it’s gone! I swear that is how I changed the status to Shipped on something yesterday! So I call Morten on the phone, “What happened to the Shipped button!?”
“You mean it’s not there?” says Morten.
“No!” says the mad user.
“Doh,” says Morten, “maybe I messed that up with the last release when I refactored that form a bit.”
30 minutes of wasted time later, Morten realizes that it does not show up because the status must have been pending or cancelled, or some other status that does not provide the ability to go to a status of Shipped.
I call this phenomenon. Hidden business rules.

What I like better, whenever possible, is having the button there and when I click it is explains the business rule to me. Code, written with easy testability in mind and database independence might look a little like this.

On Click()
If CurrentStatus.CanChangeTo(ChosenStatus, out WhyNotMaybe)
OrderService.ChangeStatus(ChosenStatus)
Else
MessageBox(“Can’t change status”, WhyNotMaybe);
End if


…Food for thought

Morten Lyhr said...

A valid point.

Often you need to show more buttons as it is dependt on some dynamic aspect of the screen. Say if field cancel reason has a value, it is ok to cancel the order else it is not.

A counter agument is that if you have many statuses, do the user really want 12 buttons?

Another solution could be to have a button/link to a help screen, where the posible state changes are shown. The link could be labeled "why cant set status to ?".

If it is a LOB application, the user should be a expert in their own business. If it is a public application most users will not be familiar with the business.

There is no silverbullet.

Anonymous said...

"If it is a LOB application..."

Very good point. I often blog about how the context strongly affects our choices and how often people hotly debate best practices without ever considering each other's context.

Morten Lyhr said...

Context is king...