Processing <form> controls with the MULTIPLE attribute
Simple <form> elements, such as the <input> element, allow only one value to be associated with them. For example, an <input> element with the name attribute surname may have an associated value of Smith; in a URL query string, this association is represented as surname=Smith. Indeed, all the controls included in <form> examples in previous chapters have only one associated value. However, the <select multiple> element allows the association of more than one value with a variable in a <form>.
The <select multiple> element allows users to select zero or more items from a list. When the selected values are sent through using the GET or POST methods, each selected item has the same variable name but a different value. For example, consider what happens when the user selects options b and c in the following HTML <form>:
<form method="GET" action="click.php"> <select multiple name="choice"> <option>a</option> <option>b</option> <option>c</option> <option>d</option> </select> <br><input type="submit"> </form>
When the user clicks Submit, the following URL is requested:
http://localhost/click.php?choice=b&choice=c
From a PHP perspective, this means that the variable $choice-which has the same name as that of the <select multiple>-is overwritten as the request is decoded, and an echo $choice prints the last value that was selected. In this case, echo $choice outputs c.
There are at least two solutions to this problem in PHP. First, it's possible to add more complex processing of the two automatically initialized arrays, HTTP_GET_VARS or HTTP_POST_VARS, to detect duplicate variable names and handle these for generic processing. Second, more elegantly and simply, you can use a PHP feature, which is described next.
The second approach works as follows. You modify the <form> and replace the name of the <select multiple> with an array-like structure, name="choice[]". The PHP interpreter then treats the variable as an array and stores the multiple values into $choice[0], $choice[1], etc. In the previous example, the <select multiple> element is renamed as choice[]:
<html><form method="GET"> <select multiple name="choice[]"> <option>a</option> <option>b</option> <option>c</option> <option>d</option> </select> <br><input type="submit"> </select></form></html>
If the user selects options b and c, the following PHP fragment prints out all selected values, in this case both b and c:
foreach($choice as $value) echo $value;
The bracket array notation in a <form> can cause some problems with client-side scripts-such as those written in JavaScript-and such <form> elements should be referenced wrapped in single quotes in a JavaScript script. Client-side JavaScript for validation is discussed later in this chapter.
Interestingly, <textarea> and <input> elements can also be suffixed with brackets to put values into an array, should the need arise.
Other <form> issues
Checkbox elements in a <form> have the following format:
<form method="GET" action="click.php"> <input type="checkbox" name="check"> <input type="submit"> </form>
A checkbox has two states, on and off, and is usually rendered as a small clickable square in a graphical web browser. If the checkbox in the example is clicked, and the <form> submitted, the following URL is requested:
http://localhost/click.php?check=on
However, if the checkbox isn't clicked, the URL requested is as follows:
http://localhost/click.php
The important difference is that a checkbox is never off from the server perspective. If the checkbox isn't clicked, no variable or value is submitted to the server. Therefore, in a PHP script, a checkbox should be tested with the following fragment:
if ($check == "on") echo "Checkbox is on"; else echo "Checkbox is off";
Additionally, in the previous example, if the checkbox isn't clicked, it isn't possible to determine whether the <form> has been submitted or has never been displayed. An easy solution is to add a name attribute to the submit <input> element as follows:
<form method="GET" action="click.php"> <input type="checkbox" name="check"> <input type="submit" name="submit" value="Submit Query"> </form>
If this <form> is submitted with the checkbox in the off state, the following URL is requested:
http://localhost/click.php?submit=Submit+Query
Testing whether the variable $submit is empty( ) can then distinguish between the initial display of the <form> and a subsequent submission of the <form> with the checkbox in the off state. The following script skeleton performs this check:
if (!empty(submit)) // carry out processing else // display the <form>
In addition, the naming of submit <input> elements permits more than one submit button to be added to a <form>. This allows two or more different types of submission that may have different validation or other behavior. For example, both Save and Cancel buttons may be present in the <form> as two different types of submission process. We use this approach in the winestore and discuss it further in Chapter 11.
Multiple <select> elements have the same property as checkboxes; if no item in the list is selected, no variable or value is submitted to the server.