ajax - request data from multiple files on one page? - javascript

I am trying to run multiple Ajax functions on load in a single page which will get data from two different php pages. Both the Ajax functions will then print the retrieved data onto the page from which the ajax function was called. The problem I encountered was that the last function call which I make from the Ajax overrides the first function call, and so only the second function result is showed.
The code for one of the Ajax function (since both of the are very similar to each other):
function favorite_track_request(str){
switch(str){
case 'next_track':
var feed = 'require_fav_track_info';
var offset = track_currentOffset + 5;
if(offset > max_track_range){
offset -= 5;
}
break;
case 'prev_track':
var feed = 'require_fav_track_info';
var offset = track_currentOffset - 5;
if(offset < 0){
offset = 0;
}
break;
default:
var feed = 'require_fav_track_info';
var offset = 0;
}
request = new ajaxRequest()
request.open("GET", "scripts/"+feed+".php?offset="+offset, true)
request.onreadystatechange = function(){
if(this.readyState == 4){
if(this.status == 200){
if(this.responseText != null){
if(request.responseText){
document.getElementById('fav_tracks').innerHTML = request.responseText;
}
}else alert("No data recieved");
}else {
alert("Ajax error: "+this.statusText);
}
}
}
request.send(null);
track_currentOffset = offset;
}
This ajax would then print to <div id="fav_tracks"></div>, however this gets overridden because another call (similar to the Ajax above) is made and that overrides the previous one. Is there any way to stop this?

