Filtering Options in a Select Box with jQuery

Posted in . There are 0 responses.

I recently created a web form for a client that had two <select> elements, where the options presented to the user in the second <select> element were determined by the option selected in the first <select> element. It is a nifty feature to automatically filter options for the user, while providing validation at the same time. It can be a time saver for the user, even if it is only a matter of milliseconds. It also makes form validation stronger knowing that your user won’t get sloppy when filling out your form.

Take out the Guess Work

In my example, the first <select> element contains primary drink categories, and the second <select> element contains specific drinks that fall under one of those categories. It might be confusing to some users if they were to select “Juice” as their primary option and included in their secondary options were “Sam Adams” and “Coke”. Let’s assume that the user submitted the form, having selected “Juice” and “Sam Adams”. What the heck are you suppose with that data? You don’t know if the user wants some sort of juice or specifically “Sam Adams”. Why give the user an opportunity to make a mistake? Take the guess-work out of the form and make it as simple as possible for the user to interact with.

Using the jQuery library and the JavaScript provided in this tutorial, we will be able to validate these fields, making sure that the user actually selects a drink and flavor. We will also be able to filter flavor results based on what the user chooses for a primary drink. This means if the user selects “Soda” for a drink, we’ll only let them see the flavors: “Coke”, “Root Beer”, and “Sprite”.

Setting up the HTML

Before we get started, I’ve created a working example which combines all of the HTML and JavaScript I’ll be covering in this tutorial. It might also help to view the source code of the provided working example.

In the HTML below, I’ve created two <select> elements, each with several options. The first <select> element contains drink options for choosing a drink category. The second <select> element contains flavor of the drink. You’ll notice that in the <option> elements nested within the second <select> element we’ve also specified a class attribute which matches up with its parent category. We’ll be using the value of the options in the drink <select> element to match up with the classes in the flavor <select> element in our JavaScript.

We want the second <select> element to be disabled by default, but rather than specifying this in the HTML, we’ll use JavaScript. This way if the user has Javascript disabled, the form will still be functional.

<form>

  <label for="primary">Drink Category</label>
  <select name="primary" id="primary">
    <option value="">-- Select a Drink --</option>
    <option value="Beer">Beer</option>
    <option value="Juice">Juice</option>
    <option value="Soda">Soda</option>
  </select>

  <label for="secondary">Flavor Selection</label>
  <select name="secondary" id="secondary">
    <option class="" value="">-- Select a Flavor --</option>
    <option class="Juice" value="Apple">Apple</option>
    <option class="Beer" value="Budweiser">Budweiser</option>
    <option class="Soda" value="Coke">Coke</option>
    <option class="Beer" value="Corona">Corona</option>
    <option class="Juice" value="Grape">Grape</option>
    <option class="Juice" value="Leomonade">Leomonade</option>
    <option class="Beer" value="Miller">Miller</option>
    <option class="Juice" value="Orange">Orange</option>
    <option class="Soda" value="Root Beer">Root Beer</option>
    <option class="Beer" value="Sam Adams">Sam Adams</option>
    <option class="Soda" value="Sprite">Sprite</option>
  </select>

</form>

Making it Cool with JavaScript

This tutorial uses the jQuery library to make life easier for our validation and filtering needs. I’m a big fan of jQuery and I highly recommend it. I realize that using jQuery can add a significant amount of page load time. While we want to be able to validate the form, we also don’t want to have the user wait for JavaScript to load before they start filling out the form. This is why I prefer placing JavaScript right before the closing </body> tag. The first thing we need to do is to include the jQuery library. You can download and host it yourself, or you can do what I do and let Google host it for you.

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>

All of our JavaScript will be in a self-contained function filterSelectBox(). In our function, the first thing we’ll do is disable the second select element. We’re using JavaScript to do this, rather than HTML, in case the user has JavaScript disabled. If we used HTML and the user had JavaScript disabled, the drink element would never become enabled. We’ll also create an array of all the drink options from the second <select> element. Then we’ll assign it to a variable. We’ll be filtering out options in this array based on the <option> the user chooses from the first select box.

(function filterSelectBox() {

  $("#secondary").attr("disabled", "disabled");

  var arr = $.makeArray(document.getElementById("secondary"));

})();

Now that we have our array assigned to a variable, we want to create an event handler that executes whenever the user changes the state of the first <select> element (which has an id of “category”). In this event handler, we also want to define a couple more variables. The first variable, primaryCat will equal the value of the first <select> element, and the second variable, txt equals an empty string.

