Javascript Functions Confusing AJAX Responses from CGI Request/Response - javascript

I have 3 Javascript functions called from the body onload in the HTML page.
Each Javascript function is contained in it's own Javascript file. Each Javascript file corresponds to another CGI script on the server.
The bodyonload.js looks like:
function bodyOnload() {
getElementsA();
getElementsB();
getElementsC();
}
Each getElements function simply calls a CGI script to get the contents for 3 different selectboxes.
The problem is that as all 3 functions are called asynchronously the select boxes are getting the wrong results. It's almost like the 3 functions are stepping on each other and putting the CGI responses in the wrong selectbox. I know the CGI responses are correct. This works fine if I serially call each function from the others. Like calling the 2nd function from the first and the 3rd function from the second. The asynchronous nature of them running at the same time seems to cause the problem.
This is the general code for each javascript file that contains the getElements functions.
function getElementsA() {
strURL = "http://test.com/scriptA.cgi";
var xmlHttpReq = false;
var self = this;
// Mozilla/Safari
if (window.XMLHttpRequest) {
self.xmlHttpReq = new XMLHttpRequest();
}
// IE
else if (window.ActiveXObject) {
self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
}
self.xmlHttpReq.open('POST', strURL, true);
self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
self.xmlHttpReq.onreadystatechange = function() {
if (self.xmlHttpReq.readyState == 4) {
fillselectboxA(self.xmlHttpReq.responseText);
}
}
self.xmlHttpReq.send();
}
function fillselectboxA(str)
{
document.getElementById("selectBoxA").length=0;
var results = new Array();
results = str.split(/\n/);
var size = results.length;
var select = document.getElementById("selectBoxA");
for (x=0;x<size;x++)
{
var element = results[x];
select.options.add(new Option(element, x))
}
}
-------------------
function getElementsB() {
strURL = "http://test.com/scriptB.cgi";
var xmlHttpReq = false;
var self = this;
// Mozilla/Safari
if (window.XMLHttpRequest) {
self.xmlHttpReq = new XMLHttpRequest();
}
// IE
else if (window.ActiveXObject) {
self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
}
self.xmlHttpReq.open('POST', strURL, true);
self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form- urlencoded');
self.xmlHttpReq.onreadystatechange = function() {
if (self.xmlHttpReq.readyState == 4) {
fillselectboxB(self.xmlHttpReq.responseText);
}
}
self.xmlHttpReq.send();
}
function fillselectboxB(str)
{
document.getElementById("selectBoxB").length=0;
var results = new Array();
results = str.split(/\n/);
var size = results.length;
var select = document.getElementById("selectBoxB");
for (x=0;x<size;x++)
{
var element = results[x];
select.options.add(new Option(element, x))
}
}
------------------------
function getElementsC() {
strURL = "http://test.com/scriptC.cgi";
var xmlHttpReq = false;
var self = this;
// Mozilla/Safari
if (window.XMLHttpRequest) {
self.xmlHttpReq = new XMLHttpRequest();
}
// IE
else if (window.ActiveXObject) {
self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
}
self.xmlHttpReq.open('POST', strURL, true);
self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
self.xmlHttpReq.onreadystatechange = function() {
if (self.xmlHttpReq.readyState == 4) {
fillselectboxC(self.xmlHttpReq.responseText);
}
}
self.xmlHttpReq.send();
}
function fillselectboxC(str)
{
document.getElementById("selectBoxC").length=0;
var results = new Array();
results = str.split(/\n/);
var size = results.length;
var select = document.getElementById("selectBoxC");
for (x=0;x<size;x++)
{
var element = results[x];
select.options.add(new Option(element, x))
}
}

