Function delivers value, before ajax request changed it - javascript

I am running an ajax request to retrieve a value of either 0,1, or 2 based upon some mysql code in the "check_answer_status.php" file. For test purposes, I have included the alert to check whether the general ajax and mysql request works fine and it does, hence the value contained within "Questiions.answerStatus" at the time of the alert is correct. However, my problem is that the function "checkAnswerStatus" has already executed and did not change the inital value of "answerStatus" (which I set to 50 for test purposes).
Context: sometime later in the code I want to execute code dependent on the value of the variable "answerStatus".
I believe I need to somehow include something like an "oncomplete" or something comparable, but I do not know how to do that. Can anyone help me out? Many thanks!
var = Questions = {
answerStatus:50,
checkAnswerStatus : function(question){
var xmlhttp;
if (window.XMLHttpRequest){
xmlhttp=new XMLHttpRequest();
}
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200){
test = xmlhttp.responseText;
Questions.answerStatus = test;
alert(Questions.answerStatus);
}
}
xmlhttp.open("POST","../../include/check_answer_status.php",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("q="+question);
},

The request you make is asynchronus (the third parameter of the xmlhttp.open function). If you changed it to:
xmlhttp.open("POST","../../include/check_answer_status.php",false);
it should work.
Another options is to pass a callback to your checkAnswerStatus function, and call the callback when the request finishes. Example:
checkAnswerStatus : function(question, callback){
var xmlhttp;
if (window.XMLHttpRequest){
xmlhttp=new XMLHttpRequest();
}
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200){
test = xmlhttp.responseText;
Questions.answerStatus = test;
callback(Questions.answerStatus); //call the function
}
}
xmlhttp.open("POST","../../include/check_answer_status.php",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("q="+question);
}
and then you will call the function like this:
Questions.checkAnswerStatus("bla bla", function(answerStatus) {
alert(answerStatus);
});

in addition to Nemos answer I would recommend you read following resources from MDN:
More technical API documentation for a brief overview of all the possibilities:
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
More real life usecases:
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest
Hope this helps

Related

Execute <script> from separate .php file

Been working on (what seemed like) a simple issues for a few days now and could use some help.
I call a php file on a button-click, do a bunch of server-side operations, and wish to change a few things in the HTML at the end of the php (change images, changing text, enabling buttons, etc.)
So, what I'm trying to do (for the test case here) is change an image twice. It works fine in the first set of code (script in the html file), but it doesn't work in the second set of code (script in the php file). I.e., I see oldImage when the page loads, secondImage when I click the button, but I never see newImage.
<button onclick="test()">Try The Test</button>
<img id="myImage" src="oldImage.jpg">
<script>
function test()
{
var img = document.getElementById('myImage');
img.src = 'secondImage.jpg';
xmlhttp=new XMLHttpRequest();
xmlhttp.open("testPhp.php",true);
xmlhttp.send();
}
</script>
Here's myPhp.php (all on one line in my code; two lines here, for readability):
$script = "<script> var img = document.getElementById('myImage');
img.src = 'newImage.jpg'; </script?";
echo $script;
Any ideas on why the script in myPhp.php doesn't work?
EDIT:
I changed the HTML portion to this, then changed myPhp.php to echo "Hello World", which shows up just fine within myDiv. However, I can't seem to echo the script. Is there any way to do this?
xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","portTester.php",true);
xmlhttp.send();
If your ajax call returns markup, for it to have any effect, it has to be added to the DOM.
But I wouldn't recommend doing it this way. Instead, have your PHP file return the information (not a script), and then have the code receiving the information (in the onreadystatechange handler of the XHR object) read that information and take the relevant action.
For example, your PHP could simply return:
newImage.jpg
Then your ajax call would be:
function test()
{
var img = document.getElementById('myImage');
img.src = 'secondImage.jpg';
xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange = handleReadyStateChange;
xmlhttp.open("testPhp.php",true);
xmlhttp.send();
function handleReadyStateChange() {
if (xmlhttp.readyState === 4 && xmlhttp.status >= 200 && xmlhttp.status < 400) {
// Request is complete and successful
img.src = xmlhttp.responseText;
}
}
}
If you need to send back richer information (as is frequently the case), look at using JSON.
You're not doing anything with the response to your AJAX call. In other words: You are calling the PHP script, the reply is printed, but is thrown away, because your Javascript isn't doing anything with it. You must add some code to interact with the reply. Here's a hint: Don't try to output Javascript from PHP, output something that you USE in your Javascript.
Add this to your Javascript after the xmlhttp.send() call:
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
document.getElementById("myImage").src = xmlhttp.responseText;
}
}
And in your PHP script, put just this:
echo 'newImage.jpg';
One possible issue is that you are missing the semi-colon after your test() in the onclick. Also, your </script> tag is malformed; it reads </script? while it should read </script>. Also, where into the DOM is this echoing? It should go into the head of your document. Right now, it looked unspecified.

