Tricking an HTML form to POST with unselected radio inputs

Tricking an HTML form to POST with unselected radio inputs

simple-radio-formThis web-development situation confused me: why wasn’t my simple form, consisting of a single radio button set, throwing the expected error when submitted without a selection? Spoiler alert: HTML forms don’t include values for unselected radio buttons (or checkboxes, it turns out).

The problem

I stumbled across this issue when, as part of a larger web application I was building, I created the first step in the process using my standard form set-up. PHP is my preferred development environment and I’ll typically re-use known good code when starting a new project. For forms, I start with a form that submits to itself via POST:

 $variableName = (array_key_exists("inputName", $_POST)) ? $_POST["inputName"] : ""; 

and then processing the input via PHP before the rest of the page content, like this:

<form action="< ?= $PHP_SELF ?>" method="post">
// form stuff
</form>

Thus the contents of the input (or and empty string “” if the input was not set) is stored in $variableName. Then I can perform server-side form validation such as ensuring required fields are set, e-mail addresses are valid, and displaying error messages back to the user, in PHP code that’s only executed when the form has been submitted. I determine that by the existence of PHP’s automatic creation of an array storing post values:

if( $_POST) {
// check the user's inputs, create error messages, process form, etc.
}
// other PHP and HTML displayed the first time, before any form submission

This approach has always worked, so I was confused when the simple form shown here failed to display the “Please chose an option” message I expected when submitted without a choice being made. After a lot of trial and error, I discovered that because no value is selected for either radio button in the browser and because it’s the only input in the form, PHP does not create the $_POST array. Therefore, my if statement fails and none of the user messages are generated and the form does nothing. Technically, it’s not horrible; the user simply has to realize they didn’t click anything and resubmit. But from a user-experience standpoint, that’s a big fail.

The solution

There are (at least) two ways to solve this:

  • Hidden input – Setting a hidden input with some arbitrary value forces the creation of the $_POST array. Also, the same setting the name attribute the same as the radio buttons’ name ensures that assigning that name to a variable will result in a value for that variable. And then you can check whether the variable has the hidden input’s value. If so, the user didn’t select one of the radio buttons.
  • Checking for the existence of the specific name – Rather than relying on the existence of the $_POST array, PHP’s isset() function can determine if a value for the radio buttons was selected:
    if( isset( $_POST["inputName"] ) ) {
    	// a radio button choice was made
    }
    

What I don’t like about the second approach is it’s not as clean as the hidden input because it requires another function call. That simple call is hardly a performance hit, but why add complexity if you can avoid it? And checking for a specific element in the array lacks the elegance of just using if( $_POST ). Checking for the existence of the specific variable name in $_POST does work to perform server-side validation on those radio buttons, though. But even in this case I prefer the first approach because collecting the variables as described above will work (the hidden input will provide the value) even if no radio button selection was made. Slick.

  1. Cross-post: One developer's perspective on the SWS's course search resource The UW's Office of Information Management invited me to be...
  2. Cross-post: The fight against academic falsification I recently wrote an entry over at the UW Registrar's...
  3. Little-known CSS selectors Anyone worth his or her proverbial web development salt knows...

Leave a Reply

You must be logged in to post a comment.