/    Sign up×
Community /Pin to ProfileBookmark

dynamic dropdown menu

I have a page that has a category dropdown and a position dropdown. When the page displays, I don’t want the position dropdown to have anything in it. When a user selects something from the category dropdown, it calls my Oracle database, gets all the positions that belong to that category, and returns them. I wan my position dropdown to then be populated with these results, all without pressing a submit button. Can anyone help me with this? I searched the forum, but didn’t really find anything to help me.

Thanks!!

to post a comment
PHP

19 Comments(s)

Copy linkTweet thisAlerts:
@bokehJul 25.2006 — Well everyone is going to recommend AJAX (except me). Depending on the number of items you should be able to set up a chained select just by using javascript arrays loaded at stage one. If you want to go the AJAX route though here's a [URL=http://bokehman.com/populate.child.menu]demo[/URL] I wrote for someone else.
Copy linkTweet thisAlerts:
@jrthor2authorJul 31.2006 — could you show me the php code for your AJAX page?

Thanks!
Copy linkTweet thisAlerts:
@bokehJul 31.2006 — Yes, of course but you should know that this was just written as a rough demo and doesn't have any redundancy for people with Javascript disabled.

[code=php]<?php

# DB connect details
$host = '*****'; # fill in
$user = '*****'; # fill in
$pass = '*****'; # fill in

$self = 'http://'.$_SERVER['HTTP_HOST'].htmlentities($_SERVER['PHP_SELF']);

# This populates the child menu
if(isset($_POST['method'])){
$items = array();
$mysql = mysql_connect($host, $user, $pass) or die (mysql_error());
mysql_select_db('test') or die (mysql_error());
$query = "SELECT item FROM clothes WHERE sex = '".mysql_ready($_POST['value'])."' ORDER BY item";
$query_result = mysql_query($query) or die (mysql_error());
if(mysql_num_rows($query_result))
{
while($row = mysql_fetch_assoc($query_result))
{
$items[] = $row['item'];
}
}
xmlResponse($items);
}

# This outputs the main HTML form
echo html_template('Clothes form', form($self), CSS(), javascript($self));

# FUNCTION SECTION #

function mysql_ready($input)
{
if(get_magic_quotes_gpc())
{
$input = stripslashes($input);
}
return mysql_real_escape_string($input);
}

function CSS()
{
return <<<CSS

select{
width:12em;
}

#ChildMenu{
visibility:hidden;
}

CSS;

}


function javascript($action)
{
return <<<JAVASCRIPT

function loadXMLDoc(url, query)
{
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
req.onreadystatechange = processReqChange;
req.open('POST', url, true);
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
req.send(query);
} else if (window.ActiveXObject) {
req = new ActiveXObject("Microsoft.XMLHTTP");
if (req) {
req.onreadystatechange = processReqChange;
req.open('POST', url, true);
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
req.send(query);
}
}
}

function processReqChange()
{
if (req.readyState == 4) {
if (req.status == 200) {
response = req.responseXML.documentElement;
method = response.getElementsByTagName('method')[0].firstChild.data;
result = response.getElementsByTagName('result')[0];
eval(method + '('', result)');
}
}
}

function DropDown(input, response)
{
if(response){
// Response mode
numOptions = response.getElementsByTagName('option').length;
if(!numOptions) return false;
oldNodes = document.getElementById('ChildMenu').childNodes.length;
while(oldNodes>0)
{
document.getElementById('ChildMenu').removeChild(document.getElementById('ChildMenu').childNodes[oldNodes-1]);
oldNodes--;
}
for(i=0;i<numOptions;i++)
{
Text = response.getElementsByTagName('option')[i].firstChild.data;
newOption = document.createElement("option");
newOption.value = Text;
optionText = document.createTextNode(Text);
newOption.appendChild(optionText);
document.getElementById('ChildMenu').appendChild(newOption);
}
document.getElementById('ChildMenu').style.visibility = 'visible';

}else{
// Input mode
selection = input.options[input.selectedIndex].value;
document.getElementById('ChildMenu').style.visibility = 'hidden';
if(selection == '') return false;
url = '{$action}';
query = 'method=DropDown&value=' + selection;
loadXMLDoc(url, query);

}
}

JAVASCRIPT;

}

function form($action)
{
return <<<HTML
<form action="$action" method="POST">
<p>
<select id="ParentMenu" name="ParentMenu" size="1" onchange="DropDown(this,null);">
<option value="" selected="selected">Choose one...</option>
<option value="male">Male</option>
<option value="female">Female</option>
</select>
</p>
<p>
<select id="ChildMenu" name="ChildMenu" size="1">
<option></option>
</select>
</p>
</form>
HTML;

}

function html_template($title, $content, $css = NULL, $javascript = NULL)
{
return <<<HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">

<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<script type="text/javascript">$javascript</script>
<style type="text/css">$css</style>
<title>$title</title>
</head>

<body>
$content
</body>

</html>
HTML;

}

function xmlResponse($input)
{
if(!count($input)) exit;
$output = NULL;
foreach($input as $v)
{
$output .= ' <option>'.$v.'</option>'."n";
}
#ini_set('display_errors', '0');
header('Content-Type: text/xml');
$output = '<?xml version="1.0" encoding="iso-8859-1"?>'."n".
'<response>'."n".
' <method>'.$_POST['method'].'</method>'."n".
' <result>'."n".$output.' </result>'."n".
'</response>';
echo $output;
exit;
}
?>[/code]
Copy linkTweet thisAlerts:
@jrthor2authorAug 01.2006 — Ok, how would youdo this without AJAX? My situation is that I have 15 form fields on my page, and these 2 dropdown menus are already inside my form tag, so I can't have another form inside a form.