It's almost like the 3 functions are stepping on each other
That's exactly what's happening, you're overwriting the onreadystatechange handler set on getElementsA when you call getElementsB, and then again when you call getElementsC. That's because this and self are the global object in all three functions (assuming they're all similar to getElementsA).
You can circumvent that by changing your function calls to object instantiation:
function bodyOnload() {
new getElementsA();
new getElementsB();
new getElementsC();
}

Related

HighCharts Graphs don't load half the time

I am displaying about 10 graphs on a webpage using highcharts. The problem I have having is that the graphs only load a portion of the time, usually around 50%. I am not sure if this is relevant, but the first graph, made using GDPC1.csv, loads every time.
Here is the code I am using to create all the graphs:
var xmlhttp = new XMLHttpRequest();
var unratexml = new XMLHttpRequest();
var cpixml = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
var d = csvToArray(xmlhttp.responseText);
var c = csvToArray(unratexml.responseText);
var x = csvToArray(cpixml.responseText);
createGDPChart(d);
createUNRATEChart(c);
createCPIChart(x);
}
}
xmlhttp.open("GET","GDPC1.csv",true);
xmlhttp.send();
unratexml.open("GET","UNRATE.csv",true);
unratexml.send();
cpixml.open("GET","test.csv",true);
cpixml.send();
The only thing I can think of is that it has something to do with my if statement, maybe it comes up false most of the time, but I don't know enough about javascript to know what to change. Thanks in advance.
Every XMLHttpRequest instance is an independent request. You have to define the onreadystatechange for every request. Something like this:
var xmlhttp = new XMLHttpRequest();
var unratexml = new XMLHttpRequest();
var cpixml = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
var d = csvToArray(xmlhttp.responseText);
createGDPChart(d);
}
}
unratexml.onreadystatechange = function() {
if (unratexml.readyState==4 && unratexml.status==200) {
var c = csvToArray(unratexml.responseText);
createUNRATEChart(c);
}
}
cpixml.onreadystatechange = function() {
if (cpixml.readyState==4 && cpixml.status==200) {
var x = csvToArray(cpixml.responseText);
createCPIChart(x);
}
}
xmlhttp.open("GET","GDPC1.csv",true);
xmlhttp.send();
unratexml.open("GET","UNRATE.csv",true);
unratexml.send();
cpixml.open("GET","test.csv",true);
cpixml.send();

XSLT is working only Firefox

