HTML Forms - Selection Menus

Chapter 40 26 mins

Learning outcomes:

  1. What is the <select> element
  2. The <option> element
  3. Basic examples of <select> menus
  4. Grouping options using <optgroup>
  5. Using <hr>s inside <select>
  6. Multi-selection menus using multiple

Introduction

So far in this unit, we've encountered a handful of form controls in HTML. We started with the basic <input> element, then explored the <textarea> element, and finally the <button> element.

We have covered three of the four elements in HTML used to represent form controls. The fourth and last one will be explored in this chapter — <select>.

The <select> element is used to represent selection menus in HTML, wherein we have a list of options to choose from. Each option goes in an <option> element.

There is a host of concepts to learn about selection menus in HTML in this chapter, including what are dropdown menus; how to use <select> and <option>; multi-selection <select>s; grouping options via <optgroup>; and much more.

So without further ado, let's get learning.

What is the <select> element?

The <select> element is used to represent a selection menu in HTML.

The <select> element denotes a selection menu, consisting of a list of options to choose from.

In fact, this purpose is evident by the name of the element, that is, <select> means that we can select from a bunch of choices. Not a bad naming for the element.

Using a selection menu, the user can select either one option or multiple options. In this way, a selection menu is similar to a set of radios when it can accept one single option, or to a set of checkboxes when it can accept multiple options.

By default, <select> menus are rendered as a text box ending with an arrow (pointing downwards to indicate that a menu will pop up below):

A <select> menu
A <select> menu

We aren't able to freely enter text into this text box; we can only select from a pre-defined list of options.

When we click on the text box, we see a dropdown menu containing this list of options to choose from. As the name suggests, a dropdown menu is a menu of options that drops down in order to show up, sitting on top of content sort of like a dialog box.

<select> menu expanded when clicked
<select> menu expanded when clicked

We can select any of these options by clicking on it or by navigating to it using arrow keys and then pressing Enter. The active option typically gets a blue background as can be seen above.

As with all form controls in HTML, the <select> element can also be given a name that is used when submitting a form containing it. As you probably guess, this name goes in the name attribute.

To learn more about the name attribute, refer to HTML Forms — Basics: Control name and value.

Besides name, <select> can take most of the general attributes of form control elements in HTML, including required, disabled, etc.

However, the initial value of a <select> can NOT go in its value attribute — as a matter of fact, there is no such attribute as value on a <select>! To specify the initial value of a <select>, we ought to specify the initially selected <option> (more on that below).

And this takes us to the main point...

On its own, the <select> element only represents a list of choices; the individual choices themselves are represented using another element — the <option> element.

The <option> element

The <option> element serves to create an option for a <select> menu.

<option> is a container element that can contain text for the underlying choice. Keep in mind that <option> can NOT contain any HTML elements within it; only text.

Whether or not <option> can even contain text depends upon the existence of two attributes on it — label and value. If both of these are present, <option> can NOT have any content within it.

The following table showcases some common attributes used on <option> elements:

AttributePurpose
selectedSpecifies whether the option is pre-selected or not.
valueThe value submitted for the <select> element.
disabledSpecifies whether the option is disabled or not.
labelThe label, i.e. the text, rendered for the <option>.

There isn't that much to cover for the <option> element so let's get straight into some examples in order to understand the working of these few attributes.

Basic examples of <select> menus

Let's say we want to create a form asking the user to enter his favorite programming language. We previously did a similar thing when demonstrating the usage of radio buttons.

While they are superbly useful when we have a few options to choose from, the thing with radio buttons is that the moment we have many possible choices for a given input, presenting all those choices with radio buttons can become visually overwhelming.

In such a case, we're better off at putting all those choices behind a selection menu.

Coming back to the example, we have a total of 8 choices in this order: C, C#, C++, Perl, PHP, Python, Java, and JavaScript.

The following code creates a <select> control to represent this set of choices:

<form>
   <label>
      Your favorite language
      <select name="favorite_lang">
         <option>C</option>
         <option>C#</option>
         <option>C++</option>
         <option>Perl</option>
         <option>PHP</option>
         <option>Python</option>
         <option>Java</option>
         <option>JavaScript</option>
      </select>
   </label>
   <button>Submit</button>
</form>

Live Example

Let's quickly make sense of what's happening here:

The <select> is named "favorite_lang". This represents the name of the parameter sent in the request the moment we submit the form.

Each option in the <select> is given by a separate <option> element, whereby its content represents the text of the choice.

Note that, by default, when <option> doesn't have value set, as we have here, its content denotes its value if it gets submitted in the form. So for example if we select the 'JavaScript' option, and then submit the form, the query string of the URL in the address bar would read ?favorite_lang=JavaScript.

And this is all that's there to explain for this elementary example.

Let's add some more bells and whistles to it.

