views:

788

answers:

2

Hello,

I had a realtivley simple ajax application, which I have broken up to be more modular. The code is at the link below, and what I have mainly done is add the GetRecordSet function and allowed fetchcompelte to take a variable for which layer to put data in. It should work fine in thery. When I put alert()s in, the code seems to execute, except for inside either of the if clauses in fetchcomplete.

http://www.nomorepasting.com/getpaste.php?pasteid=22558

This is the code for get_records.php, which again seems like it should be fine

http://www.nomorepasting.com/getpaste.php?pasteid=22559

and this is the original index php file

http://www.nomorepasting.com/getpaste.php?pasteid=22560

+1  A: 

I would suggest that you use prototypejs from http://www.prototypejs.org, which would abstract all the status checks in your code and make it simpler and get rid of the mess.

If for some reason you prefer to use your own code then avoid using string values for the readyState property of the XMLHttpRequestObject. Use the following table instead

 State Description 
   0   The request is not initialized 
   1   The request has been set up 
   2   The request has been sent 
   3   The request is in process 
   4   The request is complete

and check.

Shyam
+1  A: 

Firsly I would agree with Shyam and also install Firebug for Firefox; this will be a huge help for javascript debugging.

anyway, the line

xmlHttp.onreadystatechange = FetchComplete(layername);

will assign the result of FetchComplete(layername) to xmlHttp.onreadystatechange, which isn't what you want. It would need to be

xmlHttp.onreadystatechange = FetchComplete;

But then you have the problem of passing layername.

If you define the onreadystatechange as an anonymous inner function you can easily use variables defined outside it, so you could do something like this:

function GetAuctionData(pk) {

    var xmlHttp=GetXmlHttpObject();
    var layer = "Layer2";

    if(xmlHttp==null) {
        alert("Your browser is not supported?");
    }

    var url="get_auction.php?";
    url=url+"cmd=GetAuctionData&pk="+pk;
    url=url+"&sid="+Math.random();

    xmlHttp.onreadystatechange = function() {
        if(xmlHttp.readyState==4 || xmlHttp.readyState=="complete") {
            document.getElementById(layer).innerHTML=xmlHttp.responseText
        } else if (xmlHttp.readyState==1 || xmlHttp.readyState=="loading") {
            document.getElementById(layer).innerHTML="loading"
        }
    };

    xmlHttp.open("GET",url,true)
    xmlHttp.send(null)
}

layer is defined as a local variable in GetAuctionData() but is accessible in the anonymous function, because you are creating a Closure. Note that I haven't tested the above function, but it should work in principle.

Tom Haigh
Hi Tom, that works fine, I am just wondering if there is a more efficient way than declaring the same inner function for each method? Perhaps passing the url and such as variables is a better approach?
Joshxtothe4
Surely the inner function will be different for each method? Also if you used something like prototype you could do the whole lot on one line, e.g. new Ajax.Updater(layer, url);
Tom Haigh
I have GetAuctionData and GetRecordSet which are basically the same, except for the php file they call and parameters passed. they both have the same inner function at present. I know about frameworks but enjoy ironing out the kins at the moment.
Joshxtothe4
then you could make a function like update(layer, url) and use that function twice.
Tom Haigh