Im new to XSLT. I am getting a XML file from return value of ECHO from PHP.
Then I try to transform to XSL but it only works in Firefox.
When I run the Javascript debugger from Chrome it says
:
Uncaught TypeError: undefined is not a function maintenance.js:30
getData
[Added: the OP eventually noted that line 30 of maintenance.js reads:
function generateReport() {
xHRObject.open("GET", "getXML.php", rue);
xHRObject.onreadystatechange = getData; //this is where i get debug error in chrome
xHRObject.send(null);
}
I have broken this into multiple lines for legibility.]
But when I run firebug with same code in Firefox no error and can get the result I want.
var xhr = false;
if (window.XMLHttpRequest)
{
xhr = new XMLHttpRequest();
}
else if (window.ActiveXObject)
{
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
function getData()
{
if ((xhr.readyState == 4) &&(xhr.status == 200))
{
if (window.ActiveXObject)
{
var xml = xhr.responseXML;
var xsl = new ActiveXObject("Microsoft.XMLDOM");
xsl.async = false; xsl.load("abc.xsl");
var transform = xml.transformNode(xsl);
var frame = document.getElementById("frame");
frame.innerHTML = transform;
}
else
{
var xsltProcessor = new XSLTProcessor();
xslStylesheet = document.implementation.createDocument("", "doc", null);
xslStylesheet.async = false;
xslStylesheet.load("abc.xsl");
xsltProcessor.importStylesheet(xslStylesheet);
xmlDoc = xhr.responseXML;
var fragment = xsltProcessor.transformToFragment(xmlDoc, document);
document.getElementById("frame").innerHTML = new XMLSerializer().serializeToString(fragment);
}
}
}
function test()
{
xhr.open("GET", "getXML.php", true);
xhr.onreadystatechange = data;
xhr.send(null);
}

Trouble with having global JavaScript variables updated

I am trying to get a XML document sorted and decided to go for the "sort via XSLT" approach.
However, I am having trouble updating my two global variables that should contain the content of the XML and XSLT files and I can't really figure out why.
Up until now I never had this kind of problem and global variables used to work... I also didn't declare them inside the functions, but used the global name instead and also tried using window.variable, but to no avail.
Does anyone have an idea why the code doesn't update the global variable?
best regards,
daZza
<script type="text/javascript">
var xml = "";
var xsl = "";
function callSort()
{
loadSortXML();
loadSortXSLT();
sortXML();
}
function loadSortXML()
{
var xmlHttp = null;
var xmlData;
var xmlFile = "data/LessonsLearned.xml";
if (typeof XMLHttpRequest != 'undefined')
{
xmlHttp = new XMLHttpRequest();
}
if (!xmlHttp)
{
try
{
xmlHttp = new ActiveXObject("Msxm12.XMLHTTP");
}
catch(e)
{
try
{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP")
}
catch(e)
{
xmlHttp = null;
}
}
}
if (xmlHttp)
{
var url = xmlFile;
xmlHttp.open("GET", url, true);
xmlHttp.onreadystatechange = function()
{
if (xmlHttp.readyState == 4)
{
xml = xmlHttp.responseXML;
}
}
xmlHttp.send();
}
}
function loadSortXSLT()
{
var xmlHttp = null;
var xmlData;
var xmlFile = "data/xslt.xml";
if (typeof XMLHttpRequest != 'undefined')
{
xmlHttp = new XMLHttpRequest();
}
if (!xmlHttp)
{
try
{
xmlHttp = new ActiveXObject("Msxm12.XMLHTTP");
}
catch(e)
{
try
{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP")
}
catch(e)
{
xmlHttp = null;
}
}
}
if (xmlHttp)
{
var url = xmlFile;
xmlHttp.open("GET", url, true);
xmlHttp.onreadystatechange = function()
{
if (xmlHttp.readyState == 4)
{
xsl = xmlHttp.responseXML;
}
}
xmlHttp.send();
}
}
function sortXML()
{
console.log("XML " + xml);
console.log("XSL "+ xsl);
var parser = new DOMParser();
var domToBeTransformed = parser.parseFromString(xml, "text/xml");
var xslt = parser.parseFromString(xsl, "text/xml");
var processor = new XSLTProcessor();
processor.importStylesheet(xslt);
var newDocument = processor.transformToDocument(domToBeTransformed);
var serializer = new XMLSerializer();
var newDocumentXml = serializer.serializeToString(newDocument);
alert(newDocumentXml);
}
</script>

Ajax - For loop

Ajax calls an array of four strings, I then want to print each string to a new line.
I have this code:
window.onload = function () {
var obj;
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
obj = JSON.parse(xmlhttp.responseText);
for (var i = 0; i <= obj.length; i++) {
document.createTextNode(obj[i]);
}
}
}
xmlhttp.open("GET", "verify.php", true);
xmlhttp.send();
}
However, it doesn't work. obj.length returns 4, I don't know whether the loop isn't executing, or if I can't access the DOM? I'm very new to Javascript and DOM scripting.
Thanks in advance.
You need to actually put the nodes into the document.
var node;
for (var i = 0, n = obj.length; i < n; i++) { // NB: not <=
node = document.createTextNode(obj[i]);
document.body.appendChild(node);
node = document.createElement('br');
document.body.appendChild(node);
}
This only creates the textNode, you must still apply it to the DOM somehwere via appendChild:
https://developer.mozilla.org/en/DOM/document.createTextNode

Parsing or using variables from a called script?

I have an AJAX function which loads content from a file and displays in the file that called it.
But the script that was called I want to loop an array which is actually set in the script that called it... this is main script that calls the file:
function call_file(file, div_id) {
var xmlhttp;
if(window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else { // code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if(xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById(div_id).innerHTML = xmlhttp.responseText;
}
}
xmlhttp.open("GET", file, true);
xmlhttp.send();
}
var global = new Array();
global[0] = 1;
global[1] = 2;
call_script('html.html', 'main');
html.html is the file that is called which has this:
<script>
i = 0;
for(var id in global) {
alert(i + ' = ' + id);
i++;
}
</script>
Is this at all possible?
One way is to extract the script and eval it yourself. For example:
//....
document.getElementById(div_id).innerHTML = xmlhttp.responseText;
var str = xmlhttp.responseText;
var reg = /<script>([^>]*)<\/script>/img;
while(reg.test(str))eval(RegExp.$1);
//...

Categories