All,
I have a fairly simple javascript script that changes some text in my html page. The weird thing is that the data is only changed if I have an alert. If I hide the alert as a comment, the data doesn't appear on the webpage. To be specific, here are the relevant pieces of the JS code:
var index=0;
var xmlObject=null;
function calcIndex(){
return index++;
}
function showNextName(){
retrieveNextName();
var someText = xmlObject.getElementsByTagName("name")[0].childNodes[0].nodeValue;
document.getElementById('nextName').innerHTML=someText;
}
function retrieveNextName(){
var index=calcIndex();
request = createRequest();
if (request == null) {
alert("Unable to create request");
return;
}
var url= "Ajax_retrieveName.php?index=" + index;
request.open("GET", url, true);
request.onreadystatechange = createXml;
request.send(null);
alert("abc");
//If the alert above is missing, the html is not modified...
}
function createXml() {
if (request.readyState == 4) {
if (request.status == 200) {
xmlObject = request.responseXML;
}else{
return;
}
}else{
return;
}
}
Does anyone know what might be causing that?
The problem is that XML object is not immediately available, because the request isn't finished yet, so the callback hasn't been called yet. (Alerting allows the request to finish in the time before you clock the alert box away.)
A better solution would be to have an updateElementHtml(newHtml) function and call that from within the callback.
Related
I am using SimpleXMLElement() to obtain data from a website, which is used to embed data. The code I am using is as follows:
$rss = new SimpleXMLElement('http://eliteprospects.com/rss_player_stats2.php?player='.$player_array[0]['embed_stats'], null, true);
foreach($rss->xpath('channel/item') as $item)
{
echo utf8_decode($item->description);
}
This works great, except for one issue, the data loads exceptionally slow from the other site. The page load goes from approximately 0.5-1s to 2.5-3s.
Is there a method that I can use, to load the asynchronously, or is there a faster function I should be using instead?
An idea that came to mind was to load a separate page within an iFrame after the initial page load, or is there a better method?
Is there a method that I can use, to load the asynchronously, or is
there a faster function I should be using instead?
Unfortunately, there is nothing to do about the long response time (trivially assuming that connection speed in not archaic). Also echoing out the results all at once might slow down the browser rendering and thus the page load time.
AJAX fits nicely here - wait for window.onload and trigger the AJAX call to your webservice (holds the snippet from question) to prepare the output buffer and return the response to browser. Afterwards set/replace the innerHTML value of selected DOM element with the response.responseText.
Pseudo-code
window.onload = function()
{
var url = 'http://example.com/webserice';
Ajax.get(url, function(response)
{
var responseText = response.responseText;
document.getElementById('someid').innerHTML = responseText;
}
}
The snippet I am using in pure JS, although jQuery has a lot more appealing way to do it
Ajax = {
request : {},
createRequest : function()
{
var request = false;
if (window.XMLHttpRequest)
{
request = new XMLHttpRequest();
}
else
{
if (window.ActiveXObject)
{
request = new ActiveXObject('MSXML2.XMLHTTP.3.0');
}
else
{
request = false;
}
}
return request;
},
get : function(page, callback)
{
var self = this;
var request = this.createRequest();
if (! page)
{
return false;
}
request.onreadystatechange = function()
{
if (request.readyState == 4 && request.status == 200)
{
delete self.request;
if (typeof callback == 'function')
{
callback(request);
}
else
{
self.update(request, callback);
}
var regex = /<script\b.*?>([\s\S]*?)<\/scri/ig;
var match;
while (match = regex.exec(request.responseText))
{
eval(match[1]);
}
}
}
request.open('GET', page, true);
request.setRequestHeader('X-Requested-With', 'ajax');
request.send(null);
}
}
Please read below my scenario…
I have a PHP file wherein I have javascript within it..
<?php
echo ‘<script>’;
echo ‘window.alert(“hi”)’;
echo ‘</script>’;
?>
On execution of this file directly, the content inside the script is executed as expected. But if this same page is being called via ajax from another page, the script part is NOT executed.
Can you please let me know the possible reasons.
(note: I’m in a compulsion to have script within php page).
When you do an AJAX call you just grab the content from that page. JavaScript treats it as a string (not code). You would have to add the content from the page to your DOM in your AJAX callback.
$.get('/alertscript.php', {}, function(results){
$("html").append(results);
});
Make sure you change the code to fit your needs. I'm supposing you use jQuery...
Edited version
load('/alertscript.php', function(xhr) {
var result = xhr.responseText;
// Execute the code
eval( result );
});
function load(url, callback) {
var xhr;
if(typeof XMLHttpRequest !== 'undefined') xhr = new XMLHttpRequest();
else {
var versions = ["MSXML2.XmlHttp.5.0",
"MSXML2.XmlHttp.4.0",
"MSXML2.XmlHttp.3.0",
"MSXML2.XmlHttp.2.0",
"Microsoft.XmlHttp"]
for(var i = 0, len = versions.length; i < len; i++) {
try {
xhr = new ActiveXObject(versions[i]);
break;
}
catch(e){}
} // end for
}
xhr.onreadystatechange = ensureReadiness;
function ensureReadiness() {
if(xhr.readyState < 4) {
return;
}
if(xhr.status !== 200) {
return;
}
// all is well
if(xhr.readyState === 4) {
callback(xhr);
}
}
xhr.open('GET', url, true);
xhr.send('');
}
I have an input field for a concept and when the user fills it out, he has to then check if the concept exists. So I made a check button, which checks a database using ajax and JavaScript to see if the concept exists. My problem is when using ajax and JavaScript I get this exception:
unexpected end of input
JS :
var concept = document.getElementById('acConceptName').value;
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange=function(){
if(xmlhttp.readyState==4 && xmlhttp.status==200){
var isexisted = JSON.parse(xmlhttp.responseText);
if(isexisted[0]==true){
var errorMessage = document.getElementById('acSuggesConcepts');
var p = document.createElement('p');
p.innerHTML="this concept is already existed";
errorMessage.appendChild(p);
errorMessage.style.display="block";
}
}
}
xmlhttp.open("GET","http://localhost/Mar7ba/Ontology/isExistedConcept/"+concept+"/TRUE",true);
xmlhttp.send();
What is the exception and how can I solve it ?
PHP : function to check database and I always return true in it
public function isExistedConcept($concpetName,$Ajax){
if($Ajax==true){
$results=true
$d=array($results);
return json_encode($d);
}
}
Demo: http://jsfiddle.net/Wiliam_Kinaan/s7Srx/2/
After looking at the code for a while, one thing that might be a suspect is your PHP.
Your function in php ends with a return command. What the AJAX call is actually waiting for is some data to be sent back. The return command simply passes that value back to the entity that originally called the function.
Try alter your function to echo the result as opposed to returning it. Save your return value for when you need the result to go into another PHP function, not when you are returning data to the client.
I only put this return command here for readability.
public function isExistedConcept($concpetName,$Ajax){
if($Ajax==true){
$results=true
$d=array($results);
echo json_encode($d);
}
return;
}
Try this:
public function isExistedConcept($concpetName,$Ajax) {
if( $Ajax) return "1";
}
// This is a simplified version of what you're doing, but it returns "1" instead of "[true]"
// Now for the JS:
if( xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var isexisted = xmlhttp.responseText == "1";
if( isexisted) {...}
If that doesn't work, try adding alert(xmlhttp.responseText) and see if you're getting anything other than what should be there.
try this :
var concept = document.getElementById('acConceptName').value;
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET","http://localhost/Mar7ba/Ontology/isExistedConcept/"+concept+"/TRUE",true);
xmlhttp.onreadystatechange=function(){
if(xmlhttp.readyState==4){
if(xmlhttp.status==200){
var isexisted = JSON.parse(xmlhttp.responseText);
if(isexisted[0]==true){
var errorMessage = document.getElementById('acSuggesConcepts');
var p = document.createElement('p');
p.innerHTML="this concept is already existed";
errorMessage.appendChild(p);
errorMessage.style.display="block";
}
else{
console.log('error');
}
}
}
}
xmlhttp.send(null);
im trying to get a bit of html to refresh every 1 second with AJAX, I made this code my self with bits from different websites that I found. Im trying to understand how it all works.
I want to be able to refresh the page without reloading it in the browser and I want the JS function AJAXdisplay(); to run every one second with the variables I send to AJAXreturn(); when I call it.
When I call AJAXreturn(); I want it to run AJAXdisplay(); once to print out the html from my php file, on my body if the index file I want somthing like this
<body onClick=:AJAXdisplay(same variables as used when the page was made);">
</body>
here is my code:
function getHTTPObject(){
if (window.ActiveXObject) {
return new ActiveXObject("Microsoft.XMLHTTP");
}
if (window.XMLHttpRequest){
return new XMLHttpRequest();
}
else {
alert("Your browser does not support AJAX.");
return null;
}
}
function AJAXsend(url) {
httpObject = getHTTPObject();
if (httpObject != null) {
httpObject.open("POST",url);
httpObject.send(null);
}
}
function AJAXreturn(url,pageName){
httpObject = getHTTPObject();
if (httpObject != null) {
if (navigator.appName != "Microsoft Internet Explorer") {
history.replaceState("", "", "index.php?page=" + pageName)
}
httpObject.open("POST",url);
httpObject.send(null);
AJAXdisplay(httpObject,url,pageName);
}
}
function AJAXdisplay(httpObjectIn,urlIn, pageNameIn){
httpObjectIn.onreadystatechange = function(){
if(httpObjectIn.readyState == 4){
document.getElementById('outputHTML').innerHTML = httpObjectIn.responseText;
AJAXdisplay('function(httpObjectIn,urlIn,pageNameIn)',1000);
}
}
}
To make javascript refresh, you should use the setInterval(); function. Here's what your looking for:
var timer = setInterval ("AJAXdisplay(variable);", 1000);
And if you ever need to stop the refresh you use:
clearInterval (timer);
I have a little script which uses AJAX and PHP to display an image. You can see below that if I call the function mom() it looks in the PHP file index.php?i=mom and displays the image I'm looking for.
But I need the javascript to be lighter as I have 30 images and for each one I have to modify and copy the script below. Is there not a simpler way to have the functions be different and still call a different page?
<script type="text/javascript">
function mom()
{
var xmlHttp = getXMLHttp();
xmlHttp.onreadystatechange = function()
{
if(xmlHttp.readyState == 4)
{
HandleResponse(xmlHttp.responseText);
}
}
xmlHttp.open("GET", "index.php?i=mom", true);
xmlHttp.send(null);
}
function HandleResponse(response)
{
document.getElementById('mom').innerHTML = response;
}
</script>
My Trigger is this
<a href="#" onclick='mom();' />Mom</a>
<div id='mom'></div>
You could modify your function so it takes a parameter :
// The function receives the value it should pass to the server
function my_func(param)
{
var xmlHttp = getXMLHttp();
xmlHttp.onreadystatechange = function()
{
if(xmlHttp.readyState == 4)
{
// Pass the received value to the handler
HandleResponse(param, xmlHttp.responseText);
}
}
// Send to the server the value that was passed as a parameter
xmlHttp.open("GET", "index.php?i=" + param, true);
xmlHttp.send(null);
}
And, of course, use that parameter in the second function :
function HandleResponse(param, response)
{
// The handler gets the param too -- and, so, knows where to inject the response
document.getElementById(param).innerHTML = response;
}
And modify your HTML so the function is called with the right parameter :
<!-- for this first call, you'll want the function to work on 'mom' -->
<a href="#" onclick="my_func('mom');" />Mom</a>
<div id='mom'></div>
<!-- for this secondcall, you'll want the function to work on 'blah' -->
<a href="#" onclick="my_func('blah');" />Blah</a>
<div id='blah'></div>
This should work (if I understand correctly)
<script type="text/javascript">
function func(imgName)
{
var xmlHttp = getXMLHttp();
xmlHttp.onreadystatechange = function()
{
if(xmlHttp.readyState == 4)
{
document.getElementById(imgName).innerHTML =
}
}
xmlHttp.open("GET", "index.php?i=mom", true);
xmlHttp.send(null);
}
</script>
MARTIN's solution will work perfectly.
By the way you should use some javascript framework for Ajax handling like jQuery.
It will make your life easy.
If you are having light weight images you preload the images on your page.
I solved this by making an array of in your case xmlHttp and a global variable, so it increments for each request. Then if you repeatedly make calls to the same thing (eg it returns online users, or, whatever) then you can actually resubmit using the same element of the array too.
Added example code:
To convert it to a reoccuring event, make a copy of these 2, and in the got data call, just resubmit using reget
var req_fifo=Array();
var eleID=Array();
var i=0;
function GetAsyncData(myid,url) {
eleID[i]=myid;
if (window.XMLHttpRequest)
{
req_fifo[i] = new XMLHttpRequest();
}
else if (window.ActiveXObject)
{
req_fifo[i] = new ActiveXObject("Microsoft.XMLHTTP");
}
req_fifo[i].abort();
req_fifo[i].onreadystatechange = function(index){ return function() { GotAsyncData(index); }; }(i);
req_fifo[i].open("GET", url, true);
req_fifo[i].send(null);
i++;
}
function GotAsyncData(id) {
if (req_fifo[id].readyState != 4 || req_fifo[id].status != 200) {
return;
}
document.getElementById(eleID[id]).innerHTML=
req_fifo[id].responseText;
req_fifo[id]=null;
eleID[id]=null;
return;
}
function reget(id) {
myid=eleID[id];
url=urlID[id];
req_fifo[id].abort();
req_fifo[id].onreadystatechange = function(index){ return function() { GotAsyncData(index); }; }(id);
req_fifo[id].open("GET", url, true);
req_fifo[id].send(null);
}
The suggestions to parameterize your function are correct and would allow you to avoid repeating code.
the jQuery library is also worth considering. http://jquery.com
If you use jQuery, each ajax call would literally be this easy.
$('#mom').load('/index.php?i=mom');
And you could wrap it up as follows if you'd like, since you say you'll be using it many times (and that you want it done when a link is clicked)
function doAjax(imgForAjax) { $('#'+imgForAjax).load('/index.php&i='+imgForAjax);}
doAjax('mom');
It makes the oft-repeated ajax patterns much simpler, and handles the issues between different browsers just as I presume your getXMLhttp function does.
At the website I linked above you can download the library's single 29kb file so you can use it on your pages with a simple <script src='jquery.min.js'></script> There is also a lot of great documentaiton. jQuery is pretty popular and you'll see it has a lot of questions and stuff on SO. ajax is just one of many things that jQuery library/framework (idk the preferred term) can help with.