Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Dynamically produce Text Fields or Drop Downs

Status
Not open for further replies.

robpet

Programmer
May 30, 2006
4
CA
Okay, I've spent hours trying this, and also checking out the search engines, and I've hit a brick wall...hoping someone can help me with this.

What I have is a drop down. Based on the selection in that drop down using Javascript, I want to produce either a text box, or a second drop down. I want to populate that second drop down with some options. It is populated using AJAX with the valid values pulled from a MySQL database.

This all works great.

However, my problem is that if the option is changed after initial selection it will still work, unless the drop down is generated. At that point, changing the option in the first drop down will never change the generated drop down to a text box. I always get an object is required javascript error. I have tried destroying the object, deleting, unsetting, etc...but for the life of me, can't come up with anything to get it working.

Here is my initial drop down with the javascript call:

Code:

<select name="sel" id="sel" onChange="toggleField(this.value);">
<option value="sales_rep">Sales Rep</option>
<option value="customer">Customer Name</option>
<option value="year">Trade Year</option>
<option value="vin">Vin Number</option>
<option value="wonlost">Status</option>
</select>

and here is the javascript function (toggleField). I know it's sloppy, only because I was manipulating it trying to make it work. I would make it much cleaner in production.

Code:

function toggleField(val) {
var year = document.getElementById('years');
var wonlost = document.getElementById('winlost');
var sales = document.getElementById('sales_rep');
var cust = document.getElementById('customer');
var vin= document.getElementById('vinno');
year.style.display = 'none';
wonlost.style.display = 'none';
sales.style.display = 'none';
cust.style.display = 'none';
vin.style.display = 'none';

if(val == 'year'){
year.style.display = 'inline';
}
else{
year.style.display = 'none';
}

if(val == 'wonlost'){
wonlost.style.display = 'inline';
}
else{
wonlost.style.display = 'none';
}

if(val == 'sales_rep'){
sales.style.display = 'inline';
}
else{
sales.style.display = 'none';
}

if(val == 'customer'){
cust.style.display = 'inline';
}
else{
cust.style.display = 'none';
}

if(val == 'vin'){
vin.style.display = 'inline';
}
else{
vin.style.display = 'none';
}
}



This piece of code is the fields showing or hiding when the first drop down is selected.

Code:

<div id="optdiv" style="display:inline;">
<input type="text" name="sales_rep" id="sales_rep" value="Sales" style="display: none;">

<input type="text" name="customer" id="customer" value="Customer" style="display: none;">

<select name="years" id="years" onmouseover="getOpt('findcity.php?type=year');" style="display: none;">
<option>Select Year</option>
</select>

<input type="text" name="vinno" id="vinno" value="Vin" style="display: none;">

<select name="winlost" id="winlost" onmouseover="getOpt('findcity.php?type=wonlost');" style="display: none;">
<option>Select Status</option>
</select>
</div>

The div is used to assign the location of the dynamically populated data, loaded from MySQL through AJAX, which, as I mentioned, works great.

As a final note, using AJAX, etc, I'm hoping not to post back until the selection is made, my button is clicked, and the results are pulled from the database.

Thank you with any help you can provide...I'm about to pull out the little hair that's left!

rob
 
Hi

I either
[ul]
[li]not understand your problem[/li]
[li]can not reproduce your problem[/li]
[/ul]
Putting together those pieces you provided works for me. Or at least, works as I understand it should work : sel is always visible, the others only if the matching option is selected from sel.

Note that I would rewrite toggleField() before too many people see it. Looks really bad for a programmer.

Feherke.
 
Yes, this code works pretty good. But if the user chooses one of the drop down options from the first drop down, then changes their mind, and switches the first drop down to a text field, it won't change. That's where the problem lies.

And yes, I realize toggleField() is sloppy, and I even said that. I have tried so many things to make this work, including adding additional values in the ifs and elses. It will be much cleaner once I get past this problem.

Thanks for your input... I'm hoping someone had come across this before and may be able to offer some hope.


rob
 
Hi

