Ajax listbox inconsistent

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • MelindaM
    New Member
    • Nov 2009
    • 6

    Ajax listbox inconsistent

    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:
    Code:
    function setPartType(form)
    {
    	var url="getPackage.php?";
    	url = url+appendParmsToUrl(form);
    	xmlhttpPartType=GetXmlHttpObject();
    if (xmlhttpPartType==null)
      {
      alert ("Browser does not support HTTP Request");
      return;
      }
    url=url+"sid="+Math.random()+"&";
    xmlhttpPartType.onreadystatechange=stateChangedPartType;
    xmlhttpPartType.open("GET",url,true);
    xmlhttpPartType.send(null);
    setPackage(form);
    }
    
    function stateChangedPartType()
    {
    if (xmlhttpPartType.readyState==4)
    {
    document.getElementById("packageSelect").innerHTML=xmlhttpPartType.responseText;
    }
    }
    getPackage.php:
    Code:
    <?php require_once('../Connections/admin.php'); ?>
    <?php require_once('../Connections/phtdeelib.php'); ?>
    <?php require_once('functions.php'); ?>
    <?php
    
    mysql_select_db($database_phtdeelib, $phtdeelib);
    $query = "SELECT DISTINCT Package FROM components WHERE ";
    $query = $query . addToQuery($_SERVER['QUERY_STRING'], "partType", "PartType");
    $query = $query . "Package IS NOT NULL ORDER BY Package ASC;";
    
    $PartTypes = mysql_query($query, $phtdeelib) or die(mysql_error());
    $row_PartTypes = mysql_fetch_assoc($PartTypes);
    $totalRows_PartTypes = mysql_num_rows($PartTypes);
    ?>
    
    <select multiple size=5 name="Package" style="width: 15em;" onchange="setPackage(this.form);">
    <option value=""></option>
    <?php
    do {  
    	echo "<option value=\"" . $row_PartTypes['Package'] . "\"";
    	if ($row_PartTypes['Package'] == $partType)
    		echo " selected ";
    	echo ">" . $row_PartTypes['Package'] . "</option>";
    } while ($row_PartTypes = mysql_fetch_assoc($PartTypes));
    ?>
    </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!
  • gits
    Recognized Expert Moderator Expert
    • May 2007
    • 5390

    #2
    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:
    Code:
    setPackage(form);
    from the:
    Code:
    stateChangedPartType();
    method.

    kind regards

    Comment

    • MelindaM
      New Member
      • Nov 2009
      • 6

      #3
      Thanks for the reply. The reason I didn't put the call to setPackage() in the stateChangedPar tType() 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 stateChangedPar tType() method doesn't solve the issue with some of the listboxes not loading initially either.

      Any other ideas? I'd really appreciate it.

      Comment

      • gits
        Recognized Expert Moderator Expert
        • May 2007
        • 5390

        #4
        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

        Comment

        • MelindaM
          New Member
          • Nov 2009
          • 6

          #5
          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 stateChangedPar tType() 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:

          Code:
          function displayChainedSearch()
          {
          	var url="chainedSearch.php?";
          	xmlhttpListSearch=GetXmlHttpObject();
          if (xmlhttpListSearch==null)
            {
            alert ("Browser does not support HTTP Request");
            return;
            }
          xmlhttpListSearch.onreadystatechange=stateChangedDisplayChainedSearch;
          xmlhttpListSearch.open("GET",url,true);
          xmlhttpListSearch.send(null);
          setPartType(null);
          }
          Note the call I currently have to setPartType() at the end.

          chainedSearch.p hp 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.
          Code:
          <?php require_once('../Connections/admin.php'); ?>
          <?php require_once('../Connections/phtdeelib.php'); ?>
          
          <font class="explistbold">Advanced Search - <a href="javascript:displayTextSearch()">Description/Notes Search</a></font>
          
          <form name="chainedForm" id="chainedForm">
          <table>
          <tr class="explistbold">
          <td>Part Type:</td>
          <td>Package:</td>
          <td>Vendor:</td>
          <td>Manufacturer:</td>
          </tr>
          
          <?php 
          mysql_select_db($database_admin, $admin);
          $query_PartTypes = "SELECT dropdowns.`option` FROM dropdowns WHERE dropdowns.`menuname` = \"PartType\" ORDER BY dropdowns.`option`;";
          $PartTypes = mysql_query($query_PartTypes, $admin) or die(mysql_error());
          $row_PartTypes = mysql_fetch_assoc($PartTypes);
          $totalRows_PartTypes = mysql_num_rows($PartTypes);
          ?>
          
          <tr>
          <td valign="top"><select multiple size=5 name="PartType" style="width: 15em;" onchange="setPartType(this.form)">
          <option value="" selected></option>
          <?php
          do {  
          ?>
          			<option value="<?php echo $row_PartTypes['option']?>"><?php echo $row_PartTypes['option']?></option>	
                  <?php
          } while ($row_PartTypes = mysql_fetch_assoc($PartTypes));
            $rows = mysql_num_rows($PartTypes);
            if($rows > 0) {
                mysql_data_seek($PartTypes, 0);
          	  $row_PartTypes = mysql_fetch_assoc($PartTypes);
            }
          ?>
          </select>
          </td>
          
          <td><div id="packageSelect"></div></td>
          <td><div id="vendorSelect"></div></td>
          <td><div id="manufacturerSelect"></div></td>
          </tr>
          </table>
          <input type="hidden" name="SearchType" value="Chained">
          <div id="totalResults"></div>
          <input type='button' onclick="displayList(this.form)" value='Display Parts' />
          </form>
          
          <!--<script type="text/javascript">-->
          <!--setPartType(null);-->
          <!--</script>-->
          setPartType() and it's callback method look like this:
          Code:
          function setPartType(form)
          {
          	if(form)
          	{
          		if(form.Package)
          		{
          			form.Package.selectedIndex = -1;
          		}
          		if(form.Vendor)
          		{
          			form.Vendor.selectedIndex = -1;
          		}
          		if(form.Manufacturer)
          		{
          			form.Manufacturer.selectedIndex = -1;
          		}
          	}
          	var url="getPackage.php?";
          	url = url+appendParmsToUrl(form);
          	xmlhttpPartType=GetXmlHttpObject();
          if (xmlhttpPartType==null)
            {
            alert ("Browser does not support HTTP Request");
            return;
            }
          url=url+"sid="+Math.random()+"&";
          xmlhttpPartType.onreadystatechange=stateChangedPartType;
          xmlhttpPartType.open("GET",url,true);
          xmlhttpPartType.send(null);
          setPackage(form);
          getTotalResults(form);
          }
          
          function stateChangedPartType()
          {
          if (xmlhttpPartType.readyState==4)
          {
          document.getElementById("packageSelect").innerHTML=xmlhttpPartType.responseText;
          }
          }
          And lastly this is what the php looks like for getPackage.php (and it's the same for all the other listboxes):
          Code:
          <?php require_once('../Connections/admin.php'); ?>
          <?php require_once('../Connections/phtdeelib.php'); ?>
          <?php require_once('functions.php'); ?>
          <?php
          
          mysql_select_db($database_phtdeelib, $phtdeelib);
          $fieldsToUse = array("partType");
          echo $query;
          $query = buildQuery($_SERVER['QUERY_STRING'], "Package", $fieldsToUse, true, true, "Package");
          $PartTypes = mysql_query($query, $phtdeelib) or die(mysql_error());
          $row_PartTypes = mysql_fetch_assoc($PartTypes);
          ?>
          
          <select multiple size=5 name="Package" style="width: 15em;" onchange="setPackage(this.form);">
          <option value=""></option>
          <?php
          do {  
          	echo "<option value=\"" . $row_PartTypes['Package'] . "\">" . $row_PartTypes['Package'] . "</option>";
          } while ($row_PartTypes = mysql_fetch_assoc($PartTypes));
          ?>
          </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!

          Comment

          • gits
            Recognized Expert Moderator Expert
            • May 2007
            • 5390

            #6
            just retrieve the form in the list's form code:
            Code:
            var myForm = document.getElementById('your_forms_id');
            and use it instead of passing it to the function

            kind regards

            Comment

            Working...