why is .innerHTML changed before xmlhttp.open() and .send()?

I am learning to use xmlhttprequest/AJAX. In this sample code from w3schools, I do not understand why this line:
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
precedes this:
xmlhttp.open("GET","demo_get.asp",true);
xmlhttp.send();
The way I'm thinking about it, you should send the GET request before you have any responseText to do anything with. Where is the error in my understanding?
<html>
<head>
<script type="text/javascript">
function loadXMLDoc()
{
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("myDiv").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","demo_get.asp",true);
xmlhttp.send();
}
</script>
</head>
<body>
<h2>AJAX</h2>
<button type="button" onclick="loadXMLDoc()">Request data</button>
<div id="myDiv"></div>
</body>
</html>
The line in question is inside of xmlhttp.onreadystatechange, which is a function. Note how it is used:
xmlhttp.onreadystatechange = function ()
{
...
}
In this case, it is a callback function - it is called when the ajax request (aka xmlhttp.send()) completes.
You might want to brush up on your javascript before you dive into ajax.
You have just discovered the asynchronous part of the AJAX word :-)
Even though the .send() method is called later, the innerHTML call is made earlier.
How come that works?!
Because an AJAX call is asynchronous. Thus, it's not like making a database call in PHP: you make your call, waits for the result, and work with it. Nope.
In JS, for AJAX calls, you define a callback function. It is a function that will be called once the response has arrived.
For the XMLHttpRequest object, it is the onreadystatechange event that is fired when the response comes back. If you register a function in this event, this function will be called when the response will come back.
P.S.: the function in onreadystatechange won't exactly be fired once the response comes back, but this was for the sake of the explanation. To know when this event is fired, take a look at the different states.
It doesn't. Consider this code:
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
}
}
It doesn't execute the code inside the function, it only creates the function and assigns it to a property. The function will be executes by the XMLHTTP object when the state changes, and it will catch the state change that means that the response has arrived.

javascript ajax on submit

i am using a google map api to get location. i have used the below function onchange of address field. it is working properly onchange. i have used same function on submit in the same form to checking the function once again while submitting using a onsubmit attribute. but while submitting i cant able to get answer from this ajax because of the that return by using this return true the form submit with pout getting answer.
please any one find a solution for this
function validatePlaceForm(){
var frm = document.frmOncampus;
var oncampusAddress = frm.oncampusAddress.value;
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("my_div").innerHTML=''
var result =xmlhttp.responseText;
//alert(result);
var both =result.split("|");
frm.oncampusLatitude.value=both[0];
frm.oncampusLongtitude.value=both[1];
}
}
var url='latlog.php?address='+oncampusAddress;
xmlhttp.open("GET",url,true);
xmlhttp.send();
return true;
}
Unfortunately this will never work because the way you're using the XHR there is asynchronous:
xmlhttp.open("GET",url,true); // true means asynchronous
As the call is asynchronous the result of the function will have no result on the running of the Ajax request.
If you want to continue with using this function just change this last parameter to false, i.e.
xmlhttp.open("GET", url, false); // will now be synchronous
You also won't need a onreadystatechange handler now. Bear in mind that this will obviously make the XHR call synchronous on your onchange event too; maybe customise the function to accept a flag for is_synchronous or something.
You might also want to consider adding a timestamp onto your requests so that the browser does not cache the response.
Change the return value from true to false and call this function like this:
onsubmit="return validatePlaceForm();"
This should do the trick.
Check for the response coming from AJAX. If response is blank then return false, otherwise return true.

