By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,566 Members | 1,659 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,566 IT Pros & Developers. It's quick & easy.

Ajax listbox inconsistent

P: 6
Hi guys,

I created a form for searching through a parts library that I have stored in a MySQL database. I'm not new to web programming but this is my first time using PHP and Ajax. I have four listboxes that are chained together. In other words, if you click on the first one it filters out what's available in the next three. If you click on the 3rd one, it filters out the available options in the 4th one, etc. I do this by having php pages for each listbox and use ajax calls whenever the selected item changes in a listbox.

Everything was working beautifully and then I had somebody else try it (using the same version if Firefox) and they found that sometimes not all four listboxes load. If you keep hitting refresh you'll always get the first one, sometimes you'll get all four, and any one of the last three are hit and miss. I found out that if Firebug is running that the issue never happens but if you disable Firebug I can re-create the issue. This is with the initial loading of the page.

I have no idea how to debug this since it doesn't happen when Firebug is running. I use a different XMLHttpRequest for each call, so they shouldn't be conflicting with each other.

I'll include one example but the code for all the listboxes is the same.

javascript:
Expand|Select|Wrap|Line Numbers
  1. function setPartType(form)
  2. {
  3.     var url="getPackage.php?";
  4.     url = url+appendParmsToUrl(form);
  5.     xmlhttpPartType=GetXmlHttpObject();
  6. if (xmlhttpPartType==null)
  7.   {
  8.   alert ("Browser does not support HTTP Request");
  9.   return;
  10.   }
  11. url=url+"sid="+Math.random()+"&";
  12. xmlhttpPartType.onreadystatechange=stateChangedPartType;
  13. xmlhttpPartType.open("GET",url,true);
  14. xmlhttpPartType.send(null);
  15. setPackage(form);
  16. }
  17.  
  18. function stateChangedPartType()
  19. {
  20. if (xmlhttpPartType.readyState==4)
  21. {
  22. document.getElementById("packageSelect").innerHTML=xmlhttpPartType.responseText;
  23. }
  24. }
getPackage.php:
Expand|Select|Wrap|Line Numbers
  1. <?php require_once('../Connections/admin.php'); ?>
  2. <?php require_once('../Connections/phtdeelib.php'); ?>
  3. <?php require_once('functions.php'); ?>
  4. <?php
  5.  
  6. mysql_select_db($database_phtdeelib, $phtdeelib);
  7. $query = "SELECT DISTINCT Package FROM components WHERE ";
  8. $query = $query . addToQuery($_SERVER['QUERY_STRING'], "partType", "PartType");
  9. $query = $query . "Package IS NOT NULL ORDER BY Package ASC;";
  10.  
  11. $PartTypes = mysql_query($query, $phtdeelib) or die(mysql_error());
  12. $row_PartTypes = mysql_fetch_assoc($PartTypes);
  13. $totalRows_PartTypes = mysql_num_rows($PartTypes);
  14. ?>
  15.  
  16. <select multiple size=5 name="Package" style="width: 15em;" onchange="setPackage(this.form);">
  17. <option value=""></option>
  18. <?php
  19. do {  
  20.     echo "<option value=\"" . $row_PartTypes['Package'] . "\"";
  21.     if ($row_PartTypes['Package'] == $partType)
  22.         echo " selected ";
  23.     echo ">" . $row_PartTypes['Package'] . "</option>";
  24. } while ($row_PartTypes = mysql_fetch_assoc($PartTypes));
  25. ?>
  26. </select>
Also, if you select an item in the first listbox any missing listboxes will then appear. So once you make the initial selection everything works beautifully. The only issue is that some of them don't load initially.

Anyone have any idea what could be going on? Any ideas on how to debug the problem would be appreciated as well.

Thanks guys!
Nov 23 '09 #1
Share this Question
Share on Google+
5 Replies


gits
Expert Mod 5K+
P: 5,390
as far as i could see it after a quicklook ... you should start the chained-loading from the callbacks where the list on which the next one seems to rely on ... is loaded already ... so start:
Expand|Select|Wrap|Line Numbers
  1. setPackage(form);