rob said:
But if the user chooses one of the drop down options from the first drop down, then changes their mind, and switches the first drop down to a text field, it won't change.
[ul]
[li]I select "Trade Year"[ul]
[li]The [tt]select[/tt] saying "Select Year" appears[/li]
[/ul][/li]
[li]I select "Vin Number"[ul]
[li]The [tt]select[/tt] saying "Select Year" disappears[/li]
[li]The [tt]input[/tt] saying "Vin" appears[/li]
[/ul][/li]
[/ul]
If it not does the same for your, probably there is an error is some other code you not posted.


Feherke.
 
Wow, okay, you are absolutely right.

The Javascript code is just fine. It seems as though this only happens when I select one of the options in the second drop-down, which is autopopulated from MySQL through a call to a PHP script, and loaded using AJAX.

So I guess maybe I should go to an AJAX forum for help...

But just in case, here's what else I've been using:

$query="select distinct ".$type." from table ORDER BY ".$type." ASC";
$result=mysql_query($query);

?>
<select name="options">
<? while($row=mysql_fetch_assoc($result)) { ?>
<option value="<?php echo $row["".$type.""]; ?>"><?php echo $row["".$type.""]; ?></option>
<? } ?>
</select>

and the AJAX call (copied from somewhere, I don't know AJAX very well at all):

function getXMLHTTP() { //fuction to return the xml http object
var xmlhttp=false;
try{
xmlhttp=new XMLHttpRequest();
}
catch(e){
try{
xmlhttp= new ActiveXObject("Microsoft.XMLHTTP");
}
catch(e1){
try{
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch(e2){
xmlhttp=false;
}
}
}
return xmlhttp;
}

function getOpt(strURL) {
var req = getXMLHTTP();
if (req) {
req.onreadystatechange = function() {
if (req.readyState == 4) {
// only if "OK"
if (req.status == 200){
document.getElementById('optdiv').innerHTML=req.responseText;
}
else {
alert("There was a problem while using XMLHTTP:\n" + req.statusText);
}
}
}
req.open("GET", strURL, true);
req.send(null);
}
}

And I swear there is no other code at all in the page (for now).

Thank you again, Feherke, I appreciate your prompt and accurate replies.
 
Hi

rob said:
document.getElementById('optdiv').innerHTML=req.responseText;
This line does all the evil.

Your [tt]div[/tt] optdiv initially contains all [tt]form[/tt] elements : 3 [tt]input[/tt]s and 2 [tt]select[/tt]s. After the above quoted line is executed, the optdiv [tt]div[/tt] will contain only one [tt]form[/tt] element. So further visibility changing attempts will fail because the referred elements was destroyed.

Anyway, your AJAX is looks just as bad your toggleField() function looks. So again I suggest to rewrite it.

Personally I would write the JavaScript like this ( the getXMLHTTP() remains the same ) :
JavaScript:
[b]var[/b] control[teal]=[/teal][teal]{[/teal]
  [green][i]'year'[/i][/green][teal]:[/teal][green][i]'years'[/i][/green][teal],[/teal]
  [green][i]'wonlost'[/i][/green][teal]:[/teal][green][i]'winlost'[/i][/green][teal],[/teal]
  [green][i]'sales_rep'[/i][/green][teal]:[/teal][green][i]'sales_rep'[/i][/green][teal],[/teal]
  [green][i]'customer'[/i][/green][teal]:[/teal][green][i]'customer'[/i][/green][teal],[/teal]
  [green][i]'vin'[/i][/green][teal]:[/teal][green][i]'vinno'[/i][/green]
[teal]}[/teal]

[b]function[/b] [COLOR=darkgoldenrod]toggleField[/color][teal]([/teal]val[teal])[/teal]
[teal]{[/teal]
  [b]for[/b] [teal]([/teal][b]var[/b] one [b]in[/b] control[teal])[/teal]
    document[teal].[/teal][COLOR=darkgoldenrod]getElementById[/color][teal]([/teal]control[teal][[/teal]one[teal]]).[/teal]style[teal].[/teal]display[teal]=[/teal]val[teal]==[/teal]one[teal]?[/teal][green][i]'inline'[/i][/green][teal]:[/teal][green][i]'none'[/i][/green]

  [b]if[/b] [teal]([/teal]document[teal].[/teal][COLOR=darkgoldenrod]getElementById[/color][teal]([/teal]control[teal][[/teal]val[teal]]).[/teal]tagName[teal].[/teal][COLOR=darkgoldenrod]toLowerCase[/color][teal]()==[/teal][green][i]'select'[/i][/green][teal])[/teal]
    [COLOR=darkgoldenrod]getOpt[/color][teal]([/teal][green][i]'findcity.php?type='[/i][/green][teal]+[/teal]val[teal],[/teal]control[teal][[/teal]val[teal]])[/teal]
[teal]}[/teal]

[b]function[/b] [COLOR=darkgoldenrod]getOpt[/color][teal]([/teal]strURL[teal],[/teal]targetelem[teal])[/teal]
[teal]{[/teal]
  [b]var[/b] req[teal]=[/teal][COLOR=darkgoldenrod]getXMLHTTP[/color][teal]();[/teal]
  [b]if[/b] [teal](![/teal]req[teal])[/teal] [b]return[/b][teal];[/teal]

  req[teal].[/teal]onreadystatechange[teal]=[/teal][b]function[/b][teal]()[/teal] [teal]{[/teal]
    [b]if[/b] [teal]([/teal]req[teal].[/teal]readyState[teal]==[/teal][purple]4[/purple][teal])[/teal] [teal]{[/teal] [gray]// only if finished loading[/gray]
      [b]if[/b] [teal]([/teal]req[teal].[/teal]status[teal]==[/teal][purple]200[/purple][teal])[/teal] [teal]{[/teal] [gray]// only if "OK"[/gray]
        [b]var[/b] data[teal]=[/teal][COLOR=darkgoldenrod]eval[/color][teal]([/teal]req[teal].[/teal]responseText[teal])[/teal]
        [b]var[/b] elem[teal]=[/teal]document[teal].[/teal][COLOR=darkgoldenrod]getElementById[/color][teal]([/teal]targetelem[teal])[/teal]
        [b]while[/b] [teal]([/teal]elem[teal].[/teal]options[teal].[/teal]length[teal]>[/teal][purple]1[/purple][teal])[/teal] elem[teal].[/teal]options[teal][[/teal]elem[teal].[/teal]options[teal].[/teal]length[teal]-[/teal][purple]1[/purple][teal]]=[/teal][b]null[/b]
        [b]for[/b] [teal]([/teal][b]var[/b] i[teal]=[/teal][purple]0[/purple][teal],[/teal]l[teal]=[/teal]data[teal].[/teal]length[teal];[/teal]i[teal]<[/teal]l[teal];[/teal]i[teal]++)[/teal] elem[teal].[/teal]options[teal][[/teal]i[teal]+[/teal][purple]1[/purple][teal]]=[/teal][b]new[/b] [COLOR=darkgoldenrod]Option[/color][teal]([/teal]data[teal][[/teal]i[teal]])[/teal]
      [teal]}[/teal] [b]else[/b] [teal]{[/teal]
        [COLOR=darkgoldenrod]alert[/color][teal]([/teal][green][i]"There was a problem while using XMLHTTP:[/i][/green][lime][i]\n[/i][/lime][green][i]"[/i][/green][teal]+[/teal]req[teal].[/teal]statusText[teal]);[/teal]
      [teal]}[/teal]
    [teal]}[/teal]
  [teal]}[/teal]

  req[teal].[/teal][COLOR=darkgoldenrod]open[/color][teal]([/teal][green][i]"GET"[/i][/green][teal],[/teal]strURL[teal],[/teal][b]true[/b][teal]);[/teal]
  req[teal].[/teal][COLOR=darkgoldenrod]send[/color][teal]([/teal][b]null[/b][teal]);[/teal]
[teal]}[/teal]
For which the PHP code should look like this :
Code:
[gray]// ...[/gray]

[navy]$type[/navy][teal]=[/teal][navy]$_GET[/navy][teal][[/teal][green][i]'type'[/i][/green][teal]];[/teal]
[b]if[/b] [teal]([/teal][COLOR=darkgoldenrod]preg_match[/color][teal]([/teal][green][i]'/\\W/'[/i][/green][teal],[/teal][navy]$type[/navy][teal]))[/teal] [b]die[/b][teal]([/teal][green][i]'you can not crack me so easy'[/i][/green][teal]);[/teal]

[navy]$query[/navy][teal]=[/teal][green][i]"select distinct $type from table ORDER BY $type ASC"[/i][/green][teal];[/teal]
[navy]$result[/navy][teal]=[/teal][COLOR=darkgoldenrod]mysql_query[/color][teal]([/teal][navy]$query[/navy][teal]);[/teal]

[navy]$data[/navy][teal]=[/teal][b]array[/b][teal]();[/teal]
[b]while[/b] [teal]([/teal][navy]$row[/navy][teal]=[/teal][COLOR=darkgoldenrod]mysql_fetch_assoc[/color][teal]([/teal][navy]$result[/navy][teal]))[/teal] [teal]{[/teal]
  [COLOR=darkgoldenrod]array_push[/color][teal]([/teal][navy]$data[/navy][teal],[/teal][navy]$row[/navy][teal][[/teal][navy]$type[/navy][teal]]);[/teal]

[COLOR=darkgoldenrod]header[/color][teal]([/teal][green][i]'Content-type: text/javascript'[/i][/green][teal]);[/teal]

[b]echo[/b] [COLOR=darkgoldenrod]json_encode[/color][teal]([/teal][navy]$data[/navy][teal]);[/teal]
In the related HTML code only those ugly [tt]onmouseover[/tt] handlers should be removed :
HTML:
[b]<div[/b] [maroon]id[/maroon][teal]=[/teal][green][i]"optdiv"[/i][/green] [maroon]style[/maroon][teal]=[/teal][green][i]"display:inline;"[/i][/green][b]>[/b]
   [b]<input[/b] [maroon]type[/maroon][teal]=[/teal][green][i]"text"[/i][/green] [maroon]name[/maroon][teal]=[/teal][green][i]"sales_rep"[/i][/green] [maroon]id[/maroon][teal]=[/teal][green][i]"sales_rep"[/i][/green] [maroon]value[/maroon][teal]=[/teal][green][i]"Sales"[/i][/green] [maroon]style[/maroon][teal]=[/teal][green][i]"display: none;"[/i][/green][b]>[/b]

   [b]<input[/b] [maroon]type[/maroon][teal]=[/teal][green][i]"text"[/i][/green] [maroon]name[/maroon][teal]=[/teal][green][i]"customer"[/i][/green] [maroon]id[/maroon][teal]=[/teal][green][i]"customer"[/i][/green] [maroon]value[/maroon][teal]=[/teal][green][i]"Customer"[/i][/green] [maroon]style[/maroon][teal]=[/teal][green][i]"display: none;"[/i][/green][b]>[/b]

   [b]<select[/b] [maroon]name[/maroon][teal]=[/teal][green][i]"years"[/i][/green] [maroon]id[/maroon][teal]=[/teal][green][i]"years"[/i][/green] [maroon]style[/maroon][teal]=[/teal][green][i]"display: none;"[/i][/green][b]>[/b]
      [b]<option>[/b]Select Year[b]</option>[/b]
   [b]</select>[/b]

   [b]<input[/b] [maroon]type[/maroon][teal]=[/teal][green][i]"text"[/i][/green] [maroon]name[/maroon][teal]=[/teal][green][i]"vinno"[/i][/green] [maroon]id[/maroon][teal]=[/teal][green][i]"vinno"[/i][/green] [maroon]value[/maroon][teal]=[/teal][green][i]"Vin"[/i][/green] [maroon]style[/maroon][teal]=[/teal][green][i]"display: none;"[/i][/green][b]>[/b]

   [b]<select[/b] [maroon]name[/maroon][teal]=[/teal][green][i]"winlost"[/i][/green] [maroon]id[/maroon][teal]=[/teal][green][i]"winlost"[/i][/green] [maroon]style[/maroon][teal]=[/teal][green][i]"display: none;"[/i][/green][b]>[/b]
      [b]<option>[/b]Select Status[b]</option>[/b]
   [b]</select>[/b]
[b]</div>[/b]
Next time please post your code between [tt][ignore]
Code:
[/ignore][/tt] and [tt][ignore]
[/ignore][/tt] TGML tags.

Feherke.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top