I built a data handler "class" to manage just such a thing. You are right, the one overrides the other. I haven't investigated it, but it's probabably because your are re-assigning the onEvent that AJAX uses.
Below is the class I built (I know, it's not JQuery... it works). What it does is uses timeouts to "know" when to fire the second and third async request. There probably is a JQuery function that does the same thing.
You would call this by using the below for each AJAX call (giving each call a unique var name):
dataHandler = new DataHandler("[name of datafile to call]");
dataHandler.query['[myQueryName]'] = 'myValue' //this is an Object used to build a query string, if needed, so use as many data pairs as you need
dataHandler.asynchronous(myOnReadyStateChangeFN);//put the fn you want to use for readystatechange as a reference... do not includ the ()
Here's the "class":
function DataHandler(dataFile){
this.dataFile = dataFile;
dataInProgress = false;
this.query = new Object();
this.asynchronous = function(fn){
var thisFunction = this.asynchronous
var rand = Math.floor(Math.random()*100001);
var query, timeOutFunctionString;
if(this.dataInProgress){
timeOutFunctionString = callingObjectName+".asynchronous("+fn+")";
this.thisTimeout = setTimeout(timeOutFunctionString,500);
}else{
dataInProgress = true;
this.assignRequestObject.xmlHttp.onreadystatechange = function () {
fn();
dataInProgress = false;
return;
};
}
query = this.dataFile + '?r=' + rand;
for (var key in this.query) query = query + '&' + key + '=' + this.query[key];
//console.info("DataHandler.asynchronous\nquery = "+query+'\nthis.dataFile = ' + this.dataFile);
this.assignRequestObject.xmlHttp.open('GET', query, true);
this.assignRequestObject.xmlHttp.send(null);
};
this.AssignRequestObject = function() {
try { this.xmlHttp = new XMLHttpRequest() } catch (e) {
try { this.xmlHttp = new ActiveXObject("Msxml2.XMLHTTP") } catch (e) {
try { this.xmlHttp = new ActiveXObject("Microsoft.XMLHTTP") } catch (e) {
alert("Your browser does not support AJAX!");
return false
}
}
}
};
this.assignRequestObject = new this.AssignRequestObject();
};

Related

Send multiple parameter in ajax request using javascript

So I want to use ajax request and I know how to use it.
But problem that i had that I want to pass parameters to request. So My first page had 4 parameter then I build url like this,
var url = "./ControllerServlet?PAGE_ID=BPCLA&ACTION=closeAssessment&SAVE_FLAG=true&closeReason="+closeReasonStr+"&closeCmt="+closeCmt;
but now parameter is increasing like now I have 20 more. So now building url like this going to be messy approach. Is there a better way to do this.
Here is my function where i am building URL in javascript function.
function closeAssessment() {
var closeReason = document.getElementById("SectionClousureReason");
var closeReasonStr = closeReason.options[closeReason.selectedIndex].value;
var closeCmt=document.getElementById("SectionCloseAssessmentCmt").value;
var url = "./ControllerServlet?PAGE_ID=BPCLA&ACTION=closeAssessment&SAVE_FLAG=true&closeReason="+closeReasonStr+"&closeCmt="+closeCmt;
ajaxRequest(url);
return;
}
edit:
As you ask here is my ajaxRequest function,
function ajaxRequest(url) {
strURL = url;
var xmlHttpRequest = false;
var self = this;
// Mozilla, Safari
if (window.XMLHttpRequest) {
self.xmlHttpRequest = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
self.xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
self.xmlHttpRequest.open("POST", strURL, true);
self.xmlHttpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
self.xmlHttpRequest.onreadystatechange = function() {
if (self.xmlHttpRequest.readyState == 4) {
if (self.xmlHttpRequest.status == 200) {
var htmlString = self.xmlHttpRequest.responseText;
var parser = new DOMParser();
var responseDoc = parser.parseFromString(htmlString, "text/html");
window.close();
} else {
ajaxFailedCount++;
// Try for 1 min (temp fix for racing condition)
if (ajaxFailedCount < 1200) {window.setTimeout(function() {ajaxRequest(url)}, 50);}
else {alert("Refresh failed!")};
}
}
}
self.xmlHttpRequest.send(null);
}
You could make an object with the key/value pairs being what you want added to the URL.
var closeReason = document.getElementById("SectionClousureReason");
var params = {
PAGE_ID: 'BPCLA',
ACTION: 'closeAssessment',
SAVE_FLAG: 'true',
closeReasonStr: closeReason.options[closeReason.selectedIndex].value,
closeCmt: document.getElementById("SectionCloseAssessmentCmt").value
};
Then add them to the URL via a loop.
var url = "./ControllerServlet?";
var urlParams = Object.keys(params).map(function(key){
return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);
}).join('&');
url += urlParams;
ajaxRequest(url);
Note: I added encodeURIComponent just to be safe.
EDIT: From your comment, it seems you want to submit a <form> but you want to use AJAX to do so. In that case, you can loop over the form elements and build the above params object.
var params = {
PAGE_ID: 'BPCLA',
ACTION: 'closeAssessment',
SAVE_FLAG: 'true'
};
var form = document.getElementById('yourForm'),
elem = form.elements;
for(var i = 0, len = elem.length; i < len; i++){
var x = elem[i];
params[x.name] = x.value;
}
Build up an object of your parameters and put them in the uri through a loop like this:
var values= {
page_id: 'BPCLA',
action: 'test'
},
uri_params = [],
uri = 'http://yoururl.com/file.php?';
for (var param in values) uri_params.push( encodeURIComponent( param ) + '=' + encodeURIComponent( values[ param ] ) );
uri = uri + uri_params.join( '&' );
console.log( uri );
Or consider using POST to transport your parameters, as many browsers have limitations on the query string.
Edit: you can also build yourself a function which traverses your form and builds up the values object for you so you don't have to do it manually.
Be aware however that anyone can inject custom url paramters simpy by appending form elements before submitting the form (by using the developer tools for example) so keep that in mind.
If you are using jQuery you can use .serializeArray() or have a look at this answer for a possible function you could use.

pure javascript: Why doesn't script loaded in ajax content work?

This is the code I wrote:
function responseAjax(element, url, loader, data) {
if(request.readyState == 4) {
if(request.status == 200) {
//The response has 2 main parts: the main page element and the javascript that have the text "???PHPTOSCRIPT???" in between
output = request.responseText.split('???PHPTOSCRIPT???');
if (element) document.getElementById(element).innerHTML = output[0];//put first part into element
if (output[1] != "") eval(output[1]); //execute script
//remember the last request
if (typeof(url) !== 'undefined') {
document.cookie = "requestedURL=" + escape(url);
document.cookie = "requestedElement=" + escape(element);
document.cookie = "requestedLoader=" + escape(loader);
document.cookie = "requestedData=" + escape(data);
};
};
};
};
function ajax(url, element, loader, data, remember, async) {
remember = (typeof(remember) === 'undefined') ? false : remember;//remember last request. Default: false
async = (typeof(async) === 'undefined') ? true : async;//handle request asynchronously if true. Default: true
if (loader) document.getElementById(element).innerHTML = loader;
try { request = new XMLHttpRequest(); /* e.g. Firefox */}
catch(err) {
try { request = new ActiveXObject("Msxml2.XMLHTTP"); /* some versions IE */}
catch(err) {
try { request = new ActiveXObject("Microsoft.XMLHTTP"); /* some versions IE */}
catch(err) { request = false;}
}
}
if (request) {
url += "?r=" + parseInt(Math.random()*999999999);//handle the cache problem
//put an array of data into string. Default: null array
data = data || [];
for (var i = 0; i < data.length; i++) {
url += "&" + data[i];
};
request.open("GET", encodeURI(url), async);
url = url.split('?');//get query string for remembered request
request.onreadystatechange = (remember) ? function() {responseAjax(element, url[0], loader, data.join('&'));}
: function() {responseAjax(element)};
request.send(null);
} else {
document.getElementById(element).innerHTML = "<h3>Browser Error</h3>";
};
};
Though I use eval() to handle returned script, the script doesn't work on events after all if I use pure javascript. However, if I use jQuery such as $("#tab-panel").createTabs();, this code works fine.
Can someone please explain why pure javascript on the loaded content of ajax doesn't work?
Additional information: As I said, pure javascipt such as function sent through the ajax content doesn't work on events, however another code such as alert() works fine.

SCRIPT65535: Invalid calling object in IE9

I am new to javascript. I am facing an issue in someone else written code. They have created a security.js file and they are trying to overwrite xmlHTTPRequest (am not sure). attaching the code here.
(function () {
function getXHRObj(baseObj){
var Impl = function(){
this.onreadystatechange = null;
return this;
};
//Impl.prototype.onreadystatechange = null;
// set the prototype of the new constructor
Impl.prototype = baseObj;
//Impl.prototype.constructor = Impl; // does not work in IE
// the object to be returned
var retObj = new Impl();
function isHTTPReq(url){
if(url){
var colIndx = url.indexOf('://');
if((colIndx < 0)
|| (url.substr(0, colIndx).toLowerCase().indexOf('http') == 0))
return true;
}
return false;
}
// customize open to add token in URL
// even POST request should do this since POST may not always have key=value&... data format
retObj.open = function(method, URL, async, user, pwd){
if(isHTTPReq(URL)){
var prefix = (URL.indexOf('?') < 0)? '?' : '&';
URL += (prefix + window.csrfToken);
}
//alert('making ajax to - ' + URL);
Impl.prototype.open(method, URL, async, user, pwd);
};
// customize send
retObj.send = function(body){
/* Register the handler just before "send" to allow reuse of same object */
Impl.prototype.onreadystatechange = function(){
//alert('Impl.prototype.readyState- '+ Impl.prototype.readyState);
// copy the properties to return object
if(Impl.prototype.readyState)
retObj.readyState = Impl.prototype.readyState;
if(Impl.prototype.readyState == 4){
if(Impl.prototype.status)
retObj.status = Impl.prototype.status;
if(Impl.prototype.statusText)
retObj.statusText = Impl.prototype.statusText;
if(Impl.prototype.responseText)
retObj.responseText = Impl.prototype.responseText;
if(Impl.prototype.responseXML)
retObj.responseXML = Impl.prototype.responseXML;
//alert('xml done');
}
// publish event to return object handler
if(retObj.onreadystatechange){
//alert('invoking handler - \n' + retObj.onreadystatechange);
retObj.onreadystatechange();
}else{
//alert('no handler');
}
};
Impl.prototype.send(body);
};
// delegate other methods
/* Redefinition is necessary because IE does not allow inheritance
from native objects */
retObj.abort = function() {
Impl.prototype.abort();
};
retObj.setRequestHeader = function(hdr, val){
Impl.prototype.setRequestHeader(hdr, val);
};
retObj.getResponseHeader = function(hdr){
return Impl.prototype.getResponseHeader(hdr);
};
retObj.getAllResponseHeaders = function(){
return Impl.prototype.getAllResponseHeaders();
};
return retObj;
}
// redefine the XMLttpRequest to use custom definition
if(window.XMLHttpRequest){
var Base_XMLHttpRequest = window.XMLHttpRequest;
window.XMLHttpRequest = function(){
//alert('in new XHR');
return getXHRObj(new Base_XMLHttpRequest());
};
}
// redefine the ActiveXObject to use custom definition
if(window.ActiveXObject) {
var Base_ActiveXObject = window.ActiveXObject;
window.ActiveXObject = function(objType){
//alert('in new ActiveXObj for - ' + objType);
if((objType.toLowerCase() != "microsoft.xmlhttp")
&&(objType.toLowerCase().indexOf("msxml2.xmlhttp") < 0)){
// return the standard impl for non-ajax objects
return new Base_ActiveXObject(objType);
}else{`enter code here`
//alert('returning new impl for ' + objType);
return getXHRObj(new Base_ActiveXObject(objType));
}
};
}
})();
This code is working fine in IE7 & 8, but this is giving error in all other browsers.
IE9 error -
SCRIPT65535: Invalid calling object
security.js, line 71 character 4
Error is pointing to this.onreadystatechange = null;
var Impl = function(){
this.onreadystatechange = null;
return this;
};
Appreciate immediate help.
Thanks!

Javascript Auto-fresh XMLHttpRequest problem

I'm writing a desktop gadget which should refresh every 10 minutes or so (It's ten seconds here). What I've determined is that every time I execute the setTimeout, the XML doesn't load again.
I don't know what kind of problem this is. I made sure that the objects are set to null, but they don't re-initialize and I'm left with a blank XML object.
setTimeout("bg_load();getXML()",10000);
function getXML()
{
stat = readSetting();
url = "http://www.weather.gov/xml/current_obs/" + stat[0] + ".xml"
rssObj = new XMLHttpRequest();
rssObj.open("GET", url, false);
rssObj.onreadystatechange = function() {
if (rssObj.readyState === 4) {
if (rssObj.status === 200) {
document.getElementById("gadgetContent").innerHTML = "";
rssXML = rssObj.responseXML;
} else {
var chkConn;
document.getElementById("gadgetContent").innerHTML = "Unable to connect...";
}
} else {
document.getElementById("gadgetContent").innerHTML = "Connecting...";
}
}
rssObj.send(null);
getImage(rssXML);
getText(rssXML);
rssObj = null; rssXML = null;
}
With SJAX (Synchronous Ajax), you shouldn't use 'onreadystatechange', and in the code, you pull the response text directly out of the XMLHttpRequest after sending.
Don't Use onreadystatechange:
https://developer.mozilla.org/en/xmlhttprequest#onreadystatechange
Example of pulling the responseText out: http://www.hunlock.com/blogs/Snippets:_Synchronous_AJAX