I tried implementing your AJAX method and I am getting all the way up to this function
<i>
</i>function processReqChange()
{
if (req.readyState == 4) {
alert("readyState = 4");
if (req.status == 200) {
alert("status = 200");
response = req.responseXML.documentElement;
alert("response = "+response);
method = response.getElementsByTagName('method')[0].firstChild.data;
alert("method = "+method);
result = response.getElementsByTagName('result')[0];
alert("result");
eval(method + '('', result)');
}
}
}

but the response variable is coming back as null.
Copy linkTweet thisAlerts:
@bokehAug 01.2006 — Ok, how would youdo this without AJAX?[/QUOTE]2 methods, the first was suggested in post #2 above (load all options into javascript arrays on initial load). This depends how big the database is. And the second option is a multi step form process with conventional page reloads.
Copy linkTweet thisAlerts:
@jrthor2authorAug 01.2006 — I just posted a reply to the AJAX implentation about getting a null back. The table that I will be calling for the second dropdown list is pretty big. Also, if I was to do multiple page reloads, how can I have a form inside a form? The firs form for the entire page of data, and a form for just these 2 dropdown boxes?
Copy linkTweet thisAlerts:
@bokehAug 01.2006 — I just posted a reply to the AJAX implentation about getting a null back. The table that I will be calling for the second dropdown list is pretty big.[/QUOTE]It's not the size of the table that matters, it's the size of the query result that is important. Also, if I was to do multiple page reloads, how can I have a form inside a form? The firs form for the entire page of data, and a form for just these 2 dropdown boxes?[/QUOTE]You can't! It wouldn't be valid html and would react unpredictibly.

Can you explain in greater detail what you are attempting.
Copy linkTweet thisAlerts:
@jrthor2authorAug 01.2006 — I have a page that has 16 fileds on it for a user to input data. The 5th and 6th input data are dropdown boxes (category and position). When you select a category, i need to populate the position dropdown box with only those positions that are assigned that category id. So, I have a form that wraps all 16 fields, so I can't put another form inside this to populate the position dropdown box.
Copy linkTweet thisAlerts:
@bokehAug 01.2006 — Ok, so lets revisit inputs 5 and 6. How many choices are there in input 5? In total how many choices are there in input 6 taking into account all the choices available in input 5. Is the data public or secure?
Copy linkTweet thisAlerts:
@jrthor2authorAug 01.2006 — this is on an intranet, so it's only internal. There are approximately 60 options in the category dropdown (but this could grow). The position dropdown can also grow, but lets say for now it has 100 positions per category.
Copy linkTweet thisAlerts:
@bokehAug 01.2006 — this is on an intranet, so it's only internal.[/QUOTE]I'd go with the ajax solution then. There should be no noticable lag at all. My code above should be easy to modify for this.
Copy linkTweet thisAlerts:
@jrthor2authorAug 01.2006 — I've tried, but I get a null response object here:

response = req.responseXML.documentElement;

so it stops there.
Copy linkTweet thisAlerts:
@bokehAug 01.2006 — the response variable is coming back as null.[/QUOTE]That is because your sql query is not raising any results.
Copy linkTweet thisAlerts:
@jrthor2authorAug 01.2006 — but it's not hitting my sql query (I have a print statement to print the sql out, and I am not getting that).
Copy linkTweet thisAlerts:
@bokehAug 01.2006 — If it's returning a response it's got past the query. If you are trying to print something out that is probably what is breaking it.

Post the code.
Copy linkTweet thisAlerts:
@jrthor2authorAug 01.2006 — it's not returning a response, the response object is null. I removed my print statement and it still comes back null. What is $action suppossed to be? In the DropDown function, I changes the url variable to be this because I am not set up the same way you are:

$self = 'http://'.$_SERVER['HTTP_HOST'].htmlentities($_SERVER['PHP_SELF']);

url = '<?php echo $self ?>';
Copy linkTweet thisAlerts:
@bokehAug 01.2006 — That code is the exact code in the demo which works fine so there must be a problem with its utilization.

Post the code.
Copy linkTweet thisAlerts:
@jrthor2authorAug 01.2006 — I'll attach the code, it is way too long to post here. The 2 files attached are the relevant code. The injob_post.txt is the main page. The injob_post_commons.txt file is a file that has all the functions in it. Just rename them php.

Thanks for all your help. I kind of need this to work by tomorrow if possible.

[upl-file uuid=dd6f3d54-3a51-4f26-8bf7-3f71b791f039 size=26kB]injob_post.txt[/upl-file]

[upl-file uuid=1aa714e6-3808-4b57-8664-241ffba66fcf size=37kB]injob_post_common.txt[/upl-file]
Copy linkTweet thisAlerts:
@jrthor2authorAug 02.2006 — I got this working using a different AJAX script. Thanks for all your help.
×

Success!

Help @jrthor2 spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.19,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @AriseFacilitySolutions09,
tipped: article
amount: 1000 SATS,

tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,
)...