Issue with state drop down from array

I am very new to PHP and am having issues populating a drop down menu of states from an array. I need the choice to remain in the drop down in case the user submits with an error (i.e. an empty field or incorrectly formatted field). Here is my code. Any help is appreciated.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

[php]<?php
/* Program name: customer_form.inc

  • Description: Defines a from that collects customerinformation.
    */
    $labels = array ( “first_name” => “First Name”,
    “middle_name” => “Middle Name”,
    “last_name” => “Last Name”,
    “address” => “Address”,
    “city” => “City”,
    “state” => “State”,
    “zip” => “Zip”,
    “email” => “Email”,
    “phone” => “Phone”);

$states = array ( “AL” => “Alabama”,
“AK” => “Alaska”,
“AZ” => “Arizona”,
“AR” => “Arkansas”,
“CA” => “California”,
“CO” => “Colorado”,
“CT” => “Connecticut”,
“DE” => “Delaware”,
“FL” => “Florida”,
“GA” => “Georgia”,
“HI” => “Hawaii”,
“ID” => “Idaho”,
“IL” => “Illinois”,
“IN” => “Indiana”,
“IA” => “Iowa”,
“KS” => “Kansas”,
“KY” => “Kentucky”,
“LA” => “Louisiana”,
“ME” => “Maine”,
“MD” => “Maryland”,
“MA” => “Massachusetts”,
“MI” => “Michigan”,
“MN” => “Minnesota”,
“MS” => “Mississippi”,
“MO” => “Missouri”,
“MT” => “Montana”,
“NE” => “Nebraska”,
“NV” => “Nevada”,
“NH” => “New Hampshire”,
“NJ” => “New Jersey”,
“NM” => “New Mexico”,
“NY” => “New York”,
“NC” => “North Carolina”,
“ND” => “North Dakota”,
“OH” => “Ohio”,
“OK” => “Oklahoma”,
“OR” => “Oregon”,
“PA” => “Pennsylvania”,
“RI” => “Rhode Island”,
“SC” => “South Carolina”,
“SD” => “South Dakota”,
“TN” => “Tennessee”,
“TX” => “Texas”,
“UT” => “Utah”,
“VT” => “Vermont”,
“VA” => “Virginia”,
“WA” => “Washington”,
“WV” => “West Virginia”,
“WI” => “Wisconsin”,
“WY” => “Wyoming”
);

$submit = “Submit Information”;
?>
[/php]

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Customer Form</title>
  <style type='text/css'>
   <!--
      form {
        margin: 1.5em 0 0 0;
        padding: 0;
      }
	  .dropdown {
	  	margin-left: 18%;
		margin-top: 1em;
		margin-bottom: 1.5em;
	  }
      .field {padding-bottom: 1em;}
      label {
        font-weight: bold;
        float: left;
        width: 20%;
        margin-right: 1em;
        text-align: right;
      }
      #submit {
        margin-left: 35%;
      }
   -->
     </style>
</head>

<body>
<h3>Please enter your information below:</h3>

