Simple AJAX Retrieval of data in XML file, going wrong around ".responseXML" - javascript

I've searched and searched and quadruple checked spelling and syntax and I'm stumped. I even checked the syntax on "jslint". I've placed all the code on "jsfiddle":
http://jsfiddle.net/sxtuX/
var xmlHttp= createXmlHttpRequestObject();
function createXmlHttpRequestObject(){
var xmlHttp;
if(window.XMLHttpRequest){
xmlHttp = new XMLHttpRequest();
}
else{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
return xmlHttp;
}
function process() {
if (xmlHttp) {
try{
xmlHttp.open("GET", "data_people.xml", true);
xmlHttp.onreadystatechange = handleStateChange;
xmlHttp.send(null);
}
catch (e) {
alert ("In process function.<br/>Error in creating xmlHttp object: "+ e.toString());
}
}
}
function handleStateChange() {
if(xmlHttp.readyState==4) {
if (xmlHttp.status==200) {
try {
handleResponse();
}
catch(e) {
alert ("Trouble getting text." + e.toString());
}
}
else {
alert ("State = "+xmlHttp.readyState+" Status= " + xmlHttp.status);
}
}
}
function handleResponse() {
var xmlResponse = xmlHttp.responseXML,
root = xmlResponse.documentElement,
names = root.getElementsByTagName("name"),
ssns = root.getElementsByTagName("ssn");
alert (xmlHttp.responseText);
var stuff = "";
for(var i=0;i<names.length;i++) {
stuff = names.item(i).firstChild.data + "-" + ssns.item(i).firstChild.data + "<br/>";
}
theD = document.getElementById("theD");
theD.innerHTML = stuff;
}
The javascript works fine up until the last function "handleResponse()" which is the last function. I've placed an "alert" after all the variable declarations using "xmlHttp.responseText" just to prove to myself the file is being accessed and it does print the entire XML file in the alert window.
I tried to create the XML datafile on "jsfiddle" by following the instructions, assuming it was like the HTML file example, but I couldn't get it to work.
So my questions: Why isn't "xmlHttp.responseXML" returning anything? It's either that or something is going wrong with .documentElement. When I examine "names.length" or "ssns.length" they are both zero. Also, can I get some assistance in figuring out the proper way to code an XML file on "jdfiddle" by correcting my fibble attempt?

The way you have your javascript options in the fiddle are set up it only gets executed onLoad (which means all your functions will be defined inside an onload function - and will both not be available in the global scope nor before said function has been executed). It's a catch 22 with sprinkles on top. You'll need to set the second dropdown on the left to either No wrap - in <head> or No wrap - in <body>.
Next up - the jsfiddle example code. There's a whole bunch wrong here:
You should have been referencing Request - not Request.XML (which you just made up ;P). And you should have included the MooTools library (first dropdown on the left) - because that's where Request is from ;)
The url is case sensitive! "/echo/xml/" instead of "/echo/XML/".
The xml string needs to be have properly escaped quotes and javascript strings don't support raw line-breaks (they can be escaped too... but that's another story) - just collapse them for now.
... But you don't need that example. Just use your own code!
Just remember to use the proper test url (with POST not GET) and escape/collapse your test xml.
This is a working fiddle: http://jsfiddle.net/sxtuX/3/

Related

JS Function not returning return