from the:
Expand|Select|Wrap|Line Numbers
  1. stateChangedPartType();
method.

kind regards
Nov 25 '09 #2

P: 6
Thanks for the reply. The reason I didn't put the call to setPackage() in the stateChangedPartType() method was because I wanted to call it while I still had a reference to the form variable (which is passed into the setPartType() method.

Changing the code to be in the stateChangedPartType() method doesn't solve the issue with some of the listboxes not loading initially either.

Any other ideas? I'd really appreciate it.
Nov 25 '09 #3

gits
Expert Mod 5K+
P: 5,390
in that case you need to show more of the code. in case the lists are really chained then there needs to be a chain that needs to be taken into account when starting requests. so when one loading of a list depends on the results of the previous the request cannot load when the first request is not ready. so it doesn't matter to have any references ready at one point ... the loading chain is essential to get it to work. so to give more explicit hints it would be helpful to see the code (at least - how the dependencies should work for two lists for example) ... otherwise it would be more guesswork ...

or is the only issue the form-reference then, when moving the calls as i suggested before?

regards
Nov 25 '09 #4

P: 6
Hi again, I hope you all had a good Thanksgiving (for those of you in the US)!

I think I tried adding a call from stateChangedPartType() to set the next one but I didn't pass along the form (because I don't know how to from there) and it didn't solve the problem of the listboxes not loading initially. I can try it again. If you have a solution for how to be able to pass the form along, please let me know.

Here's where I'm at currently. I have a JS function for displaying the chained search form. There are multiple search forms I switch between using AJAX. The function looks like this:

Expand|Select|Wrap|Line Numbers
  1. function displayChainedSearch()
  2. {
  3.     var url="chainedSearch.php?";
  4.     xmlhttpListSearch=GetXmlHttpObject();
  5. if (xmlhttpListSearch==null)
  6.   {
  7.   alert ("Browser does not support HTTP Request");
  8.   return;
  9.   }
  10. xmlhttpListSearch.onreadystatechange=stateChangedDisplayChainedSearch;
  11. xmlhttpListSearch.open("GET",url,true);
  12. xmlhttpListSearch.send(null);
  13. setPartType(null);
  14. }
Note the call I currently have to setPartType() at the end.

chainedSearch.php just loads the first listbox. I originally tried calling the JS function from the php page to load the next listbox but it doesn't seem to make a difference.
Expand|Select|Wrap|Line Numbers
  1. <?php require_once('../Connections/admin.php'); ?>
  2. <?php require_once('../Connections/phtdeelib.php'); ?>
  3.  
  4. <font class="explistbold">Advanced Search - <a href="javascript:displayTextSearch()">Description/Notes Search</a></font>
  5.  
  6. <form name="chainedForm" id="chainedForm">
  7. <table>
  8. <tr class="explistbold">
  9. <td>Part Type:</td>
  10. <td>Package:</td>
  11. <td>Vendor:</td>
  12. <td>Manufacturer:</td>
  13. </tr>
  14.  
  15. <?php 
  16. mysql_select_db($database_admin, $admin);
  17. $query_PartTypes = "SELECT dropdowns.`option` FROM dropdowns WHERE dropdowns.`menuname` = \"PartType\" ORDER BY dropdowns.`option`;";
  18. $PartTypes = mysql_query($query_PartTypes, $admin) or die(mysql_error());
  19. $row_PartTypes = mysql_fetch_assoc($PartTypes);
  20. $totalRows_PartTypes = mysql_num_rows($PartTypes);
  21. ?>
  22.  
  23. <tr>
  24. <td valign="top"><select multiple size=5 name="PartType" style="width: 15em;" onchange="setPartType(this.form)">
  25. <option value="" selected></option>
  26. <?php
  27. do {  
  28. ?>
  29.             <option value="<?php echo $row_PartTypes['option']?>"><?php echo $row_PartTypes['option']?></option>    
  30.         <?php
  31. } while ($row_PartTypes = mysql_fetch_assoc($PartTypes));
  32.   $rows = mysql_num_rows($PartTypes);
  33.   if($rows > 0) {
  34.       mysql_data_seek($PartTypes, 0);
  35.       $row_PartTypes = mysql_fetch_assoc($PartTypes);
  36.   }
  37. ?>
  38. </select>
  39. </td>
  40.  
  41. <td><div id="packageSelect"></div></td>
  42. <td><div id="vendorSelect"></div></td>
  43. <td><div id="manufacturerSelect"></div></td>
  44. </tr>
  45. </table>
  46. <input type="hidden" name="SearchType" value="Chained">
  47. <div id="totalResults"></div>
  48. <input type='button' onclick="displayList(this.form)" value='Display Parts' />
  49. </form>
  50.  
  51. <!--<script type="text/javascript">-->
  52. <!--setPartType(null);-->
  53. <!--</script>-->