$("#secondary").change(function() {
    var primaryCat = $("#primary").val(),
        txt = "";
});

In the following if statement, we want to check to see if the user has selected an option (technically, an option with a value) or not. If the user has, then it will enable the secondary (drink) select element, otherwise, it will disable it.

if (primaryCat !== "") {
  $("#secondary").removeAttr("disabled");
} else {
  $("#secondary").attr("disabled", "disabled");
}

If the user has selected a valid drink category, we want to go through every option in the array of flavor options we created earlier and only keep ones where their class matches the value of the drink option. After we’ve filtered the drink options, we want to flush out all of the current flavor options and replace them with the new ones. We’re only keeping results where the options in the drink select element whose class is equal to the value of the parent category. After we’ve filtered the options, we’re removing all the current options and appending the string of new options to the drink select element.

$.each(arr, function() {
  var subCatClass = $(this).attr("class"),
    subCatValue = $(this).val();
  if (subCatClass === primaryCat) {
    txt += '<option class="' + subCatClass + '" value="' + subCatValue + '">' + subCatValue + '<\/option>';
  }
  $("#secondary").empty().append(txt);
});

This working example combines all of the HTML and JavaScript I described in this tutorial.

Wait a minute, is it really worth the hassle?

I’d like to assume that the average user is competent enough to fill out a form correctly, but you and I both know that a lot of users are not. At the very least, you should probably be using some sort of basic form validation, whether it be client-side, server-side or both. It doesn’t take too much more time or effort to make things a littler easier on the user by filtering their options — especially if there are a lot of options to choose from. You’re also saving yourself time and energy by applying form validation because you won’t have to try and sort out faulty submissions.

Since the Beginning of the Browser Wars

Posted in . There are 2 responses.

Just like anything else, web design goes through its own fads. One of the current trends, or rather, a popular question to ask is "Do websites need to look exactly the same in every browser?". This question has particularly been made popular by this website created by Dan Cederholm. There's no such thing as a stupid question, but the answer should be somewhat obvious: Nope.

I understand why this question has been so popular lately with a lot of designers pushing to use CSS3 attributes such as: border-radius, box-shadow, text-shadow, and the list goes on. Having said that, this isn't the first time this question has been asked. Fifteen years ago when everyone was coding using the <table> element for layout and the <font> element for styling, we were still at the mercy of browser wars. Some of the names and faces were different, but the battles were the same. Table attributes rendered differently, if they were even recognized, across IE and Netscape, and specifying font sizes via the <font> element always varied as well across the browsers.

Unless you're using Flash, I'd say it's next to impossible to have design consistency across different browsers, and that's totally fine. It's been like that since the birth of the browser wars.

Closing Out 2009

Posted in . There are 0 responses.

Another year has come and gone. They seem to be going by faster every year too. And with every year comes many changes, both professionally and personally. Since I’ve started blogging a few years back, I’ve taken the time at the end of every year to sum up what’s been going on in life, and set some goals for myself.

Career Changes

About nine months ago, I was extremely blessed to be offered a full-time job working for Cramer Dev. I had been doing freelance work for them for two years prior, so it was a comfortable change, having known most of my coworkers. This was welcomed for several reasons, but the number one is that I get to work from home and be with my family all the time.

I’ve just about stopped all freelance work and am not currently looking for any. The only projects outside of my full-time job that I’ve taken on are personal projects or favors for friends and family. I was blessed several years ago to have the freelance to help pay the bills and I’m blessed that I don’t need the extra money these days.

Changes on the Home Front

My wife and I are expecting our third child in early-March. This is another welcomed change and we’re all very excited. Children are a real blessing and we love our kids very much. It’s amazing to see just how much they’ve grown in the last year.

Goals for 2010

I like to set some goals, with the notion that if I don’t get something done, it’s no big deal. I’ve never been a huge fan of New Year Resolutions for a couple of reasons:

  1. In Matthew 6:34, it reads, “So don’t ever worry about tomorrow. After all, tomorrow will worry about itself. Each day has enough trouble of its own.”
  2. I don’t like to set things in stone, so that if I don’t get it done, I don’t have to feel like a failure.

For 2010, I’d like to make more time to spend with my family and do more out-of-the-house activities. I have a bad habit of blurring the lines between work life and home life. Working from home makes that even harder for me. These past nine months have been great and I’ve been working hard at learning where to set boundaries, and not let work overlap.

Professionally, I’d like to learn more about JavaScript, Object-oriented programming, and MVC frameworks. I’d also like to try to blog more often than I do now, but we’ll see about that one.

