Photo

Hi, I'm Aaron.

Input Checkbox Arrays

This post covers an unobvious method for submitting checkbox selections, but it also covers, conceptually, how to shape data sent in an HTTP Request params so that it is received by the server as a collection, instead of as a separate value in parallel with the other values.

Checkboxes as a List

A while back, I saw a collection of checkboxes that looked like this:

  <input type="checkbox" name="colors_blue" value="1" />
  <input type="checkbox" name="colors_green" value="1" />
  <input type="checkbox" name="colors_red" value="1" />
  <!-- ... -->

Whether or not you see what the problem is depends a lot on how closely you’ve worked with posting form data.

My first server-side language I used, professionally, was PHP. For all of its faults, it actually does teach you a lot about how form data is posted (per HTTP standards) and how you can work with it.

For those of you who don’t see the issue, let me first show what those checkboxes would look like when posted to a PHP handler. Let’s say we want it to respond back with what the color(s) selected were. Obviously there are many ways to do this, and this is only one possibility.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
  $blue = $red = $green = "";
  if ($_POST['colors_blue'] == 1) {
    $blue = "blue";
  }

  if ($_POST['colors_green'] == 1) {
    $green = "green";
  }
  
  if ($_POST['colors_red'] == 1) {
    $red = "red";
  }

  echo "Your choices were: $blue $red $green";
?>

Maybe you’re clever and realize you can refactor that into a function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
  function get_color($color) {
    if ($_POST["colors_$color"] == 1) {
      return $color;
    } else {
      return "";
    }
  }

  $blue = get_color("blue");
  $red = get_color("red");
  $green = get_color("green");

  echo "Your choices were: $blue $red $green";
?>

It’s actually the same number of lines of code, but will scale better with more colors added: Each color added to the array will add 3 lines to the first example, but only one line to the second.

Another approach would be to iterate over ALL the values in $_POST and use a switch() statement to determine the handling.

Those are all “wrong” solutions.

What I mean by “wrong” is that they’re not utilizing the tools correctly. It would be similar to say that it’s “wrong” to hang a framed picture by hammering the frame itself to the wall (instead of using the picture string on the back and hanging that from a nail). Yes, it technically works, but you’re making your life harder by doing it that way.

Checkboxes as an Array

If you do the HTML like this and they select one more options:

  <input type="checkbox" name="colors[]" value="red" />
  <input type="checkbox" name="colors[]" value="blue" />
  <input type="checkbox" name="colors[]" value="green" /> 

Then you can write your PHP handler like this:

1
2
3
4
5
6
7
8
9
<?php
  $color_choices = "";

  foreach($_POST['colors'] as $color) {
    $color_choices .= "$color ";
  }

  echo "Your choices were: $color_choices";
?>

Five lines. And really, you could shrink it even further if you don’t mind a bit of sloppy implied string interpolation.

1
2
3
<?php
  echo "Your choices were:" . join(','. $_POST['colors']);
?>

One line.

And it will scale infinitely, no matter how many colors you add.

This works because when you pass a named value that is suffixed with [] it is treated as a collection and allows for multiple values to be associated with it. $_POST['colors'] == array("red", "blue", "green")

Were you to do this, and someone checked all the boxes:

  <input type="checkbox" name="colors" value="red" />
  <input type="checkbox" name="colors" value="blue" />
  <input type="checkbox" name="colors" value="green" />

(Note the lack of []s on the name)

The posted array would only contain the last chosen value. $_POST['colors'] == "green"

The best way to learn more about this is to experiment with processing forms. PHP is probably the best way to do this because it sits immediately on the server layer and is readily available on most hosts (and easy to install on your own local machine!). But any server that expects you to handle the requests directly would work.

Further reading on the PHP site.