setPartType() and it's callback method look like this:
Expand|Select|Wrap|Line Numbers
  1. function setPartType(form)
  2. {
  3.     if(form)
  4.     {
  5.         if(form.Package)
  6.         {
  7.             form.Package.selectedIndex = -1;
  8.         }
  9.         if(form.Vendor)
  10.         {
  11.             form.Vendor.selectedIndex = -1;
  12.         }
  13.         if(form.Manufacturer)
  14.         {
  15.             form.Manufacturer.selectedIndex = -1;
  16.         }
  17.     }
  18.     var url="getPackage.php?";
  19.     url = url+appendParmsToUrl(form);
  20.     xmlhttpPartType=GetXmlHttpObject();
  21. if (xmlhttpPartType==null)
  22.   {
  23.   alert ("Browser does not support HTTP Request");
  24.   return;
  25.   }
  26. url=url+"sid="+Math.random()+"&";
  27. xmlhttpPartType.onreadystatechange=stateChangedPartType;
  28. xmlhttpPartType.open("GET",url,true);
  29. xmlhttpPartType.send(null);
  30. setPackage(form);
  31. getTotalResults(form);
  32. }
  33.  
  34. function stateChangedPartType()
  35. {
  36. if (xmlhttpPartType.readyState==4)
  37. {
  38. document.getElementById("packageSelect").innerHTML=xmlhttpPartType.responseText;
  39. }
  40. }
And lastly this is what the php looks like for getPackage.php (and it's the same for all the other listboxes):
Expand|Select|Wrap|Line Numbers
  1. <?php require_once('../Connections/admin.php'); ?>
  2. <?php require_once('../Connections/phtdeelib.php'); ?>
  3. <?php require_once('functions.php'); ?>
  4. <?php
  5.  
  6. mysql_select_db($database_phtdeelib, $phtdeelib);
  7. $fieldsToUse = array("partType");
  8. echo $query;
  9. $query = buildQuery($_SERVER['QUERY_STRING'], "Package", $fieldsToUse, true, true, "Package");
  10. $PartTypes = mysql_query($query, $phtdeelib) or die(mysql_error());
  11. $row_PartTypes = mysql_fetch_assoc($PartTypes);
  12. ?>
  13.  
  14. <select multiple size=5 name="Package" style="width: 15em;" onchange="setPackage(this.form);">
  15. <option value=""></option>
  16. <?php
  17. do {  
  18.     echo "<option value=\"" . $row_PartTypes['Package'] . "\">" . $row_PartTypes['Package'] . "</option>";
  19. } while ($row_PartTypes = mysql_fetch_assoc($PartTypes));
  20. ?>
  21. </select>

The first listbox always loads. The other 3 are completely random. Sometimes I get 1, sometimes I get 3, sometimes none. Unless Firebug is on, then everything works just fine.

What am I missing?

And let me know what other code would be useful to see.

Once again, I'd greatly appreciate feedback!
Nov 30 '09 #5

gits
Expert Mod 5K+
P: 5,390
just retrieve the form in the list's form code:
Expand|Select|Wrap|Line Numbers
  1. var myForm = document.getElementById('your_forms_id');
and use it instead of passing it to the function

kind regards
Dec 3 '09 #6

Post your reply

Sign in to post your reply or Sign up for a free account.