What if we wish to have the 'Java' option pre-selected when the <select> menu renders? Well, in that case, we ought to set the selected attribute on the <option> element corresponding to 'Java'.

This is done as follows:

<form>
   <label>
      Your favorite language
      <select name="favorite_lang">
         <option>C</option>
         <option>C#</option>
         <option>C++</option>
         <option>Perl</option>
         <option>PHP</option>
         <option>Python</option>
         <option selected>Java</option>
         <option>JavaScript</option>
      </select>
   </label>
   <button>Submit</button>
</form>

Live Example

Go on and open the link above — you'll notice the <select> element reading the text 'Java' initially, thanks to the specification of selected on the <option> element corresponding to 'Java'.

Great!

Now, typically when websites have <select> menus containing a large list of options, it's not HTML developers manually coding each and every option; the servers serving these websites instead use the power of given programming languages to dynamically generate these menus.

And in this respect, the options of the menus are already stored somewhere in the server, for e.g. in a database, or as an array in memory, etc.

What's important for us to know is that when this is the case, servers are usually not interested in getting back the exact text of each choice — they already have this knowledge with them. Instead, what servers want is the position of the choice in the list, often referred to as its index in the list. Using the index, they can correctly map to the corresponding text.

Let's take this idea to our example. Clearly, since we're not working with a server-side programming language (like PHP), we'll be indexing each option manually.

Consider the following code:

<form>
   <label>
      Your favorite language
      <select name="favorite_lang">
         <option value="0">C</option>
         <option value="1">C#</option>
         <option value="2">C++</option>
         <option value="3">Perl</option>
         <option value="4">PHP</option>
         <option value="5">Python</option>
         <option value="6">Java</option>
         <option value="7">JavaScript</option>
      </select>
   </label>
   <button>Submit</button>
</form>

Live Example

Everything is the same as before, just that each <option> now has an explicit value set on it. This value is the index of the option in the list of options.

Indexes in programming customarily begin at 0. The first element in a list (or collection, or sequence) has the index 0, the second one has the index 1, and so on.

Now, if we select any option and then submit the form, we'll get something like ?favorite_lang=6 instead of ?favorite_lang=Java.

The server at the back end processing the form will be able to easily determine that the value 6 for the favorite_lang parameter corresponds to the entry 'Java'.

Remember, that the server already has knowledge of all the entries. It can easily map an index to its corresponding entry.

Grouping options using <optgroup>

When presented with a large list of options, it helps to have them grouped based on their respective categories.

To group multiple <option> elements together, HTML provides the <optgroup> element at our dispense. It's a container element, containing all the <option> elements that fall under the same group.

The label for the group goes as the label attribute of the <optgroup> element.

It's possible to omit label but in that case the group's title in the <select> menu would be displayed as blank space, which doesn't look really nice.

For instance, the 8 different programming languages in the <select> example above can be grouped according to their main paradigm.

For the sake of discussion, C, Perl, and PHP fall under the 'Procedural' paradigm, while C#, C++, Python, Java, and JavaScript fall under the 'Object-oriented' pardigm.

The following figure depicts a <select> menu having this grouping based on the paradigm:

<select> menu with groups
<select> menu with groups

In the following code, we create a <select> with this grouping:

<select name="favorite_lang">
   <optgroup label="Procedural">
      <option>C</option>
      <option>Perl</option>
      <option>PHP</option>
   </optgroup>
   <optgroup label="Object-oriented">
      <option>C#</option>
      <option>C++</option>
      <option>Python</option>
      <option>Java</option>
      <option>JavaScript</option>
   </optgroup>
</select>

The first three <option> elements fall under the same category and hence are nested together inside an <optgroup>. The same applies to the next five <option>s — they fall under the same category and hence are nested inside another <optgroup>.

Both the <optgroup> elements are labeled, using their label attributes.

Live Example

Simple, isn't this?

Using <hr>s inside <select>

As per the HTML standard's take on the <select> element, it can contain <optgroup>, <option>, <hr>, and script-supporting (i.e. <script>) elements only.

Hmm. <hr>... Let's try using one.

As you may recall, the <hr> element is used to define a horizontal rule (line) in HTML. It's valid to use it inside a <select> if we wish to visually further distinguish between two different blocks of options.

Consider the following code where we extend the <optgroup> example above by placing a rule right after the first group of options:

<select name="favorite_lang">
   <optgroup label="Procedural">
      <option>C</option>
      <option>Perl</option>
      <option>PHP</option>
   </optgroup>
<hr>
<optgroup label="Object-oriented"> <option>C#</option> <option>C++</option> <option>Python</option> <option>Java</option> <option>JavaScript</option> </optgroup> </select>

Live Example

Now while <hr> can be used in <select> menus, there is not a common usage of it out there, perhaps because it doesn't look that nice when rendered.