Javascript not executing procedures correctly

I'm trying to use JavaScript to manipulate page content in a dummy webpage I'm building.
To that end, I wrote a little function called writeText(file_name, location) that gets a HTML file specified by the file name, and prints the content of that file to the innerHTML of a pair of <div> tags whose id attribute correspond to the location field.
I then wrapped the calls in other functions to automate building full pages like this.
So I call something that looks like this:
function displayHome() {
writeText('homeMain.html', 'mainFrame');
writeText('homeSide.html', 'sideFrame');
}
...to display the home page.
However, when I call this function, the display only updates the 'sideFrame' object and doesn't make any changes to the content of 'mainFrame'. But if I interrupt the function with an alert("Dummy") between the two writeText() calls, then both of the contentFrames update correctly.
I was wondering if anyone has seen anything like this before, and if anyone knows how to fix it.
For completeness' sake (this was copied nearly verbatim from the w3schools website):
function writeText(script_file, location) {
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function() {
document.getElementById(location).innerHTML = xmlhttp.responseText;
}
xmlhttp.open("GET",script_file,true);
xmlhttp.send();
}
You are using a global variable xmlhttp, so it gets clobbered the 2nd time the function runs. The request itself is asynchronous, so the second call runs while the first one is still running.
To fix this, use a local variable instead (so each call to the function has its own xmlhttp) by using the "var" keyword before xmlhttp:
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}

XMLHTTPrequest request not working

I tried the following code to send request to jsp page on a click of button. I checked on Httpfox but no request is going. I just used the whole of this code in the body of the html code. Am I doing some silly mistake. Kindly suggest..
<button type="button" onClick="handleButtonClick();">Click Me!</button>
<script type="text/javascript">
function handleButtonClick()
{
// Declare the variables we'll be using
var xmlHttp, handleRequestStateChange;
// Define the function to be called when our AJAX request's state changes:
handleRequestStateChange = function()
{
// Check to see if this state change was "request complete", and
// there was no server error (404 Not Found, 500 Server Error, etc)
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
var substring=xmlHttp.responseText;
// Do something with the text here
alert(substring);
}
}
xmlhttp = new XMLHttpRequest();
xmlHttp.open("GET", "http://csce:8080/test/index.jsp?id=c6c684d9cc99476a7e7e853d77540ceb", true);
xmlHttp.onreadystatechange = handleRequestStateChange;
xmlHttp.send(null);
}
</script>
Well, in JavaScript, variables are case-sensitive. You have xmlHttp and xmlhttp; those should be the same.
You've also got <pre><code> at the beginning of your <script> block, which is a JavaScript syntax error.
Since no request is being made, I am not convinced you can actually make requests to "http://csce:8080" as FireFox may not see that URL as being on the same subdomain (You cannot make Ajax requests for resources not on the same domain as the requestor).
Suppose you made the URL relative. Is a request even generated then? If so, that is likely your problem.
Quote: xmlhttp = new XMLHttpRequest();
Two things. First, you might want to use a more robust method of getting an XMLHttpRequest object. Second, javascript is case-sensitive; xmlhttp != xmlHttp
xmlHttp = (function (x,y,i) {
if (x) return new x();
for (i=0; i<y.length; y++) try {
return new ActiveXObject(y[i]);
} catch (e) {}
})(
window.XMLHttpRequest,
['Msxml2.XMLHTTP','Microsoft.XMLHTTP']
);
Quote: http://csce:8080/test/ind...
Keep in mind that cross-domain xmlhttp is verboten. Unless you're serving from csce:8080, that ain't gonna work.

Categories

Resources