There are other goals that I have, but those are the big ones. It’s been a terrific year with big changes and I’m sure next year will be no different. Have a Happy New Year!

Twitter: Creating an Open Dialogue

Posted in . There are 1 responses.

In the past several months, I’ve made some negative (as well as some positive) remarks on Twitter about my experiences with certain corporations. Within minutes of making these remarks, I was bombarded by them apologizing for the inconvenience, asking for more feedback, or telling me flat out that my statement was incorrect. One even tracked me back to my website and sent me a lengthy email via my contact form.

It’s cool how Twitter has actually made this dialog possible with not only corporations, but also politicians, celebrities, and the general public. Someone like me can just casually tell the world what they think, and there are people out there actually listening. We’ve never really had this opportunity before where anyone can get their voice heard. Who would have thought that some corporation would actually care about what I think or say?

Thoughts on A/B Testing and Wireframing Tools

Posted in . There are 0 responses.

During my recent visit to Chicago for the Cramer Dev quarterly get-together, we attended the Windy City Rails conference. While I’m anything but a RoR developer, I still learned some interesting stuff about the language, as well as some general principles that can be applied to font-end development. Ryan Singer of 37Signals, gave a great talk entitled UI Fundamentals for Programmers. It was a very informative session, and in some ways, it has changed the way I approach the designing process.

Ryan believes that the UI is a really important layer of software because it’s what the users see. I happen to agree with him. In his presentation, he discussed some simple, yet key concepts for designing and implementing UI for applications. More specifically he talked about communicating with the user through on-screen language, as well as using visual techniques to consciously control what the user should be focusing on. He finished his presentation by talking about some techniques for implementing templates and helpers.

At the end of Ryan’s presentation, he took some questions from the audience. There were two questions in particular where I thought he made some rather bold statements about A/B testing and wireframing software. While every designer holds different opinions regarding these topics, I’d like to voice my dissent with Ryan’s views.

A/B Testing

When Ryan was asked for his thoughts on A/B testing, his reply was “We don’t have a lot of patience for that (testing).” I don’t have a lot of patience for A/B testing myself because it’s time consuming and it’s a total drag to create several variations of one function, or an entire web page for that matter. However, making the perfect UI, which would look and function differently for everyone, is an impossible task. I’m not saying that everything needs to be A/B tested on a web app, but to have the attitude, “make one version that makes sense to us and launch it,” means you’re ignoring the user experience for a potentially large number of your users.

Ryan also stated that “testing happens on the marketing side but not within the app.” More power to them. I’m sure 37Signals has crunched the numbers and knows whether it’s worth their time in dollars and cents to do A/B testing within their software. But from a general standpoint, a company could potentially be loosing out on a lot of profit all because they think A/B testing “is a drag.” What I’m saying is, don’t write off A/B testing because you don’t like to do it. Research and figure out if it’s worth your time and resources. In the end, it’s all about the ROI.

Another point I’d like to make about A/B testing is what makes sense to one user will not make sense to another. Design is very subjective and while a design may be aesthetically pleasing based on principle, not everyone is going to like it. Even though we’re inevitably going to alienate some of our users, the goal is to alienate the least amount as possible. If done properly, A/B testing can provide solid data about how your users respond to certain elements of a web site, including design aesthetics. One thing we might learn is that our users’ perception may be vastly different from our own. A very good book that talks about these principals in more detail is Don’t Make Me Think by Steve Krug.

Wireframing Software

Another question that came from the audience was asking Ryan about his thoughts on tools like Balsamiq, or wireframing tools in general. Ryan’s response was “I don’t understand what they are for.” I loathe wireframing software and would much rather work out ideas on a whiteboard or on paper. Ryan does not interact with external clients when designing for 37Signals, but I do. The reason why wireframing software is necessary is because a client expects more than just some doodles on a piece of paper.

Whereas Ryan might dive right into Photoshop or writing HTML, it doesn’t seem cost-effective to me to follow that process. My typical client tells me they want a website and that’s about all the info I get. If I didn’t ask any probing questions about features or content, I don’t think I’d get too much more information from the client until it was too late into the design process. Wireframing helps to breakthrough some of the informational and layout challenges. It would take a lot more time and resources to achieve the same goals once you’re in mock up or development phase of a project.

Everyone has different opinions regarding A/B testing and wireframing software. I’m sure there are plenty of folks out there who would argue my points, and I’m not saying that my methods are the right way. There are multiple paths to achieving a finished website, and it will vary depending on the size of an organization, resources, and personal preferences.

Back to top