For an assignment, I am making a request to the Github Gist API and then appending the response to an HTML page. I am then supposed to allow the user to "favorite" one of the GISTS and then that GIST is to appear in a separate favorites section (favorited GISTS are to be stored in local storage). I am able to make the request, append the information and make the favorited GISTs appear in another section HOWEVER, the lists only appear for a moment and then disappear after I click on the favorite button. I can see the list flash and then go away. All of the other (non-favorite) GIST info also disappears even though it's not supposed. Can anyone please point me in the right direction? I'm not allowed to use any JQuery. Full code here: http://pastebin.com/ic0juq9n
Critical code below:
var getData = function(url)
{
if(!req)
{
throw 'Unable to create HttpRequest.';
}
req.onreadystatechange = function()
{
if(this.readyState === 4)
{
if (req.status === 200)
{
console.log("It worked!!");
var info = JSON.parse(req.responseText);
for(var key in info)
{
GistList.push(info[key]);
}
}
else
{
console.log("It messed up again");
}
}
for (i = 0; i < GistList.length; i++)
{
generateGistList(GistList[i]);
}
}
req.open('GET', url);
req.send();
};
function generateGistList(Gist) {
var itemList = document.createElement('li');
var holdURL = document.createElement('div');
var holdID = document.createElement('div');
var description = document.createElement('div');
if (Gist.description === null)
{
description.innerHTML = "No description found";
}
else
{
description.innerHTML = "Description: " + Gist.description;
}
holdURL.innerHTML = "URL: " + Gist.url;
holdID.innerHTML = "ID: " + Gist.id;
itemList.appendChild(holdID);
itemList.appendChild(holdURL);
itemList.appendChild(description);
ul.appendChild(itemList);
list.appendChild(ul);
var favorite = document.createElement("button");
favorite.innerHTML = "+";
favorite.setAttribute("gistId", Gist.id);
itemList.appendChild(favorite);
favorite.onclick = function()
{
var gistId = this.getAttribute("gistId"); //saved
var toBeFavoredGist = findById(gistId);
//here you add the gist to your favorite list in the localStorage
and remove it from the gist list and add it to favorite list
addFavorite(toBeFavoredGist);
DisplayFavs();
//removeGist(toBeFavoredGist);
}
}
Make sure if you're using forms that the form tag has an action attribute!
Related
I would like to create a web app that returns 3 random profiles of student that are randomly assigned to you once you click a button.
I am looking for un function that does that but I can't find anything. Do you have anything that does the job?
Here is the Github repository if you need it.
All I've tried function(randomusers) but I failed
$.getJSON("https://randomuser.me/api/", function (randomusers) {
var user = randomusers.results[0];
document.getElementById("prenom").textContent = (user.name.first); //prénom
document.getElementById("adresse").textContent = (user.location.street + " " + user.location.city + " " + user.location.state); // adresse
document.getElementById("email").textContent = (user.email); //email
var img = document.createElement('IMG'); //profile picture
img.setAttribute('src', user.picture.large);
document.getElementById("photo").appendChild(img);
}
I want 3 random user profiles to appear when I click the "find my partners" button. Unfortunately, I am not able to display these 3 profiles and anything for the record. Is it that I didn't link the button to the JS function or that the function is wrong?
I am new to coding and I was a bit too ambitious so I have no clue how to do it now.
Thanks a lot for your help
There are multiple ways to display this in both JavaScript and in JQuery.
You can find the working code sample in this git repository
https://github.com/helloritesh000/DisplayRandom3Profile
Call function GetRandomProfiles() on click on button Find My Partners. This will load 1 profile at a time keep clicking the button it will load the another profile.
<script type="text/javascript">
function GetRandomProfiles()
{
$.getJSON( "https://randomuser.me/api/", function( randomusers ) {
var user = randomusers.results[0];
// document.getElementById("picturegenerator").innerHTML = "";
var img = document.createElement('IMG');
img.setAttribute('src', user.picture.large);
document.getElementById("picturegenerator").appendChild(img);
var detail = document.createElement('div');
detail.innerHTML = "";
var prenom = document.createElement('div');
prenom.setAttribute('id', 'prenom');
prenom.innerHTML = user.name.first;
detail.innerHTML += prenom.outerHTML;
var adresse = document.createElement('div');
adresse.setAttribute('id', 'adresse');
adresse.innerHTML = user.location.street +" "+ user.location.city + " " + user.location.state;
detail.innerHTML += adresse.outerHTML;
var email = document.createElement('div');
email.setAttribute('id', 'email');
email.innerHTML = user.email;
detail.innerHTML += email.outerHTML;
document.getElementById("picturegenerator").appendChild(detail);
} );
}
</script>
Another way to achieve is just add the server call in a for loop which runs 3 times. It will pull 3 profiles in single button click.
<script type="text/javascript">
function GetRandomProfiles()
{
for(i=0; i<3;i++)
{
$.getJSON( "https://randomuser.me/api/", function( randomusers ) {
var user = randomusers.results[0];
// document.getElementById("picturegenerator").innerHTML = "";
var img = document.createElement('IMG');
img.setAttribute('src', user.picture.large);
document.getElementById("picturegenerator").appendChild(img);
var detail = document.createElement('div');
detail.innerHTML = "";
var prenom = document.createElement('div');
prenom.setAttribute('id', 'prenom');
prenom.innerHTML = user.name.first;
detail.innerHTML += prenom.outerHTML;
var adresse = document.createElement('div');
adresse.setAttribute('id', 'adresse');
adresse.innerHTML = user.location.street +" "+ user.location.city + " " + user.location.state;
detail.innerHTML += adresse.outerHTML;
var email = document.createElement('div');
email.setAttribute('id', 'email');
email.innerHTML = user.email;
detail.innerHTML += email.outerHTML;
document.getElementById("picturegenerator").appendChild(detail);
} );
}
}
</script>
Well, you have to do three tasks, and you can do it by using pure JavaScript.
Get 3 random users from the API URL (https://randomuser.me/api/) through HTTP request.
Collect the random user data in an array.
Print the HTML with the proper contents from the array that you have.
With pure JavaScript:
You need to create a helper function to do asynchronous HTTP requests (AJAX). This is a very basic structure for any web project with JavaScript to do asynchronous HTTP requests without any third party library like jQuery. This helper function is kinda similar to $.get(), $.getJSON(), $.ajax() functions in jQuery.
var newXHR = null;
function sendXHR(type, responseType, url, data, callback) {
newXHR = new XMLHttpRequest() || new window.ActiveXObject("Microsoft.XMLHTTP");
newXHR.responseType = responseType;
newXHR.open(type, url, true);
newXHR.send(data);
newXHR.onreadystatechange = function() {
if (this.status === 200 && this.readyState === 4) {
callback(this.response); // Anonymous function is required at this point: function(argument) { ... }.
}
};
}
Note:
You can not use a for loop statement with asynchronous requests
because the results can be obtained at an undetermined time, while the
execution of a for loop is synchronous. In that sense, it is
quite useful to use a callback function that allows the
continuation of the execution of your code when the previous execution
ends in a recursive function with asynchronous requests.
Then:
You may create a recursive function with three parameters: url, times, callback. Where:
url. It's a string that is the API URL: https://randomuser.me/api/.
times. It's a number. In this case is 3, because you need to do 3 HTTP requests to the API URL.
callback. It's a function reference to execute passed as parameter. Its value must be a function. This function reference can receive a value as parameter.
The count and arrayOfUsers variables must be defined in the global scope.
function getUsers(url, times, callback) {
if (count < times) { // Check the limit in the recursive process. You need to execute this function only 3 times to get 3 random users from the API URL.
sendXHR("GET", "json", url, null, function(response) { // The response parameter contains the data from the API URL, so you can store this value in an array for every request.
arrayOfUsers.push(response); // Save the random user data from the API in the array.
count++; // Increment the counter.
getUsers(url, times, callback); // Keep executing the function to get more random user data.
});
} else {
callback(arrayOfUsers); // Once reaching the limit return the result of arrayOfUsers through the callback function.
}
}
To store random user data obtained from the HTTP request, you can use Array#push: In this case: arrayOfUsers.push(response);.
A more practical way to build an HTML markup with data is by concatenating strings.
In this case, I have this function:
function renderUsers(data) {
var html = "", len = data.length, user;
for (var i = 0; i < len; i++) {
user = data[i];
html += "<div class=\"user\"><div><label>Name: </label><span title=\"";
html += "LastName: ";
html += user.results[0].name.last;
html += "\">";
html += user.results[0].name.first;
html += "</span></div><div><label>Address: </label><span>";
html += user.results[0].location.street;
html += " ";
html += user.results[0].location.city;
html += " ";
html += user.results[0].location.state;
html += "</span></div><div><label>Email: </label><span>";
html += user.results[0].email;
html += "</span></div><div><label>Image: </label><span>";
html += "<img alt=\"";
html += user.results[0].picture.large;
html += "\" src=\"";
html += user.results[0].picture.large;
html += "\" /></div></div>";
}
return html; // Return the built html.
}
You would have something like this:
(function() {
// Declaring global variables.
var newXHR = null, arrayOfUsers = [], count = 0;
// Helper function to make HTTP requests (AJAX) with JavaScript.
function sendXHR(type, responseType, url, data, callback) {
newXHR = new XMLHttpRequest() || new window.ActiveXObject("Microsoft.XMLHTTP");
newXHR.responseType = responseType;
newXHR.open(type, url, true);
newXHR.send(data);
newXHR.onreadystatechange = function() {
if (this.status === 200 && this.readyState === 4) {
callback(this.response);
}
};
}
// Recursive function to get random users.
function getUsers(url, times, callback) {
if (count < times) { // Check the limit in the recursive process. You need to execute this function only 3 times to get 3 random users from the API URL.
sendXHR("GET", "json", url, null, function(response) { // The response parameter contains the data from the API URL, so you can store this value in an array for every request.
arrayOfUsers.push(response); // Save the random user data from the API in the array.
count++; // Increment the counter.
getUsers(url, times, callback); // Keep executing the function to get more random user data.
});
} else {
callback(arrayOfUsers); // Once reaching the limit return the result of arrayOfUsers through the callback function.
}
}
// Function to render in the page with the random users.
function renderUsers(data) {
var html = "", len = data.length, user;
for (var i = 0; i < len; i++) {
user = data[i];
html += "<div class=\"user\"><div><label>Name: </label><span title=\"";
html += "LastName: ";
html += user.results[0].name.last;
html += "\">";
html += user.results[0].name.first;
html += "</span></div><div><label>Address: </label><span>";
html += user.results[0].location.street;
html += " ";
html += user.results[0].location.city;
html += " ";
html += user.results[0].location.state;
html += "</span></div><div><label>Email: </label><span>";
html += user.results[0].email;
html += "</span></div><div><label>Image: </label><span>";
html += "<img alt=\"";
html += user.results[0].picture.large;
html += "\" src=\"";
html += user.results[0].picture.large;
html += "\" /></div></div>";
}
return html; // Return the built html.
}
var btnFindMyPartners = document.getElementById("btnFindMyPartners");
btnFindMyPartners.onclick = function() {
var users = document.getElementById("users");
users.removeAttribute("hidden");
users.textContent = "Loading...";
arrayOfUsers = []; // Reset array of users.
count = 0;
getUsers("https://randomuser.me/api/", 3, function(data) {
document.getElementById("users").innerHTML = renderUsers(data);
});
};
}());
body {
font-family: "Segoe UI", sans-serif;
font-size: 0.8em;
}
button {
border: #819bc2 solid 1px;
cursor: pointer;
}
#users,
#users .user,
#users .user div,
button {
border-radius: 5px;
margin: 5px;
padding: 5px;
}
#users {
border: #819bc2 solid 1px;
}
#users .user {
background-image: linear-gradient(to left, #cfcee6, #fff);
border: #46628c solid 1px;
box-shadow: inset #92979c 0 0px 20px 0px;
}
#users .user div {
border: #d4dbe7 solid 1px;
}
<button id="btnFindMyPartners">Find my partners</button>
<div id="users" hidden>
</div>
I would like to remind you of the following when you build HTML markup dynamically.
HTML5 - The id attribute:
The id attribute specifies its element's unique identifier (ID). The
value must be unique amongst all the IDs in the element's home subtree
and must contain at least one character. The value must not contain
any space characters.
Hope this helps a little bit more.
The idea is to allow me to press a button on the HTML page to execute a command to copy and delete all photos on cameras with feedback showing at the beginning and ending of the execution.
At the moment, after clicking the "Get Images From Camera", the textarea is showing this text:
Executed command: \copyImages
Result is as below: Copying images from
both cameras...\n
And it goes on to copy and delete all images like I want. But at the end of this process, nothing is returned back to the screen, so the user has no idea what happens. The nature of callback in Node js makes it too confusing for me to figure out how to do this.
P.S. I've tried all I know before I come here to get your help. So know that any suggestions are very appreciated!
So, my question is how do I change the codes below so that I could
display a message to show the user that the copying is completed successfully like:
Please wait for the copying to complete...
Completed!
Below are the HTML markups
<button id="copyImages" type="button" class="button">Get Images From Camera</button>
<textarea id="output" readonly></textarea>
Here is the Javascript event handling:
copyImages.onclick = function() {
dest = '/copyImages';
writeToOutput(dest);
}
function writeToOutput(dest) {
$.get(dest, null, function(data) {
resultText += "Executed command: "+dest+"\n"
+"Result is as below: \n"+data;
$("#output").val(resultText);
}, "text");
return true;
}
These functions below are for setting up a Node App server using express module to listen to anything the HTML page passes to it. They are run on a different device.
expressServer.listen( expressPort, function() {
console.log('expressServer listening at *:%d', expressPort );
});
// allow CORS on the express server
expressServer.use(function(req, res, next) {
// enable cross original resource sharing to allow html page to access commands
res.header("Access-Control-Allow-Origin", "*");
// return to the console the URL that is being accesssed, leaving for clarity
console.log("\n"+req.url);
next();
});
expressServer.get('/copyImages', function (req, res) {
// user accesses /copyImages and the copyImages function is called
copyImages(function(result) {
res.end(result + "\n");
});
});
Copy images from Theta S Camera to Raspberry Pi and delete those from the cameras
var resultCopyImages = "";
copyImages = function (callback) {
resultCopyImages = "Copying images from both cameras...\n";
for (var i = 0; i < camArray.length; i++) {
copyOneCamImages(i, callback);
}
return (callback(resultCopyImages));
//how to return multiple messages?
}
copyOneCamImages = function (camID, callback) {
d.on('error', function(err){
console.log('There was an error copying the images');
return(callback('There was an error running a function, please make sure all cameras are connected and restart the server'));
})
d.run(function(){
var imageFolder = baseImageFolder + camID;
// if the directory does not exist, make it
if (!fs.existsSync(imageFolder)) {
fs.mkdirSync(imageFolder);
console.log("no 'images' folder found, so a new one has been created!");
}
// initialise total images, approximate time
var totalImages = 0;
var approxTime = 0;
// get the first image and do not include thumbnail
var entryCount = 1;
var includeThumb = false;
var filename;
var fileuri;
// get the total amount of images
camArray[camID].oscClient.listImages(entryCount, includeThumb)
.then(function (res) {
totalImages = res.results.totalEntries;
approxTime = totalImages * 5;
resultCopyImages = '';
resultCopyImages = 'Camera ' + (camID + 1) + ': Copying a total of: ' + totalImages + ' images'
+ '\nTo folder: ' + imageFolder
+ '\nThis process will take approximately: ' + approxTime + ' seconds \n';
console.log(resultCopyImages);
callback(resultCopyImages);
});
// copy a single image, with the same name and put it in images folder
camArray[camID].oscClient.listImages(entryCount, includeThumb)
.then(function (res) {
filename = imageFolder + '/' + res.results.entries[0].name;
fileuri = res.results.entries[0].uri;
imagesLeft = res.results.totalEntries;
// gets the image data
camArray[camID].oscClient.getImage(res.results.entries[0].uri)
.then(function (res) {
var imgData = res;
fs.writeFile(filename, imgData);
camArray[camID].oscClient.delete(fileuri).then(function () {
if (imagesLeft != 0) {
// callback to itself to continue copying if images are left
callback(copyOneCamImages(camID, callback));
//????????????????????????????????????????????????????????????????????????????
//if(imagesLeft==1) return(callback("Finished copying"));
}/* else {
resultCopyImages = "Finshed copying image.\n";
console.log(resultCopyImages);
}
else if
return(callback(resultCopyImages));
}*/
});
});
});
})
}
So far there is no real answer to the question I asked so we have concluded the project and skipped the feature. However, it's just the matter of mastering the REST API and the asynchronous functions in NodeJs. The project is expected to continue for a next version sometime next year.
Below is my ajax function which retrieves the data from servelt and shows it fine in the jps and the problem is every time a new ajax calls is submit the form just appends the data into the results received from previous calls, I need reset the current values stored in the table OrderResultContainer and then display it with new data.
I tried
document.getElementById("OrderResultContainer").reset = ();
but it's just reset the entire form data and not showing any data in the page.
function addData() {
if(window.XMLHttpRequest) {
var xhttp = new XMLHttpRequest();
var loading = document.getElementById("loading");
document.getElementById("loading").style.display = "";
document.getElementById("OrderResultContainer").style.display = "none";
xhttp.open("POST","Order",true);
var formData = new FormData(document.getElementById('orderform'));
xhttp.send(formData);
xhttp.onreadystatechange=function() {
if ((xhttp.readyState == 4) && (xhttp.status == 200)) {
var jsonorderdata = JSON.parse(xhttp.responseText);
txt = "";
for (x in jsonorderdata) {
txt += "<tr><td>" + jsonorderdata[x].ordernumber+"</td>""</tr>";
}
document.getElementById("loading").style.display = "none";
document.getElementById("ViewOrderResultContainer").innerHTML = document.getElementById("ViewOrderResultContainer").innerHTML + txt;
document.getElementById("divOrderResultContainer").style.display = "";
}
};
}else
console.log('Ajax call is failed');
}
Can anyone help me on how to reset the data in the table OrderResultContainer alone after a new ajax response received from servlet.
You append the received data to the previous with following code:
document.getElementById("ViewOrderResultContainer").innerHTML = document.getElementById("ViewOrderResultContainer").innerHTML + txt;
So if you change it like following you would have only new data:
document.getElementById("ViewOrderResultContainer").innerHTML = txt;
It is kind of hard to see without the corresponding html but this looks like the problem:
document.getElementById("ViewOrderResultContainer").innerHTML =
document.getElementById("ViewOrderResultContainer").innerHTML + txt;
Your taking the innerHtml from the ViewOrderResultContainer and append the value from txt. If you do that more than once than it will keep growing. If you want to replace the text than replace it with
document.getElementById("ViewOrderResultContainer").innerHTML = txt;
p.s. the given javascript is not valid
txt += "<tr><td>" + jsonorderdata[x].ordernumber+"</td>""</tr>";
I have a slickgrid screen (on regular Domino form) wherein user can select and update some documents. I needed to show a pop-up displaying status of every selected document so I created an XPage. In my XPage I am looping through selected documents array (json) and call an RPC method for every document. Code to call RPC method is in a button which is clicked on onClientLoad event of XPAGE. RPC is working fine because documents are being updated as desired. Earlier I had RPC return HTML code for row () which was being appended to HTML table. It works in Firefox but not in IE. Now I am trying to append rows using Dojo but that’s not working either.
Here is my Javascript code on button click.
var reassign = window.opener.document.getElementById("ResUsera").innerHTML;
var arr = new Array();
var grid = window.opener.gGrid;
var selRows = grid.getSelectedRows();
for (k=0;k<selRows.length;k++)
{
arr.push(grid.getDataItem(selRows[k]));
}
var tab = dojo.byId("view:_id1:resTable");
while (arr.length > 0)
{
var fldList = new Array();
var ukey;
var db;
var reqStatusArr = new Array();
var docType;
var docno;
ukey = arr[0].ukey;
db = arr[0].docdb;
docType = arr[0].doctypeonly;
docno = arr[0].docnum;
fldList.push(arr[0].fldIndex);
reqStatusArr.push(arr[0].reqstatusonly);
arr.splice(0,1)
for (i=0;i < arr.length && arr.length>0;i++)
{
if ((ukey == arr[i].ukey) && (db == arr[i].docdb))
{
fldList.push(arr[i].fldIndex);
reqStatusArr.push(arr[i].reqstatusonly);
arr.splice(i,1);
i--;
}
}
console.log(ukey+" - "+db+" - "+docno+" - "+docType);
var rmcall = faUpdate.updateAssignments(db,ukey,fldList,reassign);
rmcall.addCallback(function(response)
{
require(["dojo/html","dojo/dom","dojo/domReady!"],function(html,dom)
{
var tbdy = dom.byId("view:_id1:resTable").getElementsByTagName("tbody");
html.set(tbdy,
tbdy.innerHTML+"<tr>"+
"<td>"+docType+"</td>"+
"<td>"+docno+"</td>"+
"<td>"+reqStatusArr.join("</br>")+"</td>"+
"<td>"+response+"</td></tr>"
);
});
});
}
dojo.byId("view:_id1:resTable").style.display="inline";
dojo.byId("idLoad").style.display="none";
RPC Service Code
<xe:jsonRpcService
id="jsonRpcService2"
serviceName="faUpdate">
<xe:this.methods>
<xe:remoteMethod name="updateAssignments">
<xe:this.arguments>
<xe:remoteMethodArg
name="dbPth"
type="string">
</xe:remoteMethodArg>
<xe:remoteMethodArg
name="uniquekey"
type="string">
</xe:remoteMethodArg>
<xe:remoteMethodArg
name="fieldList"
type="list">
</xe:remoteMethodArg>
<xe:remoteMethodArg
name="reassignee"
type="string">
</xe:remoteMethodArg>
</xe:this.arguments>
<xe:this.script><![CDATA[print ("starting update assignments from future assignments page");
var db:NotesDatabase = null;
var vw:NotesView = null;
var doc:NotesDocument = null;
try{
db=session.getDatabase("",dbPth);
if (null!= db){
print(db.getFileName());
vw = db.getView("DocUniqueKey");
if (null!=vw){
print ("got the view");
doc = vw.getDocumentByKey(uniquekey);
if (null!=doc)
{
//check if the document is not locked
if (doc.getItemValueString("DocLockUser")=="")
{
print ("Got the document");
for (i=0;i<fieldList.length;i++)
{
print (fieldList[i]);
doc.replaceItemValue(fieldList[i],reassignee);
}
doc.save(true);
return "SUCCESS";
}
else
{
return "FAIL - document locked by "+session.createName(doc.getItemValueString("DocLockUser")).getCommon();
}
}
else
{
return "FAIL - Contact IT Deptt - Code: 0";
}
}
else
{
return "FAIL - Contact IT Deptt - Code: 1";
}
}
else
{
return "FAIL - Contact IT Deptt - Code: 2";
}
}
catch(e){
print ("Exception occured --> "+ e.toString());
return "FAIL - Contact IT Deptt - Code: 3";
}
finally{
if (null!=doc){
doc.recycle();
vw.recycle();
db.recycle();
}
}]]></xe:this.script>
</xe:remoteMethod>
</xe:this.methods>
</xe:jsonRpcService>
Thanks in advance
I have resolved this issue. First, CSJS variables were not reliably set in callback function so I made RPC return the HTML string I wanted. Second was my mistake in CSJS. I was trying to fetch tbody from table using
var tbdy = dom.byId("view:_id1:resTable").getElementsByTagName("tbody");
where as it returns an array so it should have been
var tbdy = dom.byId("view:_id1:resTable").getElementsByTagName**("tbody")[0]**;
also I moved tbody above while loop. I can post entire code if anyone is interested!!
Building a chat app and I am trying to fetch all logged in user into a div with ID name "chat_members". But nothing shows up in the div and I have verified that the xml file structure is correct but the javascript i'm using alongside ajax isn't just working.
I think the problem is around the area of the code where I'm trying to spool out the xml data in the for loop.
XML data sample:
<member>
<user id="1">Ken Sam</user>
<user id="2">Andy James</user>
</member>
Javascript
<script language="javascript">
// JavaScript Document
var getMember = XmlHttpRequestObject();
var lastMsg = 0;
var mTimer;
function startChat() {
getOnlineMembers();
}
// Checking if XMLHttpRequest object exist in user browser
function XmlHttpRequestObject(){
if(window.XMLHttpRequest){
return new XMLHttpRequest();
}
else if(window.ActiveXObject){
return new ActiveXObject("Microsoft.XMLHTTP");
} else{
//alert("Status: Unable to launch Chat Object. Consider upgrading your browser.");
document.getElementById("ajax_status").innerHTML = "Status: Unable to launch Chat Object. Consider upgrading your browser.";
}
}
function getOnlineMembers(){
if(getMember.readyState == 4 || getMember.readyState == 0){
getMember.open("GET", "get_chat.php?get_member", true);
getMember.onreadystatechange = memberReceivedHandler;
getMember.send(null);
}else{
// if the connection is busy, try again after one second
setTimeout('getOnlineMembers()', 1000);
}
}
function memberReceivedHandler(){
if(getMember.readyState == 4){
if(getMember.status == 200){
var chat_members_div = document.getElementById('chat_members');
var xmldoc = getMember.responseXML;
var members_nodes = xmldoc.getElementsByTagName("member");
var n_members = members_nodes.length;
for (i = 0; i < n_members; i++) {
chat_members_div.innerHTML += '<p>' + members_nodes[i].childNodes.nodeValue + '</p>';
chat_members_div.scrollTop = chat_members_div.scrollHeight;
}
mTimer = setTimeout('getOnlineMembers();',2000); //Refresh our chat members in 2 seconds
}
}
}
</script>
HTML page
<body onLoad="javascript:startChat();">
<!--- START: Div displaying all online members --->
<div id="chat_members">
</div>
<!---END: Div displaying all online members --->
</body>
I'm new to ajax and would really appreciate getting help with this.
Thanks!
To troubleshoot this:
-- Use an HTTP analyzer like HTTP Fiddler. Take a look at the communication -- is your page calling the server and getting the code that you want back, correctly, and not some type of HTTP error?
-- Check your IF statements, and make sure they're bracketed correctly. When I see:
if(getMember.readyState == 4 || getMember.readyState == 0){
I see confusion. It should be:
if( (getMember.readyState == 4) || (getMember.readyState == 0)){
It might not make a difference, but it's good to be absolutely sure.
-- Put some kind of check in your javascript clauses after the IF to make sure program flow is executing properly. If you don't have a debugger, just stick an alert box in there.
You must send the xmlhttp request before checking the response status:
function getOnlineMembers(){
getMember.open("GET", "get_chat.php?get_member", true);
getMember.onreadystatechange = memberReceivedHandler;
getMember.timeout = 1000; //set timeout for xmlhttp request
getMember.ontimeout = memberTimeoutHandler;
getMember.send(null);
}
function memberTimeoutHandler(){
getMember.abort(); //abort the timedout xmlhttprequest
setTimeout(function(){getOnlineMembers()}, 2000);
}
function memberReceivedHandler(){
if(getMember.readyState == 4 && getMember.status == 200){
var chat_members_div = document.getElementById('chat_members');
var xmldoc = getMember.responseXML;
var members_nodes = xmldoc.documentElement.getElementsByTagName("member");
var n_members = members_nodes.length;
for (i = 0; i < n_members; i++) {
chat_members_div.innerHTML += '<p>' + members_nodes[i].childNodes.nodeValue + '</p>';
chat_members_div.scrollTop = chat_members_div.scrollHeight;
}
mTimer = setTimeout('getOnlineMembers();',2000); //Refresh our chat members in 2 seconds
}
}
To prevent caching response you can try:
getMember.open("GET", "get_chat.php?get_member&t=" + Math.random(), true);
Check the responseXML is not empty by:
console.log(responseXML);
Also you might need to select the root node of the xml response before selecting childNodes:
var members_nodes = xmldoc.documentElement.getElementsByTagName("member"); //documentElement selects the root node of the xml document
hope this helps