ComboBox vs. FilteringSelect: Selecting The Right Tool for the Job

June 13, 2010 by Ken · 3 Comments 

Continuing for the moment on the topic of Dijit, I turn my focus to two dijit.form widgets which are easily confused: ComboBox and FilteringSelect. These widgets are very similar in appearance, but differ fundamentally in behavior and functionality, which can easily lead to confusion if one is not fully aware of what sets the two apart.

This post aims to give a synopsis of what sets these widgets apart from each other, and will also address a question that I’ve seen repeatedly in the #dojo IRC channel:

  • “How do I get the value of the selected option in a dijit.form.ComboBox?”

UI Behavior

To get started, here’s an example of a ComboBox and a FilteringSelect, side by side, both using the same data.

ComboBox
FilteringSelect

Solely based on appearance, these two widgets look pretty darned identical, right? Now try typing in each one. As long as you’re typing a value that exists within the drop-down, they still behave pretty much exactly the same. But now try typing something that doesn’t exist in the choices in the drop-down, and you should notice the key difference in behavior:

  • ComboBox lets you type whatever you want, acting like a simple textbox with suggestions (like the search textbox on google or bing, for example).
  • FilteringSelect marks the field as invalid if the value typed in the textbox doesn’t match an item in the drop-down, making it more like a drop-down augmented with type-to-select functionality.

Keep this in mind; this distinction will be of utmost importance as we dive deeper to examine how these widgets behave programmatically.

Programmatic Usage

Now let’s return to that question, about getting the value of the selected option in a ComboBox. This is actually somewhat of a trick question; let’s dig in to examine what potentially factors into this question, and then how to answer it.

Note: I will admit I somewhat skim across the surface of a few other potential Dojo topics in the next section. I certainly see potential for future blog posts in some of these areas – if there’s something that interests you, let me know in the comments!

Instantiation

Dojo generally provides two methods of instantiating widgets (as well as other classes): programmatically using JavaScript, and declaratively using HTML that will be run through dojo.parser. Many newcomers first use declarative HTML, finding it to be easier to get into. Let’s look at perhaps the simplest form of HTML markup that could be used to create the ComboBox seen above:

<select id="myCB" name="cb" dojoType="dijit.form.ComboBox">
 <option value="1">one</option>
 <option value="2">two</option>
 <option value="3">three</option>
 <option value="4">four</option>
 <option value="5">five</option>
</select>

Notice how ComboBox accepts an HTML SELECT element as input, containing any number of OPTION tags. Internally, these options get pushed into a data store, which the ComboBox then interfaces with to present its drop-down choices. FilteringSelect shares this behavior; in fact, the above code could be used to instantiate a FilteringSelect simply by specifying it in the dojoType attribute instead of ComboBox.

However, where these two widgets begin to differ is perhaps the point of most interest – obtaining the current selected value.

Let’s look at that example again…

You’ll notice, upon clicking the above link, that two buttons have been added under each widget in the example:

  • One retrieves the value from the widget, e.g. dijit.byId('myCB').attr('value') – this is the preferred way to retrieve form widgets’ values in JavaScript.
  • The other retrieves it directly from the form field element’s value attribute, e.g. document.forms[0].cb.value – this is the value that would be passed to the server when the form is submitted.

Clicking each of the two buttons for the same widget produces the same result. This demonstrates how form widgets included in Dijit are designed to propagate correctly to the server in form submissions, which is quite useful. However, you may have noticed that clicking the buttons for the ComboBox gives a different result than clicking the buttons for the FilteringSelect:

  • The ComboBox’s value reports the text entered in the textbox. (This, combined with the declarative markup, can lead people to ask the question posed earlier.)
  • The FilteringSelect’s value reports the value of the option element fed into the FilteringSelect when we defined it declaratively. (Technically, it’s reporting the value of the identity attribute of the selected item within its data store; recall that our options got pushed into one when the widgets instantiated.)

Now, why the difference in behavior? Why can’t the ComboBox report the associated option (identity) value, too? Recall what we learned above, about the key difference in behavior between these two widgets. Flashback time!

  • ComboBox lets you type whatever you want, acting like a simple textbox with suggestions (like the search textbox on google or bing, for example).
  • FilteringSelect marks the field as invalid if the value typed in the textbox doesn’t match an item in the drop-down, making it more like a drop-down augmented with type-to-select functionality.

Hmm. Let’s think this over and break it down.

ComboBox is inherently free-form, its options only serving as suggestions. You can enter anything in this field and it will remain valid! The ComboBox is really a text field first and foremost; the drop-down is just an added bonus to enhance the user experience. Moreover, if you enter something that doesn’t exist in the drop-down (or really, the data store fueling it), the ComboBox can’t possibly associate an option (identity) value to give back!

FilteringSelect, on the other hand, restricts you to entering values that exist in its drop-down (data store); thus, it is essentially the reverse of the ComboBox – a drop-down first, a text-box second. Therefore, it is completely feasible in this case that every distinct selectable item has an internal value. It would also be feasible to make it behave “consistently” with the ComboBox, if you were so inclined – simply set its option (identity) values identical to its labels.

Conclusion

Let’s definitively answer that (trick?) question:

  • “How do I get the value of the selected option in a dijit.form.ComboBox?”

The short answer is you can’t. However, you might be trying to hammer a nail with a blowtorch – FilteringSelect might be what you’re really looking for, rather than ComboBox.

Each widget has its purpose. Always remember:

  • If you’re interested in a freeform text field with the ability to accelerate user input using a list of prefabricated values, you want a ComboBox.
  • If you’re interested in limiting user input to a set of discrete values, you want a FilteringSelect.

I hope this article proves illuminating to some readers. Feel free to speak up with questions/comments.

Further Reading

Documentation page for dijit.form.ComboBox
API Documentation for dijit.form.ComboBox

Documentation page for dijit.form.FilteringSelect
API Documentation for dijit.form.FilteringSelect

Comments

3 Responses to “ComboBox vs. FilteringSelect: Selecting The Right Tool for the Job”
  1. rajkamal says:

    Nice distinction.

    The link “Let’s look at that example again…” in this page is not hashing but opening tab with same page :-{

    Thanks for the post

    • Ken says:

      Hi, thanks for the feedback.

      You should be able to just left-click the link, what it does is move the node holding the example down to that part of the page. Middle-clicking or otherwise opening in new tab won’t have the desired effect. Sorry if that was confusing.

Speak Up