0

I have a function that uses AJAX to get a list of items from a php script and can pass a filter. The user can set the filter by selecting from a drop down box on the page.

The problem i'm having is I am calling the function during page load to fill the form with default data and the function is just quitting silently when I try to read the filter text from the drop down box. It works fine after page load, but not during. However the function works fine if I put an alert("test") before it tries to read from the drop down so i'm assuming the drop down just hasnt finished loading properly when the function is called. How can I test to see if its safe to read so I can provide my own default value if it isnt safe?

Code Snippit:

var ProdCat = document.getElementById("prod_cat2");             
var Filter = "All Products";

Filter = ProdCat.options[ProdCat.selectedIndex].text;

alert("test");

xr2.open("GET","hs_shop.php?ajaxreq&r=prodlist&p1=" + Filter, true);
xr2.send();

So the above code is in a function called onLoad and the alert doesnt trigger at all. But if I comment out the Filter = ProdCat.(etc) line then the alert DOES trigger. Alert ALWAYS triggers even with that line AFTER page load. Looking for a solution to keep the one function both during load and after, thanks!

David Burford
  • 701
  • 2
  • 8
  • 16
  • 1
    AJAX is asynchronous. Anything that depends on what it returns must be done in the callback function, not in the mainline code. – Barmar Jul 30 '13 at 15:12
  • 1
    I can hardly believe it fails silently. Have a look at your error console! – Bergi Jul 30 '13 at 15:13
  • And Javascript is single-threaded. So the callback function won't run until the browser finishes executing the startup code and waits for events. – Barmar Jul 30 '13 at 15:14
  • Barmar: Its not the depending on the return bit thats broken, its reading the filter value to even call the request. Bergi: quite right! sorry i'm deving js and php at the same time and php quits and displays an error when I mess up and sometimes I forget JS doesnt! The error is: ProdCat.options[ProdCat.selectedIndex] is undefined – David Burford Jul 30 '13 at 15:21
  • possible duplicate of [$(document).ready equivalent without jQuery](http://stackoverflow.com/questions/799981/document-ready-equivalent-without-jquery) – Barmar Jul 30 '13 at 15:25
  • are you suggesting the only solution is to use that massive function to see if the entire document has finished loading rather than testing a single component for usability? – David Burford Jul 30 '13 at 15:28
  • thankfully that was not the case, answer accepted, one simple if. Question wasn't a duplicate, did not wish to know if document had loaded but if specific element was :) – David Burford Jul 31 '13 at 09:39

2 Answers2

2

It sounds like the script is above the markup for the ProdCat select box in your HTML file. If so, the simplest thing is to simply move the script tag containing it down so that it's underneath the markup for the select box. The select box won't exist until its markup is parsed, but it will exists immediately once it is.

How can I test to see if its safe to read so I can provide my own default value if it isnt safe?

If you don't want to relocate the script (or you run into this in other situations where that doesn't make sense), you can test whether you got the element:

if (ProdCat) {
    Filter = ProdCat.options[ProdCat.selectedIndex].text;
}

If you like, you can even have it retry:

var ProdCat;
var Filter = "All Products";

function startAjax() {
    ProdCat = document.getElementById("prod_cat2");
    if (ProdCat) {
        Filter = ProdCat.options[ProdCat.selectedIndex].text;
        xr2.open("GET","hs_shop.php?ajaxreq&r=prodlist&p1=" + Filter, true);
        xr2.send();
    else {
        setTimeout(startAjax, 100); // 1/10th of a second later, try again
    }
}

startAjax();

Update: In a comment, you said:

The error is: ProdCat.options[ProdCat.selectedIndex] is undefined

Okay, so you have the element, but there's nothing selected (yet). So the test would be:

if (ProdCat &&                              // We have the select
    ProdCat.selectedIndex >= 0 &&           // and it has a selected value
    ProdCat.options[ProdCat.selectedIndex]  // (Paranoia) and that option exists
    ) {
    Filter = ProdCat.options[ProdCat.selectedIndex].text;
}
T.J. Crowder
  • 879,024
  • 165
  • 1,615
  • 1,639
1

Check if the element could be found. If not, the default filter 'All Products' is used.

var ProdCat = document.getElementById("prod_cat2");             
var Filter = "All Products";

if (ProdCat)
{
  Filter = ProdCat.options[ProdCat.selectedIndex].text;
}

alert("test");

xr2.open("GET","hs_shop.php?ajaxreq&r=prodlist&p1=" + Filter, true);
xr2.send();
GolezTrol
  • 109,399
  • 12
  • 170
  • 196