I am new to JavaScript and trying to play with some Ajax to dynamically load HTML into a <div> element. I have a PHP page that spits out a JSON with the HTML needed to insert into the <div>. I have been testing and cannot get the call to work. I started to do alerts on my readystate, and I get 0 and then nothing else. From my understanding, the function sendData() should be called every time the readystate changes, but it appears to only do it once, or the readystate never changes, so it only gets called once...?
This is my PHP
<?php
$array['html'] = '<p>hello, menu here</p>';
header('Content-type: application/json');
echo json_encode($array);
?>
This is my HTML
<!DOCTYPE html>
<html>
<head>
<title>Veolia Water - Solutions and Technologies Dashboard</title>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<meta name="description" content="Veolia Water - Dashboard"/>
<meta http-equiv="imagetoolbar" content="no" />
<meta author="Nathan Sizemore"/>
<link rel="stylesheet" href="./css/stylo.css" media="screen"/>
</head>
<body>
<div id="menu">
</div>
<div id="content">
</div>
</body>
<script src="./js/dashboard.js"></script>
</html>
This is my JavaScript
var request;
window.onload = function()
{
load_menu();
}
//Load menu function
function load_menu()
{
request = getHTTPObject();
alert(request.readyState);
request.onreadystatechange = sendData();
request.open("GET", "./php/menu.php", true);
request.send(null);
}
function getHTTPObject()
{
var xhr = false;
if (window.XMLHttpRequest)
{
xhr = new XMLHttpRequest();
}
else if (window.ActiveXObject)
{
try
{
xhr = new ActiveXObject("Msxml2.XMLHTTP");
}
catch(e)
{
try
{
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(e)
{
xhr = false;
}
}
}
return xhr;
}
function sendData()
{
alert(request.readyState);
// if request object received response
if (request.readyState == 4)
{
var json = JSON.parse(request.responseText);
document.getElementById('menu').innerHTML = json.html;
alert(json.html);
}
}
Thanks in advance for any help!
Nathan
Use this:
request.onreadystatechange = sendData;
Note that the () are removed from sendData()
What you had before was immediately executing sendData and returning its result to onreadystatechange. Since nothing is actually returned, the value is undefined. It wasn't actually setting anything to onreadystatechange and therefore not actually executing anything when the state changes. The onreadystatechange property expects a reference to a function...which is exactly what sendData is.
In your code, since sendData was executed once (accidentally), the state reported is 0 (the XHR's initial state).
Change this line
request.onreadystatechange = sendData();
To this
request.onreadystatechange = sendData;
The first code calls sendData and assigns the result as the handler.
The second one assigns the function itself.
request.onreadystatechange = sendData();
should be
request.onreadystatechange = sendData;
You're calling sendData immediately and using the result of that function as the listener, rather than using the function itself.
Related
I am trying a simple ajax call. The test.php is just echoing some text. But the ajax call always returns readyState 1 and status 0. Here is the piece of code which I am using for ajax call.
<html>
<head>
<script>
function showData()
{
var xhr;
if(window.XMLHttpRequest)
{
xhr = new XMLHttpRequest();
}
else
{
xhr = new ActiveXObject(Microsoft.XMLHTTP);
}
xhr.onreadystatechange = function(){
if(xhr.readyState==4 && xhr.status==200)
{
document.getElementById('data').innerHTML = xhr.responseText;
}
else
{
var content = document.getElementById('data').innerHTML;
document.getElementById('data').innerHTML = content + 'ERROR with ready state '+xhr.readyState+' and status of '+xhr.status+'<br>';
}
}
xhr.open('GET','test.php',true);
send(null);
}
</script>
</head>
<body>
<input type="submit" value="Get Data" onClick="showData()" />
<span id="data" ></span>
</body>
</html>
Thank you in anticipation.
You'd have to call the xhr.send() method.
xhr.send();
A readyState of 1 means that the xhr request is just set up, since you have xhr.open(). If the xhr.send() is called, then the other states come into play.
I am having problems with a really basic request to a php file from AJAX. I am running all this stuff through XAMPP. What I'm trying to do with this code is to echo the name typed into the textbox once the submit button is clicked and the results to be posted in the div "results". I am doing this to try and weed out errors in another script and so far it hasn't gone too well.
<html>
<head>
<script type="text/javascript">
function go() {
var request;
if(window.XMLHttpRequest) {
request = new XMLHttpRequest();
}
else {
request = new ActiveXObject("Microsoft.XMLHTTP");
}
var uname = document.getElementById("name").value;
request.onreadystatechange= function() {
if(request.readyState == 4) {
document.getElementById("result").innerHTML = response.Text;
}
}
url = "win.php?name="+uname;
request.open("GET", url, true);
request.send();
}
</script>
</head>
<body>
Name:<input type="textbox" name="jesus" id="name" />
<input type="button" value="Submit" onlick="go()" />
<div id ="result"> Result:</div>
</body>
</html>
<?php
$name = $_GET['name'];
echo $name;
?>
You don't have an object called response, you are looking for the responseText property on the request object.
document.getElementById("result").innerHTML = request.responseText;
Also:
avoid using globals
don't send your HTTP request before the target div exists, you run the risk of it still not existing when the response comes back
you probably should check that the HTTP status of the response is 200 (OK) as well as being finished (readyState 4).
Don't put raw user input in URLs, escape it with encodeURIComponent first
Use that
document.getElementById("result").innerHTML = response.responseText;
This question may have been asked a million times in the past but I am yet to come across a solution. So I ask again, hoping a less
aggressive answer like "Look somewhere else" or "Don't repeat
questions". If the reader feels the urge to type any of or similar to
the aforementioned sentences, I can only request the reader to refrain
from doing so and ignore this post completely. Any help is greatly
appreciated.
The problem
In my program, an AJAX script works to communicate with a PHP script. There are no syntax errors. The AJAX receives the responseText well and alerts it out.
alert(request.responseText); //this works as desired
But fails to return it to another function.
return(request.responseText); //this actually returns undefined
The full code
Client file
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>test</title>
<script type="text/javascript" language="javascript" src="ajax.js"></script>
<script type="text/javascript" language="javascript">
function createXMLHttp()
{
var xmlHttp = null;
if(window.XMLHttpRequest)
{
xmlHttp = new XMLHttpRequest();
}
else if(window.ActiveXObject)
{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
return xmlHttp;
}
function ajax_phprequest(data, php_file)
{
var request = createXMLHttp();
request.open("POST", php_file, true);
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.send(data);
request.onreadystatechange = function()
{
if (request.readyState == 4)
{
document.write(request.responseText);
return request.responseText; //changed from return(request.responseText;);
}
}
}
function foo()
{
alert(ajax_phprequest("user=defuser&pass=123456","auth.php"));
}
</script>
</head>
<input type="button" id="somebutton" value="Call foo()" onclick="foo();" />
<body>
</body>
</html>
The full code
auth.php file
<?php
$user;
$pass;
if (isset($_POST['user'])) $user = $_POST['user'];
else
{
echo 'err_u_Username is not specified';
exit();
}
if (isset($_POST['pass'])) $pass = $_POST['pass'];
else
{
echo 'err_p_Password is not specified';
exit();
}
if ($user = 'defuser' && $pass = '123456') echo ('That\'s right!');
else echo ('That\'s not right!');
?>
This can easily be solved by including the code in the same file as the document. But I wish to call the function from a different file and then return it to the file that has foo() or the document. Simply, I want the AJAX function to return the responseText without it giving an `undefined' every time. If this has anything to do with synchronization: I want to know of any workarounds against this problem.
The gist of it has already been mentioned, but I would like to go into a bit more depth as to why this doesn't work.
You have the following code:
request.onreadystatechange = function()
{
if (request.readyState == 4)
{
document.write(request.responseText);
return(request.responseText);
}
}
Basically, you are setting the onreadystatechange event to the value of an anonymous function. In that anonymous function, you are returning a value, which won't be returned to the caller of ajax_phprequest(), but to the caller of the anonymous function, which is the event system and which doesn't care much about what value is returned.
This happens this way because it all happens asynchronously. In other words, you call ajax_phprequest() and all that happens at that moment happens behind the screens. The user can continue working like nothing has happened. However, in the background, the php file is requested and hopefully returned. When that happens, you get to use the contents, but the moment at which you called ajax_phprequest() has long since passed.
A proper way would be to use a callback function instead. It could look something like this:
function ajax_phprequest(data, php_file, callback)
{
var request = createXMLHttp();
request.open("POST", php_file, true);
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.send(data);
request.onreadystatechange = function()
{
if (request.readyState == 4)
{
document.write(request.responseText);
callback(request.responseText);
}
}
}
function foo()
{
ajax_phprequest("user=defuser&pass=123456","auth.php", function (text)
{
alert(text);
});
}
That is because the call is ASYNCHRONOUS so you cannot return from stack the usual way, i.e. your alert(ajax_phprequest("user=defuser&pass=123456","auth.php")); is evaluated before the ajax response is returned ... you need to use a callback:
function callback( text ){
// something
}
...
if (request.readyState == 4){
callback( request.responseText );
}
I'm creating a link-sharing website and on my index.php page (the page I want to refresh every 5 seconds) there are posts/links that must appear automatically (AJAX refreshing) without the user to refresh by him/herself or pressing F5 the whole time.
How would this work, precisely?
You should use the setInterval javascript function to deal with this issue.
setInterval(callServer, REFRESH_PERIOD_MILLIS);
See:
some info on ajax Periodic Refresh
javascript setInterval documentation
[edit] some good refresh examples, especially without js framework (depending wether you want to use jquery, mototools, another or no framework...)
you have to user the setInterval method to call your ajax function to inject new content into your div:
<HTML>
<HEAD>
<TITLE>Hello World Page</TITLE>
<script language="JavaScript">
function xmlhttpPost(strURL) {
var xmlHttpReq = false;
// Mozilla/Safari
if (window.XMLHttpRequest) {
xmlHttpReq = new XMLHttpRequest();
if (xmlHttpReq.overrideMimeType) {
xmlHttpReq.overrideMimeType('text/xml');
// See note below about this line
}
// IE
} else if (window.ActiveXObject) { // IE
try {
xmlHttpReq = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
if (!xmlHttpReq) {
alert('ERROR AJAX:( Cannot create an XMLHTTP instance');
return false;
}
xmlHttpReq.open('GET', strURL, true);
xmlHttpReq.setRequestHeader('Content-Type',
'application/x-www-form-urlencoded');
xmlHttpReq.onreadystatechange = function() {
callBackFunction(xmlHttpReq);
};
xmlHttpReq.send("");
}
function callBackFunction(http_request) {
if (http_request.readyState == 4) {
if (http_request.status == 200) {
var responceString = http_request.responseText;
//TODO implement your function e.g.
document.getElementById("myDiv").InnerHTML+ = (responceString);
} else {
alert('ERROR: AJAX request status = ' + http_request.status);
}
}
}
setInterval("xmlhttpPost('test.php')", 5000);
</script>
</HEAD>
<BODY>
Hello World
<div id="myDiv"></div>
</BODY>
</HTML>
Is there a need to use AJAX?
Unless I'm missing something; you could use the meta refresh tag:
<meta http-equiv="refresh" content="5">
I would recommend increasing the time between refreshes as this will put a heavier load on the server and may cause to freeze, or slow down the site.
Use setInterval(myAjaxCallbackfunction,[time in ms]).
Callback uses property of js that function are first class members(can be assigned to variables), and can be passed as argument to function for later use.
I have a php page that needs to be refreshed every 5 secs. On embedding the ajax file, I don't find the updates taking place in Firebug. Here is the skeleton of the code:
**notification.php**
<?php
....
....
?>
<html>
<head>
<script src="./refresh.js"></script>
<script type="text/javascript">
refreshContents();
</script>
</head>
<body>
....
<div id="identifier">
<p>Waiting area</p>
</div>
</body>
</html>
**refresh.js**
var seconds = 5;
var content = "identifier";
var url = "notification.php";
function refreshContents()
{
var xmlHttp;
try
{
xmlHttp = new XMLHttpRequest();
}
catch(e)
{
try
{
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch(f)
{
try
{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(g)
{
alert("Browser not supports Ajax");
return false;
}
}
}
xmlHttp.onreadystatechange=function()
{
if (xmlHttp.readyState == 4)
{
document.getElementById(content).innerHTML = xmlHttp.responseText;
setTimeout('refreshContents()', seconds*1000);
}
}
xmlHttp.open("GET", url, true);
xmlHttp.send(null);
}
var seconds = 5;
window.onload = function startrefresh(){
setTimeout('refreshContents()', seconds*1000);
}
Though it may not be the ideal solution, jQuery has a pretty simple way of implementing exactly this:
$(document).ready(function () {
function reload() {
$("#content").load("notification.php");
}
setTimeOut(reload, seconds*1000)
}
I'm not sure that will work perfectly, haven't done it in a little while, but its a much more elegant solution I do believe.
Why not just put a <meta http-equiv="refresh" content="5"> tag into your <head>? It will refresh the page every 5 seconds without the need for any javascript.
see the following example :
<html>
<head>
<title>Refresh a page in jQuery</title>
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
</head>
<body>
<button id="PageRefresh">Refresh a Page in jQuery</button>
<script type="text/javascript">
$('#PageRefresh').click(function() {
location.reload();
});
</script>
</body>
</html>
this code definetly help you.
or we can use -
<meta http-equiv="refresh" content="5">