Dropping down

Emily's doggos
Emily's doggos

The select tag

Here's a dropdown.

They're really called select widgets, but many people just call them dropdowns, since that's what they do.

Here's the HTML for that.

  • <select>
  •     <option>Dogs</option>
  •     <option>are</option>
  •     <option>the</option>
  •     <option>best</option>
  • </select>

Here's a more realistic example.

  • <label>Please choose the best animal<br>
  • <select name="best-animal">
  •   <option value="none">(Choose)</option>
  •   <option value="catto">Cat</option>
  •   <option value="doggo" selected>Dog</option>
  •   <option value="llamo">Llama</option>
  •   <option value="poly">Parrot</option>
  • </select>
  • </label>

(The (Choose) option is an instruction for users, and a placeholder for "nothing chosen yet.")

The widget's value in the POST array will have the index best-animal, since that's what the name is.

The value property gives the value of the POST element.

  • If the user chooses Cat, $_POST['best-animal'] will be catto.
  • If the user chooses Parrot, $_POST['best-animal'] will be poly.

The option the user has chosen will have the selected property in the HTML. That's why the dropdown showed Dog when you opened this page:

  • <option value="doggo" selected>Dog</option>

Choosing multiple items

Here's the animal one again, but with some extra stuff.

All that's changed is the select tag.

  • <label>Please choose the best animal<br>
  • <select name="best-animal" multiple size="5" >
  •   <option value="none">(Choose)</option>
  •   ...

multiple means users can choose more than one option. Try it. Click on one, then Ctrl+click on another.

size is the number of items that are shown. If size is less than the number of items in the list, you get a scroll bar.

Multiple selection in POST

Here's that thing again.

So, a user chooses some values, and submits the form. The processing page gets values the user chose. How will the processing page know which values the user choose?

PHP has a little trick here. Put [] at the end of the name property:

  • <select name="best-animal[]" multiple size="5">

$_POST['best-animal'] will be an array, listing all the values the user chose.

Simple example

At the start of this section, we had two simple pages:

  • A form with a widget, that passed data to...
  • A page that showed the user's input.

Let's go back to that, without DBs, to see how the dropdown widget works. You can try it, and download the code.

Here's the HTML, same as before, but with [] added to name.

  • <select name="best-animal[]" multiple size="5">
  •   <option value="none">(Choose)</option>
  •   <option value="catto">Cat</option>
  •   <option value="doggo" selected>Dog</option>
  •   <option value="llamo">Llama</option>
  •   <option value="poly">Parrot</option>
  • </select>

Let's see what different user inputs look like to the processing page, and what output we want. We have to allow for several different scenarios:

If user choice... Then $_POST['best-animal'] is... Desired output
User selected no options

No options selected
Does not exist

Does not exist


Output
Selected only (Choose)

Selected only Choose
One element, with a value of none

Debugger


Desired output
Selected one or more animals

Input
Animals

Debugger


Desired output
Selected one or more animals, and (Choose)

Input
Animals, and none

Debugger


Desired output

The table guides the code we should write.

PHP processing dropdowns

  1. <?php
  2. // Fill $message, and show it in the HTML.
  3. $message = '';
  4. if (!isset($_POST['best-animal'])) {
  5.     // Nothing selected.
  6.     $message = "You didn't choose any animals.\n";
  7. }
  8. if ($message == '') {
  9.     // Test whether just the (Choose) option was chosen.
  10.     $chosen = $_POST['best-animal'];
  11.     if (count($chosen) == 1 && $chosen[0] == 'none') {
  12.         $message = "You didn't choose any animals.\n";
  13.     }
  14. }
  15. if ($message == '') {
  16.     // User chose animals.
  17.     $message = "<p>You chose:</p>\n<ul>\n";
  18.     foreach ($chosen as $animal) {
  19.         // Skip the none option.
  20.         if ($animal != 'none') {
  21.             $animal = ucfirst($animal);
  22.             $message .= "<li>$animal</li>\n";
  23.         }
  24.     }
  25.     $message .= "</ul>\n";
  26. }?>
  27. <html lang="en">
  28.     <head>
  29.         <meta charset="UTF-8">
  30.         <title>Best animals</title>
  31.         <link rel="stylesheet" href="library/styles.css">
  32.     </head>
  33.     <body>
  34.         <h1>Best animals</h1>
  35.         <p><?php print $message; ?></p>
  36.     </body>
  37. </html>

Lines 4-7 handle the nothing-chosen case, using isset() to see if $_POST['best-animal'] exists. If it doesn't, the user didn't choose anything.

Lines 10-13 cover the situation where users selected only the (Choose) option, and none of the animals. It might not make sense for users to choose that, but the code still allows for it.

Reflect

What does the count() function in line 11 do?

If you were logged in as a student, the lesson would pause here, and you'd be asked to type in a response. If you want to try that out, ask for an account on this site.
Adela
Adela

It tells you how many elements are in an array.

Aye!

Lines 18-24 process animal selections. Line 20 skips the (Choose) case, if it was selected.

Let's run through that last bit. Suppose I did this...

Chosen

... and hit the Go button, send the data for processing.

This code...

  • $chosen = $_POST['best-animal'];

... puts data from POST for the widget into $chosen. What's in there? Here's what the debugger says:

Debugger

$chosen is an array, with two elements, each one the value of the thing the user selected:

  • <select name="best-animal[]" multiple size="5">
  •   <option value="none">(Choose)</option>
  •   <option value="catto">Cat</option>
  •   <option value="doggo" selected>Dog</option>
  •   <option value="llamo">Llama</option>
  •   <option value="poly">Parrot</option>
  • </select>

So, let's loop over the array, and make HTML for each of the elements. We want this:

  • <ul>
  • <li>Doggo</li>
  • <li>Poly</li>
  • </ul>

Here's the code again:

  1. $message = "You choose:<br>\n<ul>\n";
  2. foreach ($chosen as $animal) {
  3.     // Skip the none option.
  4.     if ($animal != 'none') {
  5.         $animal = ucfirst($animal);
  6.         $message .= "<li>$animal</li>\n";
  7.     }
  8. }
  9. $message .= "</ul>\n";

Line 1 makes the opening ul. Line 9 closes the ul. The code between them makes all the lis inside the ul.

Now, $chosen has two elements, doggo, and poly. The first time through the loop, $animal will be doggo:

Doggo

Reflect

What does ucfirst do?

If you were logged in as a student, the lesson would pause here, and you'd be asked to type in a response. If you want to try that out, ask for an account on this site.
Ethan
Ethan

Makes the first character of a string uppercase.

Right! It turn doggo into Doggo, better for output.

The second time through the loop...

Poly

...@$animal@ is poly.

The HTML is accumulated in $message. Not simply output it.

  • <body>
  •     <h1>Best animals</h1>
  •     <p><?= $message ?></p>
  • </body>

Exercise

Exercise

Pokemon evolutions

Make a PHP app showing the evolutions for Pokemon the user selects. There's a form with a dropdown showing a few Pokemon, like this:

Input

Click the button, and the user would see:

Output

With this input...

Input

... the user would see...

Output

You can try my solution

Choose any Pokemon you want, at least four.

Submit your URL, and a zip of your files.

Up next

Let's grab options for dropdowns from the DB.