Combo Boxes and Target Sizes

Just like in darts, it's easier to hit a larger target when using the mouse. With this in mind, let's make our combo boxes more user-friendly.

Combo Boxes and Target Sizes

Importance of Target Size

When designing mouse-optimized user interfaces, one of the most important concepts is target size.  It's a simple concept.  The bigger the target, the easier it is to hit.  

Think about darts.  Hitting the bullseye of a dart board from eight feet away is very difficult.  Hitting the dartboard itself is much easier.  

The same concept applies when it comes to using the mouse to work with a combo box.  

Target Size: Combo Box Edition

There are two primary features of a combo box that make it such a versatile and powerful control: autocomplete and displaying a list of choices via a dropdown window.  

Autocomplete

For autocomplete to work in a combo box with an existing value, the user must first select the entire text within the combo box.  Thus, for maximum efficiency, we want to make it as easy as possible for the user to select all of the text within a combo box.

"We want to make it as easy as possible for the user to select all of the text within a combo box."

The down-pointing triangle on the right side of the control is a relatively small target, especially when you contrast it with the much larger text area to the left.  If the user clicks on an empty combo box, they will usually want to be able to choose from one of the options in the dropdown.  So, we want to make it as easy as possible to trigger a dropdown on an empty combo box.

"We want to make it as easy as possible for the user to show the dropdown for an empty combo box."

Increasing the Target Size: Built-in Approaches

One simple way to increase the target size of a combo box (or any editable control) is to make sure that the control's corresponding label is properly associated with the control.  

Here are the steps to associate an "unassociated" label with its corresponding control.

Labels can never receive the focus themselves.  So, if a label is "associated" with an editable control, then clicking on the label will set focus to that associated control.  In addition to passing focus to the combo box, clicking on the associated label also selects all of the text within the combo box.  As stated above, this is important for streamlining the autocomplete feature.

Clicking on an associated label sets focus to the combo box and also selects the existing text.

Clicking on an associated label increases the target size, but only if your users understand that it's an option.  Probably the best way to train them is to be consistent with your UI design.  Make sure that all labels are associated with their editable control counterparts.  While you're in form design view, watch for the green triangle in the upper left corner of your unassociated labels.  Follow the steps in the above animated gif to associate them with the appropriate control.

Increasing the Target Size: VBA Approach

Sometimes your combo box won't have an associated label.  Not only that, some users will never make the connection between clicking the label and having the focus shift to the combo box's value.

I created a simple function that effectively increases the target size of combo boxes for both autocomplete and dropdown purposes.  

When an empty combo box control receives the focus, the function triggers the combo's .Dropdown method.

Both combo boxes can be dropped down by clicking the down arrow; the enhanced one can be dropped down by clicking anywhere within the combo box or on the attached label (if there is no value in the box).

Autocomplete

When you single-click on a combo box that already has a value, the entire contents of the combo box are selected.  This lets the user immediately replace the value of the combo box, taking advantage of all the autocomplete goodness that comes with doing that.

The enhanced combo box has a bigger target area for selecting all text; a single click anywhere in the box selects the text to allow for immediate replacement.

If the user double-clicks a word in the combo box, we use the default double-click action.  Same goes for the click and drag action.

The Code: EnterCombo()

'Add a call to this function to the OnKeyUp and OnMouseUp events for all combo boxes:
' =EnterCombo([Form].[ActiveControl])   for combo boxes with 1 column only
' =EnterCombo([Form].[ActiveControl],1) for combo boxes with 2 columns (1st hidden)
Function EnterCombo(cmb As ComboBox, Optional col As Integer = 0)
    On Error GoTo Err_EnterCombo
    
    If Nz(cmb.Column(col)) = "" Then
        cmb.Dropdown
    Else
        'we need to check the current selection length, otherwise the control does not work as
        'expected when the user clicks directly on the triangular dropdown symbol
        If cmb.SelLength = 0 And cmb.SelStart > 0 And Nz(cmb.Column(col)) <> "" Then
            cmb.SelStart = 0
            cmb.SelLength = Len(Nz(cmb.Column(col)))
        End If
    End If
        
Exit_EnterCombo:
    Exit Function
Err_EnterCombo:
    'if there is no record selected an error will be generated
    '(happens if control is in form header/footer and AllowAdditions is set to false
    ' and the form is filtered so there are no records)
    'there is no need to fill up the error log with these errors, so we won't record it
    If Err.Number <> 2185 Then
        'Replace with your own error logging function:
        'LogError Err.Number, Err.Description, "EnterCombo", cmb.Name, False
    End If
    Resume Exit_EnterCombo
End Function

Usage

There are two primary ways to call this function: 1) in code or 2) from the Event tab of the combo box Property Sheet.  

To call the function in code:

Private Sub cbExample_KeyUp(KeyCode As Integer, Shift As Integer)
    EnterCombo Me.cbExample
End Sub

Private Sub cbExample_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
    EnterCombo Me.cbExample
End Sub

To call the function from the Property Sheet:

Note that you can only call a public Function from the Property Sheet; you cannot call a public Sub.  That is why I declared the routine as a Function, even though it does not return any results.

Oftentimes you will want to call this function from multiple combo boxes on the same form.  You can hold down the shift key and click on multiple combo boxes to update the On Mouse Up and On Key Up properties for several combo boxes at once.  The problem is that each combo box control will have a different name.

A handy shortcut I use is to pass the ActiveControl property of the Form object to the function.  This way I can assign the function call to several controls all at the same time.

Here's an example:

Use Form.ActiveControl as a handy way to call the same function from the event property of multiple controls all at once.

Photo by Proxyclick Visitor Management System on Unsplash

All original code samples by Mike Wolfe are licensed under CC BY 4.0