[php]<?php
/* loop that displays the form */
echo “”;
foreach($labels as $field=> $label)
{
if($field == “state”)
{
echo “

”;
“”;
foreach($states as $state) {
echo “<option value=’”.@$$field."’)’.$state’";
}
echo “
\n”;
else
{
echo"
$label
<input id=’$field’ name=’$field’ type=‘text’ value=’".@$$field."’
size='50% maxlength=‘65’ />
\n";
}
}
echo "


";
?>
[/php]

[code]

[/code]

try
[php]
if($field == “state”) {
echo “

”;
“”;
foreach($states as $state) {
if(!empty($_POST[‘state’])) {
echo “$_POST[state]”;
} else {
echo “$state”;
	}
}
echo "</select></div>\n";

} else {
[/php]

I tried this out but now the drop down has disappeared. I should have noted that I have a separate PHP file that checks the form and all this is working.

I am just having issues with the drop down pulling from the array and I would like the selection in the drop down to remain if the user submits the form and the error messages show (for empty fields, wrong format, etc).

I’ve included copy of my additional PHP code. But again the issue is with the code I posted previously.

Thanks again for your help,
Aubree.

[php]<?php
/* Program name: check_form.php

  • Description: Program displays the blank form and checks

  • all the form fields for blank fields, for correct formating and

  • it cleans the data.
    /
    if(isset($_POST[‘submitted’]) and $_POST[‘submitted’] == “yes”)
    {
    foreach($_POST as $field => $value)
    {
    if(empty($value))
    {
    if($field != “middle_name”)
    {
    $blank_array[] = $field;
    }
    }
    else
    {
    $good_data[$field] = strip_tags(trim($value));
    }
    }
    if(@sizeof($blank_array) > 0)
    {
    $message = "


    You didn’t fill in one or more required fields.
    You must enter:

      ";
      /
    display list of missing information /
    foreach($blank_array as $value)
    {
    $message .= “
  • $value
  • ”;
    }
    $message .= “

”;
echo $message;
extract($good_data);
include(“customer_form.inc”);
exit();
}
/ checks format of the user information */
foreach($_POST as $field => $value)
{
if(!empty($value))
{
$first_name_patt = “/^[A-Za-z’ -]{1,50}$/”;
$middle_name_patt = “/^[A-Za-z’ -]{1,50}$/”;
$last_name_patt = “/^[A-Za-z’ -]{1,50}$/”;
$address_patt = “/^[A-Za-z0-9 .,’-]{1,50}$/”;
$city_patt = “/^[A-Za-z’ -]{1,50}$/”;
$state_patt = “/^[A-Za-z’ -]{1,50}$/”;
$zip_patt = “/^[0-9]{5}(-[0-9]{4})?$/”;
$email_patt = “/^.+@.+\…+$/”;
$phone_patt = “/^[0-9)(xX -]{7,12}$/”;

if(preg_match("/first_name/i",$field))
{
if(!preg_match($first_name_patt,$value))
{
$error_array[] = “$value is not a valid first name”;
}
}
if(preg_match("/middle_name/i",$field))
{
if(!preg_match($middle_name_patt,$value))
{
$error_array[] = “$value is not a valid middle name”;
}
}
if(preg_match("/last_name/i",$field))
{
if(!preg_match($last_name_patt,$value))
{
$error_array[] = “$value is not a valid last name”;
}
}
if(preg_match("/address/i",$field))
{
if(!preg_match($address_patt,$value))
{
$error_array[] = “$value is not a valid address”;
}
}
if(preg_match("/city/i",$field))
{
if(!preg_match($first_name_patt,$value))
{
$error_array[] = “$value is not a valid city”;
}
}
if(preg_match("/state/i",$field))
{
if(!preg_match($state_patt,$value))
{
$error_array[] = “$value is not a valid state”;
}
}
if(preg_match("/zip/i",$field))
{
if(!preg_match($zip_patt,$value))
{
$error_array[] = “$value is not a valid zip”;
}
}
if(preg_match("/email/i",$field))
{
if(!preg_match($email_patt,$value))
{
$error_array[] = “$value is not a valid email”;
}
}
if(preg_match("/phone/i",$field))
{
if(!preg_match($phone_patt,$value))
{
$error_array[] = “$value is not a valid phone number”;
}
} // end format check
}

$clean_data[$field] = strip_tags(trim($value));
}
if(@sizeof($error_array) > 0)
{

$message = “

    ”;
    foreach($error_array as $value)
    {
    $message .= “
  • $value
  • ”;
    }
    $message .= “
”;

echo $message;
extract($good_data);
include(“customer_form.inc”);
exit();
}
else
{
echo "
Information submitted in the form
“;
echo “

    ”;
    foreach($_POST as $field => $value)
    {
    echo "
  1. $field = $value
  2. ”;
    }
    echo “
”;
}
}
else
{
include(“customer_form.inc”);
}
?>
[/php]

I think I know what’s wrong, try
[php]

if($field == “state”) {
echo “

”;
“”;
foreach($states as $state) {
if($_POST[‘state’] == ‘$state’) {
echo “$state”;
} else {
echo “$state”;
	}
}
echo "</select></div>\n";

} else {
[/php]

The drop down is still missing – just a blank space where it should be?

I just took your original code and added some comments to point out syntax errors

[php]
/* loop that displays the form */
echo “”;
foreach($labels as $field => $label) {
if($field == “state”) {
echo “

”;
echo “”; // missing echo on this line
foreach($states as $state_abbr => $state) {
// echo “<option value=’”.@$$field."’)’.$state’";
// using ) instead of > for option tag
// improper use of single single quote and missing . for ‘.$state’
// unknow use of variable variable $$field
		// fixed syntax errors and added ternary operator for selected
		echo "<option value='" . $state_abbr . "'" . (isset($_POST['state']) && $_POST['state'] == $state_abbr ? " selected='selected'" : "") . ">" . $state . "</option>";
	}
	echo "</select></div>\n";
} // missing closing bracket for if statement
else {
	echo "<div class='field'><label for='$field'>$label</label><input id='$field' name='$field' type='text' value='".@$$field."' size='50% maxlength='65' /></div>\n";
}

}
echo "



";
[/php]

This worked! YAY! I really appreciate you taking the time to show me what was wrong with my code.

The solution shows two options – one for the state and one for the abbreviated state. What if I don’t want the abbreviated states to show?

If I update the array to
[php]$states = array ( “Alabama”, Alaska", “Arizona”…);[/php]

Any guidance as to how to fix the foreach statement to show just the one state option? I have fiddled with this with little success.

Any help is appreciated.

Thanks.

[php] foreach($states as $state) {
echo “<option value=’” . $state. “’” . (isset($_POST[‘state’]) && $_POST[‘state’] == $state ? " selected=‘selected’" : “”) . “>” . $state . “”;
}[/php]

This should work without the abbreviations.

This worked. Thank you so much! :smiley:

Gave you +1 seb. I did go overboard and use abbreviations with full names :wink: I personally think it’s better to use abbreviations especially if storing them in a db

This is true; an abbreviation of state is always two characters long. This allows you to store them using VARCHAR(2) instead of VARCHAR(64) or more, which makes index lookups faster at the cost of having to maintain a dictionary.

If you want to make your DB even faster, though, use integers and keep an integer-based dictionary. This reduces the size of your info even more at the cost of not being directly readable - which discourages the very bad practice of editing DB directly.

True, but then you have to hardcode all the abbreviations using a lot of if statements or one hell of a switch. Its not like there’s a lot of states though, a database should be able to handle 50 states easily enough :slight_smile:

Untrue. If you’re using a database, you can make an associative table to keep the ID->value correspondence. Putting a foreign key constraint allows the housekeeping to be done by itself, and you’re gaining in performance over a VARCHAR(2) due to the optimizations done by the SQL engine (assuming you’re finding the state abbreviation or name using an INNER JOIN).

Added bonus: you can keep extra data about your regions as extra fields. Currency, tax, geolocation bounding rectangles, etc etc etc.

That’s a lot of extra work though, lot of debugging too. If you want to put in the time and effort required to do it, its good to do. But its a lot easier to just store the names and abbreviates in the same table or in a switch (that’s how I did it for countries).

Overhead is quite a lot less in terms of mantaining stuff if your code is well written to start with. MVC makes this trivial - Location model with parents. A Location belongs to another Location, which allows you to have region->country hierarchy almost natively. Using a proper DB driver, that’s also one modification of one SQL query (adding an INNER JOIN) and six new SQL directives.

Anyway, nitpicking aside, VARCHAR(2) is still a good solution. 20-25% gain over storing the full name.

Sponsor our Newsletter | Privacy Policy | Terms of Service