Question

First of all, any suggestions on rewriting my title?

Issue: I have an AJAX updatable div, when my error checking alert calls are in, everything works perfect. But when I remove a specific one, the DIV never gets updated. I know it sounds confusing, but code is as follows, and then I will explain further.

AJAX SCRIPT

var xmlhttp
    /*@cc_on @*/
    /*@if (@_jscript_version >= 5)
      try {
      xmlhttp=new ActiveXObject("Msxml2.XMLHTTP")
     } catch (e) {
      try {
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP")
      } catch (E) {
       xmlhttp=false
      }
     }
    @else
     xmlhttp=false
    @end @*/
    if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
     try {
      xmlhttp = new XMLHttpRequest();
     } catch (e) {
      xmlhttp=false
     }
    }
    function myXMLHttpRequest() {
      var xmlhttplocal;
      try {
        xmlhttplocal= new ActiveXObject("Msxml2.XMLHTTP")
     } catch (e) {
      try {
        xmlhttplocal= new ActiveXObject("Microsoft.XMLHTTP")
      } catch (E) {
        xmlhttplocal=false;
      }
     }

    if (!xmlhttplocal && typeof XMLHttpRequest!='undefined') {
     try {
      var xmlhttplocal = new XMLHttpRequest();
     } catch (e) {
      var xmlhttplocal=false;
      alert('couldn\'t create xmlhttp object');
     }
    }
    return(xmlhttplocal);
}

function sndReq(page,key,includesDir,changeDiv,parameterString) {
    var divToChange = document.getElementById(changeDiv); // the Div that the data will be put into

    // Place loading image in container DIV
    divToChange.innerHTML = '<div class="loading">Loading</div>';

    if (includesDir == 1){
        //Find Current Working Directory.  Use to find path to call other files from
        var myloc = window.location.href;
        var locarray = myloc.split("/");
        delete locarray[(locarray.length-1)];
        var arraytext = locarray.join("/");

        xmlhttp.open("POST","AJAXCaller.php",true);
        xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
        xmlhttp.send(parameterString);

    } else {

    }

    xmlhttp.onreadystatechange = handleResponse(changeDiv);
    xmlhttp.send(null); 
}

function handleResponse(changeDiv) {
/* ======== If I remove the following line script halts ================*/
/* ======== If line stays here, script executes perfectly ==============*/
    alert('to changetext 1\n'+xmlhttp.responseText);
/* =========End of line removal issue =================================*/       
  if(xmlhttp.readyState == 4){

        if (xmlhttp.status == 200){

        var response = xmlhttp.responseText;

        var update = new Array();

            if(response.indexOf('|') != -1) {
                update = response.split('|');
                changeText(update[0], update[1]);
            } else {
                changeText(changeDiv, response);
            }

        } //End IF xmlhttp.status == 200


    }
}

function changeText( div2show, text ) {
    // Detect Browser
    var IE = (document.all) ? 1 : 0;
    var DOM = 0; 
    if (parseInt(navigator.appVersion) >=5) {DOM=1};

    // Grab the content from the requested "div" and show it in the "container"
    if (DOM) {
        var viewer = document.getElementById(div2show);
        viewer.innerHTML = text;
    }  else if(IE) {
        document.all[div2show].innerHTML = text;
    }
}

When I check my firefox error console, this error ONLY appears when I remove that alert as defined in the code:

Timestamp: 5/30/2012 5:07:55 PM
Error: b.data is undefined
Source File: http://cdn.sstatic.net/js/wmd.js?v=cfd2b283af83
Line: 92

I am an advanced PHP/mySQL developer, but have been trying hard to grasp AJAX/Javascript. Doing tutorials like mad. So please be descriptive in comments/answers so I can use them as a reference for learning...

Why would displaying an alert box alter code execution (for the better!) in any way?

NEW ERRORS - Google Chrome&Firefox Console (sigh...)

Uncaught Error: INVALID_STATE_ERR: DOM Exception 11
sndReqAJAX.js:89
element.onclick

Line 89 is the following (verified by Google Chrome Console)

xmlhttp.send(null);

Everything I find on the web refers to extremely complex issue regarding DOM objects not existing... This wouldn't apply here, would it?

Was it helpful?

Solution

First, the problem. This is the line:

xmlhttp.onreadystatechange = handleResponse(changeDiv);

The reason this is wrong is that xmlhttp.onreadystatechange should be a function - you need to assign a function to the property, what you are doing is calling the function and assigning the return value to the property. This is not in itself a problem, as long as your function returns a function. Which it doesn't.

If you're used to working with PHP (especially if your used to working with PHP <5.3) you may not be used to this concept. Javascript has support for closures in a way that anyone who doesn't use them much will find confusing.

What the line needs to look like is this:

xmlhttp.onreadystatechange = handleResponse;

By appending (changeDiv) you are calling the function, whereas what you need to do is simply pass it, like you would any other value.

Now, where it gets complicated is that you want to pass an argument that is local to the scope of the calling function. There are a number of ways to handle this, but a cursory look at your code tells me that handleResponse() is not used anywhere else, so it would be better to define this as a closure and not litter the global scope with a named event handler. This also overcomes the variable scoping problem:

xmlhttp.onreadystatechange = function() {
  if (xmlhttp.readyState == 4) {
    if (xmlhttp.status == 200) {
      var response = xmlhttp.responseText;
      var update = []; // "new Array()" is baaaad
      if (response.indexOf('|') != -1) {
        update = response.split('|');
        changeText(update[0], update[1]);
      } else {
        changeText(changeDiv, response);
      }
    } //End IF xmlhttp.status == 200
  }
};

Replace the aforementioned offending line with that block of code, and remove the handleResponse() function definition, and that should solve the immediate problem. Now, as to why the alert() "fixes" your original code - this is a little hard to explain, but I shall have a go... give me a minute to inspect the code properly


Attempt at a full and comprehensible explanation abandoned. If anyone wants one, post a comment and I'll have another go at it when I've had some sleep...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top