So, I'd say to use it sparingly, if at all.

Multi-selection menus using multiple

Without a doubt, the mainstream usage of <select> is in showcasing dropdown menus where we can select one option from a given list of options. However, HTML allows us to configure <select> to be able to accept multiple options.

The multiple attribute comes at play in this respect.

A <select> element with multiple set simply means that we can have more than one option selected. It creates what's referred to as a multi-selection menu.

Importantly though, with multiple, the way a <select> element is rendered by the browser is quite different from the way it's rendered without multiple.

A multi-selection menu
A multi-selection menu

That is, a multi-selection menu is not displayed with the currently selected option depicted in a box which, when clicked, shows a dropdown menu of options — there's just no dropdown, so to speak. Instead, we have a normal scrollable box containing all the options in it, at once.

Selecting multiple options in a multi-selection <select> is a little bit tedious.

If we're using the mouse:

  • To select one option, we can simply click on it.
  • To select another option (with the previous one still selected), we ought to click on it with the Ctrl key pressed.

If we're using the keyboard:

  • To select one option, we can navigate through the options using arrow keys and simply halt the navigation when we arrive at the desired option.
  • To select another option (with the previous one still selected), we ought to navigate with the arrow keys, but this time with the Ctrl key pressed. Once we arrive at the desired option, we need to click on the spacebar.

These steps have been simplified to a little extent as we've ignored the interaction of the Shift key in the selections.

All in all, it's not a very trivial thing to select multiple options from a multi-selection <select> menu. A mere user, who might not know about the fact that Ctrl can often be used to select multiple things (not just in a multi-selection menu but in other kinds of user interfaces) won't be able to use it without frustration.

Anyways, moving on, because a couple of options are shown at once when using a multi-selection menu, the number of these options shown initially is given by the size attribute of <select>.

size gives the display size of a <select>. When omitted, size defaults to "0" but the display size is taken to be 4, i.e. the rendered menu is as big so as to accomodate 4 entries (<option> and <optgroup> elements).

When size is omitted, its value is NOT "4"; it's only the display size for the menu that is 4! Surprising, isn't it?

How are multiple selected options in a <select> submitted?

When we have multiple selections for a <select> element, they are submitted just like multiple selected checkboxes. That is, each selected <option> is submitted as its own parameter, with its respective value.

For example, if we have a select named lang and we select two options with the values "0" and "1", and then submit the form (via the default GET method), the query string will read as follows: ?lang=0&lang=1. lang=0 corresponds to the first selected option and lang=1 corresponds to the second one.

Let's consider a couple of examples to help us better understand all this theory.

In the following code, we transform our familiar favorite language <select> input into a multi-selection menu by applying the multiple attribute on it:

<select multiple name="favorite_lang">
   <optgroup label="Procedural">
      <option>C</option>
      <option>Perl</option>
      <option>PHP</option>
   </optgroup>
   <optgroup label="Object-oriented">
      <option>C#</option>
      <option>C++</option>
      <option>Python</option>
      <option>Java</option>
      <option>JavaScript</option>
   </optgroup>
</select>

Note that we've made two additions here in order to make the layout look a little bit better with the multi-selection menu: a <br> after the label text, to have the <select> appear below it; and a <br> after the <select>, to have the button appear below it as well.

Live Example

Here's the rendered output for this <select>:

Notice how we have four entries in the menu; this is because of the default display size of 4 (as the size attribute is omitted).

Now, let's bring in the size attribute to increase the display size to 8:

<select multiple size="8" name="favorite_lang">
   <optgroup label="Procedural">
      <option>C</option>
      <option>Perl</option>
      <option>PHP</option>
   </optgroup>
   <optgroup label="Object-oriented">
      <option>C#</option>
      <option>C++</option>
      <option>Python</option>
      <option>Java</option>
      <option>JavaScript</option>
   </optgroup>
</select>

Live Example

As is evident here, by virtue of size="8", we get a total of 8 entries displayed at a time in the multi-selection menu.

If we set size to a given number, the selection menu will be extended to that very display size. This might mean that, in order to reach that display size, the menu is filled with lots and lots of blank space. Therefore, use size carefully!

Extending this example further, in the following code, we pre-select the first and third languages using the selected attribute:

<select multiple size="8" name="favorite_lang">
   <optgroup label="Procedural">
      <option selected>C</option>
      <option>Perl</option>
      <option selected>PHP</option>
   </optgroup>
   <optgroup label="Object-oriented">
      <option>C#</option>
      <option>C++</option>
      <option>Python</option>
      <option>Java</option>
      <option>JavaScript</option>
   </optgroup>
</select>

Live Example

"I created Codeguage to save you from falling into the same learning conundrums that I fell into."

— Bilal Adnan, Founder of Codeguage