PHP Sessions and select.selectedIndex (I can't figure this out!)

Hi all,

I am attempting to develop a registration system for a login system (which I have yet to build) that uses PHP sessions to pass data from a user_registration.php file to a register.php file. However, I am having difficulty setting the select.selectedIndex field of a select dropdown menu using sessions, nonnumeric data, hidden fields, and javascript. Can someone look over my code and see if anything is wrong with my code? I apologize about so much code being included but I wouldn't be able to really explain it otherwise.

The state_sel and grade_sel variables are declared in a session_init.php file (not all code is shown for the sake of space):
PHP:
<?php
//session_init.php
$_SESSION['GRADE_SEL'] = "";
$_SESSION['STATE_SEL'] = "";
$_SESSION['SESSION'] = true;

?>
An data array is set up for specific values that will be used in session_func.php:
PHP:
<?php
//session_func.php
//setup a dummy array that will contain values that we want to work with...
$arVals = array('grade_sel'=>"", 'state_sel'=>"", 'fname'=>"", 'lname'=>"", 'email'=>"", 'school'=>"", 'grade'=>"", 'address'=>"", 
                    'city'=>"", 'county'=>"", 'state'=>"", 'city'=>"", 'zip'=>"", 'phone'=>"");
?>
user_registration.php (not all code is shown for the sake of space). This file contains my registration form with the hidden fields and javascript that is supposed to set the values for my hidden fields.
PHP:
<?php
//user_registration.php
session_start();
if (!isset($_SESSION['SESSION'])) require("session_init.php");  //If session does not exist then it is started here.
    $arVals = array();
    require_once("session_func.php");
    
    //make sure the session values are initialized...
    reset($arVals);

    while(list ($key, $val) = each($arVals)) {
        if (!isset($_SESSION[$key])) $_SESSION[$key] = "";
        if ($_SESSION[$key]== "NULL") $_SESSION[$key] = "";
        if ($debug) echo $key . " : " . $arVals[$key] . "<br />";
    }

    if ($_SESSION['grade_sel'] == "") $_SESSION['grade_sel'] = 0;
    if ($_SESSION['state_sel'] == "") $_SESSION['state_sel'] = 0;
?>
My javascript validation method that is "supposed" to pass the values of my hidden fields but seems to pass the default values:
PHP:
//user_registration.php
<script language="javascript" type="text/javascript">
      function SubmitForm() 
      {
          var form = document.forms[0];
          var bRequired = true;
          
          //Client-side field validation to determine if required fields are blank.
          if ((form.firstname.value.length < 1) ||
              (form.lastname.value.length < 1) ||
              (form.school.value.length < 1) ||
              (form.county.value.length < 1) ||
              (form.email.value.length < 1) {
                  alert("Please fill out all the required fields.");
                  bRequired = false;
              }
          if (!bRequired) return false;     
          
          form.grade_sel.value = form.grade.selectedIndex; //gets the selected value of the grade selection dropdown
          form.state_sel.value = form.state.selectedIndex; //gets the selected value of the state selection dropdown
          
          form.submit();
      }
  </script>
The hidden fields in my form located in user_registration.php:
PHP:
//user_registration.php
<input name="grade_sel" type="hidden" value="<?php echo $_SESSION['grade_sel']; ?>" /> <!-- Used to update selection field -->
        <input name="state_sel" type="hidden" value="<?php echo $_SESSION['state_sel']; ?>" />
If the user is redirected from register.php (see below) back to the user_registration.php page, it is supposed to display previously entered values including those in the drop down box. However, I am sending non-numeric data so I am unsure as to why select.selectedIndex is not working here:
PHP:
//user_registration.php
<script language="javascript" type="text/javascript">
    //Set the selection box values...
        var form = document.forms[0];
        form.grade.selectedIndex = parseInt("<?php echo $_SESSION['grade_sel']; ?>");
        form.state.selectedIndex = parseInt("<?php echo $_SESSION['state_sel']; ?>");
    </script>

register.php determines if values are entered and redirects back to user_registration.php if they aren't. Also, it reads the posted variables from $_POST array into the $_SESSION array:
PHP:
//register.php
    session_start();
    
    if (!isset($_SESSION['SESSION'])) require("session_init.php");  //If session does not exist then it is started here.
    $arVals = array();
    require_once("session_func.php");
    
    reset($_POST);
    
    //Gets $_POST values and adds them to session variables.
    while (list($key, $val) = each ($_POST)) {
        if ($val == "") $val = NULL;
        $arVals[$key] = (get_magic_quotes_gpc()) ? $val : addslashes($val); //Removes single quotes and double quotes to protect DB.
        if ($val == "NULL") {
            $_SESSION[$key] = NULL;
        }
        else
        {
            $_SESSION[$key] = $val;
            //if ($debug) echo $key . " : " . $arVals[$key] . "<br />";
            if ($debug) echo $key . " : " . $_SESSION[$key] . "<br />";
        }
    }
 
Truthfully, you&#8217;d probably be best off just shooting a PM to Giles. ;)
 
I am attempting to develop a registration system for a login system (which I have yet to build) that uses PHP sessions to pass data from a user_registration.php file to a register.php file. However, I am having difficulty setting the select.selectedIndex field of a select dropdown menu using sessions, nonnumeric data, hidden fields, and javascript. Can someone look over my code and see if anything is wrong with my code? I apologize about so much code being included but I wouldn't be able to really explain it otherwise.

OK, the scope for me having misinterpreted what's happening here is massive, but I'll have a go...

I think that you might be overcomplicating things.

Am I correct in thinking that if the form in user_registration.php is being called by registration.php if some predetermined condition is not set?

If you want to set a dropdown using PHP from a $_POST variable (or indeed from some other source, such as a database), you only need to put a condition into the <option> tag, thus:

Code:
<select name="timezone" id="timezone">
<option value="1">Central European</option>

In $_POST you'd have $key="timezone" and $val="1", but the thing is that you can then test for this, and use the "selected="selected" HTML attribute, thus:

PHP:
if($_POST["timezone"] == "1") echo " selected=\"selected\""

The space before the first selected is important. But the point here is that you don't have to pass a numeric value, it just needs to match the option values in the form.

If you want to use Javascript to set form values, I've had much better results with document.getElementById('formvaluename').setAttribute('attributename', value). Firefox seems to cope much better with this than relying upon referring to the DOM and hoping that the browser sorts it out explicitly.

And by the way this check/action:
PHP:
       if ($val == "NULL") {
            $_SESSION[$key] = NULL;
        }

is unnecessary since you've checked and set $val to NULL beforehand - therefore you can just set $_SESSION[$key] to $val, whatever.

I suspect that hasn't helped, but hope it has. :)
 
I probably am overcomplicating this as I have been following a video tutorial from lynda.com about a user registration system.

Am I correct in thinking that if the form in user_registration.php is being called by registration.php if some predetermined condition is not set?
You would be correct in assuming this. Upon posting to register.php from user_registration.php, validation will be performed. If validation is not passed, register.php redirects the user back to user_registration.php.

In $_POST you'd have $key="timezone" and $val="1", but the thing is that you can then test for this, and use the "selected="selected" HTML attribute, thus:

PHP:
if($_POST["timezone"] == "1") echo " selected=\"selected\""
I'm not so sure this would work or be feasible with what I would like to do. If I cannot get javascript to work I will try this instead.

My intention is to have a dropdown menu with all fifty states of America like below:
Code:
<select name="state">
            <option value="AL">Alabama</option>
            <option value="AK">Alaska</option>
            <option value="AZ">Arizona</option>
</select>
My other dropdown is similar, but just has about 5 values in it so your solution would work for that situation though.

If you want to use Javascript to set form values, I've had much better results with document.getElementById('formvaluename').setAttribute('attributename', value). Firefox seems to cope much better with this than relying upon referring to the DOM and hoping that the browser sorts it out explicitly.
I unsure if I follow you on this. Specifically, I understand that I would put the name of the field (such as state) I am trying to set in formvaluename but I am unsure what to put where attributename is.

At the bottom of my page I have something like:
Code:
<script language="javascript" type="text/javascript">
        //Set the selection box values...
        document.getElementById('grade').setAttribute('attributename', "<?php echo $_SESSION['grade_sel']; ?>");
        document.getElementById('state').setAttribute('attributename', "<?php echo $_SESSION['state_sel']; ?>");
    </script>
 
I'm not so sure this would work or be feasible with what I would like to do. If I cannot get javascript to work I will try this instead.

My intention is to have a dropdown menu with all fifty states of America like below:
Code:
<select name="state">
            <option value="AL">Alabama</option>
            <option value="AK">Alaska</option>
            <option value="AZ">Arizona</option>
</select>
My other dropdown is similar, but just has about 5 values in it so your solution would work for that situation though.

I unsure if I follow you on this. Specifically, I understand that I would put the name of the field (such as state) I am trying to set in formvaluename but I am unsure what to put where attributename is.

At the bottom of my page I have something like:
Code:
<script language="javascript" type="text/javascript">
        //Set the selection box values...
        document.getElementById('grade').setAttribute('attributename', "<?php echo $_SESSION['grade_sel']; ?>");
        document.getElementById('state').setAttribute('attributename', "<?php echo $_SESSION['state_sel']; ?>");
    </script>

For 50 states, you could create an array in PHP with the states and their abbreviations in it (or two arrays, whatever works for you) and then spit out the options programmatically, testing against the $_POST each time. I do something similar for my F1 driver lists: 365 drivers and counting...

You referred to a form property "selectedIndex" in your earlier post. I would suspect that the JS command you need is therefore document.getElementById('grade').setAttribute('selectedIndex', "<?php echo $_SESSION['grade_sel']; ?>");. But you should check that.

Also, why are you writing form data into $_SESSION, rather than carrying it over in $_POST? Do you really need to have this data available to all pages in the session?
 
For 50 states, you could create an array in PHP with the states and their abbreviations in it (or two arrays, whatever works for you) and then spit out the options programmatically, testing against the $_POST each time. I do something similar for my F1 driver lists: 365 drivers and counting...

You referred to a form property "selectedIndex" in your earlier post. I would suspect that the JS command you need is therefore document.getElementById('grade').setAttribute('selectedIndex', "<?php echo $_SESSION['grade_sel']; ?>");. But you should check that.

I'll have to try one of these two suggestions. Although, now that I think about it, I suspect the reason why my javascript isn't working has to do with the way my form is being submitted...

Also, why are you writing form data into $_SESSION, rather than carrying it over in $_POST? Do you really need to have this data available to all pages in the session?

Yes. Once the user has submitted the form the first time, the post variables are taken and stored into a session. This is being done to ensure that a user does not have to re-enter data if they are redirected back to the user_registration.php page.
 
For 50 states, you could create an array in PHP with the states and their abbreviations in it (or two arrays, whatever works for you) and then spit out the options programmatically, testing against the $_POST each time. I do something similar for my F1 driver lists: 365 drivers and counting...

I've decided to do this since it would be easier and more reliable in the long run not to rely on users' having javascript enabled. I don't know why I didn't think of this myself...

Thanks Giles! 👍

Here's what I ended up doing for both dropdowns I have... the function below is called from user_registration.php to load an array that contains the values of my options:

PHP:
//session_func.php
function printDropdown($p_SESSION_VAL, $p_ARRAY) {
    while (list($key, $val) = each($p_ARRAY)) {
        if ($p_SESSION_VAL != $key) { //If value is NOT selected by user echo this...
            echo "<option value=\"".$key."\">".$val."</option>";
        }
        elseif ($p_SESSION_VAL == $key) { //If value is selected in dropdown echo this...
            echo "<option value=".$key." selected=\"selected\">".$val."</option>";
        }
    }
}
And the function call from register.php:
Code:
<!--register.php-->
        <select name="state">
            <?php printDropdown($_SESSION['state'], $arStates); ?>
        </select><br />
 
You need an escaped quote mark in your second value attribute. Browsers should parse it as-is, but Sage will come round to your house and bash you.

Also, put in a \n at the end of the string, as it will tidy up the source.
 
You need an escaped quote mark in your second value attribute. Browsers should parse it as-is, but Sage will come round to your house and bash you.

Also, put in a \n at the end of the string, as it will tidy up the source.

I think I caught this one before I saw this. Thank you though.

Do you know of a way to reset form fields that use PHP Session variables? The problem with this is if you use a normal reset button, the browser considers the session values in the fields to be the default values. I've been looking for an answer to this but can't really seem to find one other than using the following javascript (It doesn't seem to work correctly in FF with dropdowns):

Code:
  <script type="text/javascript" language="javascript">
    function ResetForm(objForm){
    var arrElems = objForm.elements; objForm.reset();

    for(xi=0;xi < arrElems.length;xi++){
      formFieldType = arrElems[xi].type.toLowerCase();
      switch(formFieldType) {
        case "text": case "hidden": case "password": case "textarea":
          arrElems[xi].value=""; break;
        case "radio": case "checkbox":
          arrElems[xi].selected = false; break;
        default:
          if(formFieldType.indexOf("select") != -1) 
            arrElems[xi].selectedIndex = -1;
      }
    }
  }
  </script>
 
Try selecting selectedIndex of 0. If you combine this with an initial element of the likes of <option value="xx">Select...</option> then it will work for you, and users like to be given that prompt that it's a dropdown.

Also, you could (this may be a bit dramatic for you) unset($_POST) after rendering the form.
 
Hmm.. changing the code to use a selectedIndex of 0 doesn't seem work for dropdowns since the session variables are considered to be the defaults. Resetting the form just resets the dropdowns to whatever is stored in the session variable for that dropdown at the time.

modified code:
Code:
<script type="text/javascript" language="javascript">
    function ResetForm(objForm){
    var arrElems = objForm.elements; objForm.reset();

    for(xi=0;xi < arrElems.length;xi++){
      formFieldType = arrElems[xi].type.toLowerCase();
      switch(formFieldType) {
        case "text": case "hidden": case "password": case "textarea":
          arrElems[xi].value=""; break;
        case "radio": case "checkbox":
          arrElems[xi].selected = false; break;
        default:
          if(formFieldType.indexOf("select") != 0) 
            arrElems[xi].selectedIndex = 0;
      }
    }
  }
  </script>

I'll send you a link in a PM to the page that I am working on so that you can visualize the form reset problem that I am having...
 
Back