Unable to return an object's value from a JavaScript function

I have a function which attempts to capture a return value from a calling function in the following manner:
var select = xhrRetrieve(projID);
Here is an example of the xhrRetrieve function:
function xhrRetrieve(projID) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState == 4) {
if(xhr.status == 200) {
var obj = $.parseJSON(xhr.responseText);
return obj.select.toString();
}
}
}
var url = "ajax.cgi";
var data = "action=retrieve-opp&proj-id=" + projID;
xhr.open("POST",url);
xhr.setRequestHeader("Content-Type","application/x-www-urlencoded");
xhr.send(data);
}
I am using jQuery in conjunction with straight JavaScript. Whenever I attempt to get the value of obj.select using:
var select = xhrRetrieve(projID);
Select always comes back undefined.
What am I doing wrong?
The function doesn't return anything
The moment you call your function, the (not currently present) return value is being assigned to select. At the same moment, your ajax request is being fired, which takes time to complete; the callback function will not be called until the ajax request has completed (and succeeded).
This should work:
function doStuffWithTheAjaxResponse(select) {
// do stuff
}
function xhrRetrieve(projID) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState == 4) {
if(xhr.status == 200) {
var obj = $.parseJSON(xhr.responseText);
doStuffWithTheAjaxResponse(obj.select.toString());
}
}
}
var url = "ajax.cgi";
var data = "action=retrieve-opp&proj-id=" + projID;
xhr.open("POST",url);
xhr.setRequestHeader("Content-Type","application/x-www-urlencoded");
xhr.send(data);
}
Since the request is asynchronous the function will return before your code in onreadestatechange fires. You can switch to synchronous and get the value before the function returns:
function xhrRetrieve(projID) {
var returnVal;
var xhr = new XMLHttpRequest();
var url = "ajax.cgi";
var data = "action=retrieve-opp&proj-id=" + projID;
//3rd param is false to switch to synchronous
xhr.open("POST",url, false);
xhr.setRequestHeader("Content-Type","application/x-www-urlencoded");
xhr.send(data);
if(xhr.readyState == 4) {
if(xhr.status == 200) {
var obj = $.parseJSON(xhr.responseText);
return obj.select.toString();
}
}
}
The function xhrRetrieve doesn't have a return value. What do you expect to happen?
You have two functions there. The inner function returns a value, but not the outer one. The inner function is an event handler so the return value doesn't go anywhere. Your XMLHttpRequest is asynchronous, so you won't get a return value right away. See this post for a more detailed explanation: parameter "true" in xmlHttpRequest .open() method

Categories

Resources