I have the follwing function:
function anfahrtskosten()
{
var xmlhttp;
var entfernung=0;
var anfahrtskostenergebnis=0;
var anfahrtskostenergebnis1=0;
var plz=document.modhochzeitskalk.plz.value;
//aus den Parametern
var anfahrtskosten=1;
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)
entfernung = xmlhttp.responseText;
if (entfernung > 100 && entfernung < 2000) {
anfahrtskostenergebnis1 = anfahrtskosten * entfernung;
} else {
anfahrtskostenergebnis1 = 0;
}
anfahrtskostenergebnis = Math.round(anfahrtskostenergebnis1);
document.getElementById("anfahrtskostenergebnis").innerHTML=anfahrtskostenergebnis+",00 €";
}
xmlhttp.open("GET","/modules/mod_hochzeitskalk/ogdb_remote.php?plzstart=10245&plzend="+plz,true);
xmlhttp.send();
return anfahrtskostenergebnis;
}
I want to use the number stored in the var anfahrtskostenergebnis within another function, I tried it like this:
var gesamtkosten = anfahrtskosten() + videokosten() + filmkosten() + fotokosten() + extrakosten();
But it doesnt work, what am I doing wrong?
Because you are using AJAX, you can not continue processing until the AJAX call returns. The call is Asynchronous, meaning, the program flow continues, and the AJAX call is run in a paralel thread.
It makes a lot of sense to do it this way, as the alternative is to halt all script activity whist you wait for slow network traffic to deliver a result.
You need to re-structure your program to use callback functions, which are called after the value has been returned via AJAX.
This should get you started, but I suspect you are going to have to do similar things for the other functions you add together, and keep track somehow of the values that have already been collected, running the final callback once they are all retrieved.
function anfahrtskosten(){
var xmlhttp;
... your original code here...
anfahrtskostenergebnis = Math.round(anfahrtskostenergebnis1);
// call the callback here, with the value you retrieved
callback(anfahrtskostenergebnis); // <~~~~
document.getElementById("anfahrtskostenergebnis").innerHTML=anfahrtskostenergebnis+",00 €";
}
xmlhttp.open("GET","/modules/mod_hochzeitskalk/ogdb_remote.php?plzstart=10245&plzend="+plz,true);
xmlhttp.send();
}
var callback = function(anfahrtskosten){
var gesamtkosten = anfahrtskosten + videokosten() + filmkosten() + fotokosten() + extrakosten();
// do something with cost...
}
You are missing a start brace '{' after if (xmlhttp.readyState==4 ... (ie., your if is only executing the first statement)
a really easy solution or goaround is to store the varibale somewhere in the document in a innerhtml, what I did already in my example
document.getElementById("anfahrtskostenergebnis").innerHTML=anfahrtskostenergebnis+",00 €";
so the second functions can reuse this value by reading it from the innerHTML.
In my case I needed also to set a small timeout before executing the second function, to be sure

AJAX and Javascript not working

NO JQUERY. I am using peoplecode which is similar to JSP, ASP, and ZXZ. The ajax request is triggered am I am trying to pull the text 'Hello World' from this script...
Function IScript_AJAX_Test()
%Response.Write("<div id='hello'>Hello World</div>");
End-Function;
My javascript function that makes the ajax call looks like this...
function AJAX_test (ajax_link) {
if (typeof XMLHttpRequest == 'undefined') {
XMLHttpRequest = function() {
try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch(e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch(e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) {}
try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) {}
throw new Error('This browser does not support XMLHttpRequest or XMLHTTP.');
};
}
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState == 4 && request.status == 200) {
document.getElementById('ajax').innerHTML = request.responseText.document.getElementById('hello').innerHTML;
//document.getElementById('ajax').innerHTML = 'Testing';
}
}
request.open('GET', ajax_link, true);
request.send();
//document.getElementById('ajax').innerHTML = ajax_link;
}
As you can see in this line..
document.getElementById('ajax').innerHTML = request.responseText.document.getElementById('hello').innerHTML;
...I am trying to grab the text by getting the innerHTML from the id. This isn't working though. When I click the button nothing happens.
I tried using the line below, but it returns an entire new page where the id would be (probably because of Peoplesoft)...
document.getElementById('ajax').innerHTML = request.responseText;
Can someone help me achieve this...
I tried your code and it works for me, with
Function IScript_AJAX_Test()
%Response.Write("<div id='hello'>Hello World");
End-Function;
and in the javascript
document.getElementById('ajax').innerHTML = request.responseText;
Make sure you call the content servlet (psc), not the portal servlet (psp), e.g.
'http://peoplesofturl/psc/ps/EMPLOYEE/HRMS/s/WEBLIB_Z_SYS.FUNCLIB.FieldFormula.IScript_AJAX_Test', otherwise you'll get the response wrapped in the peoplesoft portal.
You can generate the url from peoplecode with the GenerateScriptContentRelURL or GenerateScriptContentURL functions.
Make it simple:
Function IScript_AJAX_Test()
%Response.Write("Hello World");
End-Function;
Javascript:
document.getElementById('ajax').innerHTML = request.responseText;
Ajax might be two types. One is server-side and the other one is client-side. You are trying to get data from client side. In this case ajax fetch nothing but the whole page result of a page not a portion. You will have the whole page result(HTML output) if you write
document.getElementById('ajax').innerHTML = request.responseText;
But you cannot fetch just only the innerHtml part of certain portion of another page. On that case you will get the whole page.

