Validate your (x)html code. For example, there is no language attribute for the script element which also lacks the required type attribute, and you are also mixing html and xhtml code.
While there are several ways to achieve what you want, the simplest in my opinion is to use XHR.
Something along the lines of...
Keep the second select element initially empty. It will be updated after something is selected in the first one.
Organism
<select name="organism" onchange="initializeGenome(this);">
<option value="0">Please select...</option>
<option value="1">Frog</option>
<option value="2">Alien</option>
</select>
<br/>
Genome
<select name="genome" id="genome">
<option value="0">Please select...</option>
</select>
This javascript code executes onchange event for first select element.
<script type="text/javascript">
function initializeGenome(el)
{
var target = document.getElementById('genome');
target.length = 1;
if (el.value == 0)
return;
/* I'd recommend using some javascript framework (jQuery perhaps) to handle this since
* the IE family prior to IE8 didn't have XMLHttpRequest and instead used some
* legacy crap solution.
* If you don't need to support older browsers or don't want to start using a js fw
* then google for "xhr", "ajax" or "xmlhttprequest", possibly in combination with "php".
*/
var x = new XMLHttpRequest();
// Event that fires every time x changes readystate. when readystate == 4, the request has completed
x.onreadystatechange =
function()
{
/* But a completed request isn't necessarily a successful request.
* HTTP status code should obviously be 200
*/
if (x.readyState == 4 && x.status == 200)
{
updateGenomeSelect(x.responseText);
}
};
/* encodeURIComponent not necessary for numeric data, but for arbitrary text you
* should use it.
*/
var postData = 'organism='+encodeURIComponent(el.value);
/* .open() must be called before you can set request headers
* The third parameter makes the request asynchronous, i.e. the script execution
* doesn't halt and wait for completion of the request. This is a good thing
* since you can't guarantee that the server will be always able to respond in a reasonable
* amount of time, and the client should not hang during this time
*/
x.open('post', 'a_test.php', true);
// These are needed for post data
x.setRequestHeader("content-type", "application/x-www-form-urlencoded");
x.setRequestHeader("content-length", postData.length);
x.setRequestHeader("connection", "close");
// This sends your post request
x.send(postData);
}
function updateGenomeSelect(data)
{
/* google for "jsondecode vs eval" - eval is bad, but you should read more about
* this since you can't count on browsers having native support for
* json decoding (other than using eval)
*/
var d = document;
var opt_data = eval('('+data+')');
var target = d.getElementById('genome');
for (var i = 0; i < opt_data.length; ++i)
{
var opt = d.createElement('option');
opt.value = opt_data[i].value;
opt.text = opt_data[i].text;
target.appendChild(opt);
}
}
And this php script should be executed as a result of the javascript code above
<?php
/* IE fix. If you don't send this, IE decides what content-type the content _really_ has,
* even though you say it's something else. You might for example say that you send text/plain
* but IE decides that it really is text/html and futhermore claims this is for security reasons!
*/
header('x-content-type-options: nosniff');
/* This ought to be application/json but since IE7 or possibly even IE8 wouldn't accept that
* you should use text/plain.
*/
header('content-type: text/plain; charset=utf-8');
if (isset($_POST['organism']))
{
$id = (int) $_POST['organism'];
# get genome from database
# create an array looking like this
$rows = array(
array('id' => 1, 'text' => 'Option text 1'),
array('id' => 2, 'text' => 'Option text 2'),
array('id' => 3, 'text' => 'Option text 3')
);
echo json_encode($rows);
}
exit;