Thursday, March 26, 2015

Using vanilla javascript and php to change the select options on a form

For a project at work I needed a simple form component.  I wanted one select that showed organization.  When an organization was selected I needed it to populate the next select with the people in that organization. I decided I wanted to do this with old school vanilla javascript. So there will be no jquery or angular, etc. To take it a step further. The select options needed to be filled out from a mysql database.

We will need a form with two select fields.  The first one will have the name of of the organization and the value set to an identifying number. The second select will be empty.  We set an onchange event of the first select to call our javascript function, switchSecondSelect.

<form name="form" id="form">
<select name="first_select" id="firstselect" onchange="switchSecondSelect();">
<option selected="selected" value=""> </option>
<option value="1"> Value 1</option>
<option value="2"> Value 2</option>
<option value="3"> Value 3 </option>
</select>
<br />
<br />
<select name="second_select" id="second_select">
<option selected="selected" value=""></option>

</select>

</form>

In switchSecondSelect we will do several things. First we have to zero out the value of the second select.  If it had been previously set by an onchange event and the new options list was shorter than the old one, the option list would include what was left over from the previous. To set the options in a select we use the Option method.

  Since we want to set both the value of the option and the text displayed. In most languages this would be done with an associative array with the key being the text and the value being the option value.  But javascript doesn't have associative arrays. Luckily it does have Objects which are pretty much associative arrays. The syntax is similar to an array except for the use of {} and a key value pair separated by a :.  We then use the Option method to set the options on the second select.

Here is our function:

//move selections inside the function so I can choose which to use
function switchSecondSelect(){
 //Zero out the length of the select
 document.getElementById("second_select").options.length=0;
 var selections = {"": ""};
 
 var select_one = document.getElementById("firstselect").options.selectedIndex;
 var selected_value = document.getElementById("firstselect").options[select_one].value;
 if(selected_value == 1){
  var selections = {1: "Bob Smith", 2: "Barb Smith"};
 } else if(selected_value == 2){
  var selections = {3: "Kofi Okoro", 4: "Ba Okoro", 5: "Keita Okoro"};
 } else if(selected_value == 3)
 {
  var selections = {6: "Camille Rodriguez"};
 }
 
 
 
 //use option constructor to set second selects options.
//We always want the first option blank for our use here.
 document.getElementById("second_select").options[0] = new Option("", "", true, false);

 //now  go through the object and feed those values into the select
 var count = 1;
 for (value in selections)
 {
  
    
  document.getElementById("second_select").options[count] = new Option(selections[value], value, false, false);
  count++;
 } 
}

Now things get really complicated and I am not going to explain most of it. We need to use php to query mysql and then use the results to construct the first select and the javascript function. In the code, I call custom functions that are part of our framework. We use two tables in the database. The first has the organization name and a unique identifying number. The second table contains information for the people as well as a unique identifying number for that person and a field that records which organization they are involved with.

    <form name="form" id="form">
        <select name="first_select" id="firstselect" onchange="switchSecondSelect();">
            <option selected="selected" value=""> </option>





        </select>

<script type="text/javascript">

    //Set an array of the values you want to change the second select options to have to use an object since javascript doesn't have associative arrays
    //since we want to set the value and string
    //  Where as var array = ["one", "two", "three"];  Objects use the syntax below
    document.getElementById("firstselect").options[0] = new Option("", "", true, false);



    <?
        $companies = $this->app->getAllCompanies();
      
        $count = 1;
         foreach($companies as $company)
        {


                $company_id = $company['rec_id'];
                $company_name = $company['name'];
                echo "document.getElementById(\"firstselect\").options[$count] = new Option(\"$company_name\", \"$company_id\", false, false); \r\n";
                $count++;
        }
    ?>



    //move selections inside the function so I can choose which to use
    function switchSecondSelect(){
        //Zero out the length of the select
        document.getElementById("second_select").options.length=0;
        var selections = {"": ""};

        var select_one = document.getElementById("firstselect").options.selectedIndex;
        var selected_value = document.getElementById("firstselect").options[select_one].value;
        <?
            $sizeCompanyArray = sizeof($companies);
            $count = 1;
            foreach($companies as $company)
            {


                $company_id = $company['rec_id'];

                $employees = $this->app->getContactsByCompany($company_id);
                //set the first selects values which should be the company identifier and the name

                echo "if(selected_value == $company_id) {";
                echo "var selections = {";

                foreach($employees as $employee)
                {
              //  util_debug($employee);
                    $name = $employee['first_name'] . " " . $employee['last_name'];
                    $rec_id = $employee['rec_id'];
                    echo "$rec_id: \"$name\", ";


                }
                echo "}; }";
                if($count != $sizeCompanyArray)
                {
                    echo "else ";
                }
                $count++;

            }
        ?>






        //use option constructor to set second selects options. Always have the first one empty. This is necessary for our framework
        document.getElementById("second_select").options[0] = new Option("", "", true, false);
     
        //now  go through the object and feed those values into the select
        var count = 1;
        for (value in selections)
        {


            document.getElementById("second_select").options[count] = new Option(selections[value], value, false, false);
            count++;
        }
    }
</script>

    <br />
    <br />
    <select name="second_select" id="second_select">
        <option selected="selected" value=""></option>
        <?
    }

No comments:

Post a Comment