AJAX div not updating without alert call with error: b.data is undefined

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 and 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?
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...

id, string or integer was expected with eval()

I get a strange error in IE.. but no problems in both FF and chrome
when I alert the variable I get this:
json_post('delete_accounting', 'json.action.php?action=delete_accounting', 'id=682', 'rtn_accounting', {tr_id:'tr_acc682', enc_id:374, delete:1});
but when I want to eval() the sting I get this error (the error is translated from danish, so I don't know how it is put in english?)
id, string or integer was expected
EDIT:
var xmlhttp = {};
function json_post(request_var, response, get_str, callback_function, callback_var)
{
request_var += Math.floor(Math.random()*999).toString();
CNSTR.mouseLoader.cnstr();
if(window.XMLHttpRequest) xmlhttp[request_var] = new XMLHttpRequest();
else if(window.ActiveXObject) xmlhttp[request_var] = new ActiveXObject('Microsoft.XMLHTTP');
xmlhttp[request_var].open('POST', response, true);
xmlhttp[request_var].setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlhttp[request_var].onreadystatechange = function()
{
if(xmlhttp[request_var].readyState == 4)
{
CNSTR.mouseLoader.dstr();
if(callback_function) eval(callback_function+'('+xmlhttp[request_var].responseText+(callback_var ? ', callback_var':'')+')');
}
}
xmlhttp[request_var].send(get_str);
}
I'm quite sure that the error occurs in the eval() because when I run the sting as real code there are no problems..
like this:
json_post('delete_accounting', 'json.action.php?action=delete_accounting', 'id=682', 'rtn_accounting', {tr_id:'tr_acc682', enc_id:374, delete:1});
I have also tried to escape everything in the callback function rtn_accounting(), and still the same error in the same line with the eval()
by adding quotes in the object in the last parameter is works
json_post('delete_accounting', 'json.action.php?action=delete_accounting', 'id=682', 'rtn_accounting', {'tr_id':'tr_acc682', 'enc_id':374, 'delete':1});

Strange javascript behavior - multiple active XMLHttpRequests at once? Long running scripts?

I'm attempting to issue two concurrent AJAX requests.
The first call (/ajax_test1.php) takes a very long time to execute (5 seconds or so).
The second call (/ajax_test2.php) takes a very short time to execute.
The behavior I'm seeing is that I /ajax_test2.php returns and the handler gets called (updateTwo()) with the contents from /ajax_test2.php.
Then, 5 seconds later, /ajax_test1.php returns and the handler gets called (updateOne()) with the contents from /ajax_test2.php still!!!
Why is this happening?
Code is here: http://208.81.124.11/~consolibyte/tmp/ajax.html
This line:-
req = new XMLHttpRequest();
should be:-
var req = new XMLHttpRequest();
As AnthonyWJones stated, your javascript is declaring the second AJAX object which first overwrites the req variable (which is assumed global since there is no var) and you are also overwriting the ajax variable.
You should separate your code i.e:
function doOnChange()
{
var ajax1 = new AJAX('ajax_test1.php', 'one', updateOne);
var ajax2 = new AJAX('ajax_test2.php', 'two', updateTwo);
}
function AJAX(url, action, handler)
{
if (typeof XMLHttpRequest == "undefined")
{
XMLHttpRequest = function()
{
try { return new ActiveXObject("Msxml2.XMLHTTP.6.0") } catch(e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP.3.0") } catch(e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP") } catch(e) {}
try { return new ActiveXObject("Microsoft.XMLHTTP") } catch(e) {}
throw new Error( "This browser does not support XMLHttpRequest." )
};
}
url = url + '?action=' + action + '&rand=' + Math.random()
var req = new XMLHttpRequest();
req.onreadystatechange = function() {
if (req.readyState == 4)
{
if (req.status == 200)
{
alert('' + handler.name + '("' + req.responseText + '") ')
handler(req.responseText)
}
}
}
req.open("GET", url, true);
req.send(null);
}
Regards
Gavin
Diodeus and Mike Robinson:
You guys didn't read my post fully. I know that one of the pages takes longer to execute than the other. That is the expected behavior of each page.
HOWEVER if you read my original post, the problem is that the callback for both pages ends up getting called with the HTML contents of the first page only.
AnthonyWJones and Gavin:
Thanks guys! That works like a charm! I guess I need to brush up on my Javascript!

Categories

Resources