PDA

View Full Version : AJAX working, JS functions not working


samuurai
04-06-2008, 02:08 AM
Hi Everyone,

I have a couple of problems...

I've just started playing with AJAX, I've got it to load html from the server nicely, but if those html files have javascript on them, the functions aren't working. The error is "echoecho function not defined" I'm using an alert just for testing. It works if I browse to the html file, but it doesn't if I call that html file through ajax.

Also, should I use onDomReady for ajax pages to call JS functions?

Here's my code:

<link rel="stylesheet" href="css/layout.css" type="text/css" media="screen" charset="utf-8" />
<link rel="stylesheet" href="css/jd.gallery.css" type="text/css" media="screen" charset="utf-8" />

<script type="text/javascript">
function startGallery() {
var myGallery = new gallery($('myGallery'), {
timed: false,
defaultTransition: "fadeslideleft"
});
}

window.onDomReady(startGallery);
</script>
<button type="submit" onClick="echoecho();">submit</button>
<div id="myGallery">
<div class="imageElement">
<h3>Item 1 Title</h3>
<p>Item 1 Description</p>
<a href="#" title="open image" class="open"></a>
<img src="images/brugges2006/1.jpg" class="full" />
<img src="images/brugges2006/1-mini.jpg" class="thumbnail" />
</div>
<div class="imageElement">
<h3>Item 2 Title</h3>
<p>Item 2 Description</p>
<a href="#" title="open image" class="open"></a>
<img src="images/brugges2006/2.jpg" class="full" />
<img src="images/brugges2006/2-mini.jpg" class="thumbnail" />
</div>
<div class="imageElement">
<h3>Item 3 Title</h3>
<p>Item 3 Description</p>
<a href="#" title="open image" class="open"></a>
<img src="images/brugges2006/3.jpg" class="full" />
<img src="images/brugges2006/3-mini.jpg" class="thumbnail" />
</div>
<div class="imageElement">
<h3>Item 4 Title</h3>
<p>Item 4 Description</p>
<a href="#" title="open image" class="open"></a>
<img src="images/brugges2006/4.jpg" class="full" />
<img src="images/brugges2006/4-mini.jpg" class="thumbnail" />
</div>
<div class="imageElement">
<h3>Item 5 Title</h3>
<p>Item 5 Description</p>
<a href="#" title="open image" class="open"></a>
<img src="images/brugges2006/5.jpg" class="full" />
<img src="images/brugges2006/5-mini.jpg" class="thumbnail" />
</div>
<div class="imageElement">
<h3>Item 6 Title</h3>
<p>Item 6 Description</p>
<a href="#" title="open image" class="open"></a>
<img src="images/brugges2006/6.jpg" class="full" />
<img src="images/brugges2006/6-mini.jpg" class="thumbnail" />
</div>
<div class="imageElement">
<h3>Item 7 Title</h3>
<p>Item 7 Description</p>
<a href="#" title="open image" class="open"></a>
<img src="images/brugges2006/7.jpg" class="full" />
<img src="images/brugges2006/7-mini.jpg" class="thumbnail" />
</div>
<div class="imageElement">
<h3>Item 8 Title</h3>
<p>Item 8 Description</p>
<a href="#" title="open image" class="open"></a>
<img src="images/brugges2006/8.jpg" class="full" />
<img src="images/brugges2006/8-mini.jpg" class="thumbnail" />
</div>
</div>

mjlorbet
04-06-2008, 04:08 AM
hmm, well, echoecho isn't defined in the code you posted, hence the error. the extra reason that this isn't working for you is that scripts aren't automatically imported when loading a page, for example, if you just request this page with ajax & dump it out in the innerHTML of some object, any script blocks will just be ignored. so, you can do a little leg work & search for script tags & use eval on the code between the tags (one way of doing it) and add the rest to your page. or you can use one of the other methods to dynamically load a js file with the code you want to include too. it's really up to you.

samuurai
04-06-2008, 04:17 PM
Oops, I pasted the wrong code.. I meant to include the echoecho() function. But you saw my predicament anyway, it is indeed ignoring the <script> tags. I've been looking at ways around it (being very new to JS)...

I've found this code:

function cloneInnerHTML(node, target) {

if (target) {
newNode = target;
target.innerHTML = '';
} else {
var newNode = node.cloneNode(false);
}

if (node.hasChildNodes()) {
var children = node.childNodes;
for (var i = 0; i < children.length; i++) {

var child = children[i];
if (child.tagName == 'SCRIPT') {
var newScript = document.createElement('script');
newScript.setAttribute('type', 'text/javascript');
newScript.setAttribute('id', child.getAttribute('id'));
copyScriptText(child, newScript);
newNode.appendChild(newScript);
} else {
newNode.appendChild(cloneInnerHTML(child, null));
}

}
}

return newNode;

}

tempdiv = document.createElement('div');
tempdiv.innerHTML = ajax_result; // new html fetched via an ajax call
cloneInnerHTML(tempdiv, document.getElementById('somediv'));


However, i'm not entirely sure where to integrate this code (or parts of it) into my code. Does it go in my XMLHttpRequest function?
Ideally i'd like to be able to write JS functions in the .html files i'm calling with XMLHttpRequest. What do you find is the easiest way to do that?

samuurai
04-06-2008, 04:24 PM
I'm also trying to integrate google maps api which also isn't working.
There must be an easy way around using javascript in ajax requested pages.


Here's the google api code.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Maps JavaScript API Example</title>
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAAFZVzezZVv-KIzHJQ7Y3bFBQZURgDIK-bLuHbF8MlJlu6M6ER3hQLEo4V5mLxopDKe8YRSwsilz-Vnw"
type="text/javascript"></script>
<script type="text/javascript">

//<![CDATA[

function load() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
}
}

//]]>
</script>
</head>
<body onload="load()" onunload="GUnload()">
<div id="map" style="width: 500px; height: 300px"></div>
</body>
</html>

mjlorbet
04-06-2008, 05:22 PM
hmm, the first codeblock you posted actually won't work in firefox, you'll get children is null or not an object, check the mozilla docs for the usages on childNodes in respect to html elements, you can also just take your responseText (from your readystatechange handler's final check (where the data is being processed) and do this:


var inscriptElement = false;
var tempscript = "";
var html = "";
for(var a = 0; a < a++){
if(!inscriptElement){
if(this.responseText.substr(a).indexOf('<script type="text/javascript">') == 0){
inscriptElement = true;
a += ('<script type="text/javascript">').length;
}
else
html += this.responseText.substr(a, 1);
}
else if(this.responseText.substr(a).indexOf("</script>") != 0){
tempscript += this.responseText.substr(a, 1);
}
else{
eval(tempscript);
tempscript = "";
inscriptElement = false;
a += ("</script>").length;
}
}


now keep in mind i wrote this on the fly (so test it before deploying it), but it's indended purpose is to separate script & html & add the script to the page. the html will be stored in a variable, fittingly called html, so yourElement.innerHTML = html; puts the html in your div or span or other element, the scripts will be automatically loaded.

samuurai
04-06-2008, 09:17 PM
Hi.. thanks very much for that! I learnt a lot reading your code, however i'm having trouble getting it to work... I *THINK* i've put the code into the right place:

I think it's getting the page, but it's coming up as "undefined" in the browser.

Here's my ajax.js file:


function ajaxFunction(url,id)
{
var xmlHttp;
try
{
// Firefox, Opera 8.0+, Safari
xmlHttp=new XMLHttpRequest();
}
catch (e)
{
// Internet Explorer
try
{
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
try
{
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e)
{
alert("Your browser does not support AJAX!");
return false;
}
}
}
xmlHttp.onreadystatechange=function()
{
if(xmlHttp.readyState==4)
{

var inscriptElement = false;
var tempscript = "";
var html = "";
for(var a = 0; a < a++;){
if(!inscriptElement){
if(this.responseText.substr(a).indexOf('<script type="text/javascript">') == 0){
inscriptElement = true;
a += ('<script type="text/javascript">').length;
}
else
html += this.responseText.substr(a, 1);
}
else if(this.responseText.substr(a).indexOf("</script>") != 0){
tempscript += this.responseText.substr(a, 1);
}
else{
eval(tempscript);
tempscript = "";
inscriptElement = false;
a += ("</script>").length;
}
}

//document.getElementById(id).innerHTML=null;
document.getElementById(id).innerHTML=html;
}
}
xmlHttp.open("GET",url,true);
xmlHttp.send(null);
}


I changed document.getElementById(id).innerHTML=html; instead of xmlHttp.responseText - is that right?

I've found another approach, but I really like your approach because it's much more flexible. Here's the link to the other one method: http://www.dynamicdrive.com/dynamicindex17/ajaxcontent.htm

It has a loadobjs function but requires external files.

Thanks for helping me out!

samuurai
04-06-2008, 09:29 PM
for(var a = 0; a < a++){
I think I found the problem! I think there's meant to be an extra parameter in the for statement. What should it read?

I set it to 10 and i'm now getting another issue...

this.responseText has no properties
onreadystatechange()ajax.js (line 60)
[Break on this error] if(this.responseText.substr(a).indexOf('<script type="text/javascript"...

samuurai
04-06-2008, 10:38 PM
I'm now a step closer :)

I realised this.responsText wasn't right.. for my ajax function it should've been xmlHttp.responseText. :)

Now I don't know how many times the for loop should iterate. At the moment, it's returning "<" only. If I increase the for loop to "5" I get "<link" which is the first part of the page i'm calling.

I don't know if that search will work because it will search for "<script... etc" in strings like "<" which it won't find any results in.

Is there another way of pulling out the <script> elements ?

mjlorbet
04-06-2008, 11:02 PM
this.responseText.length

note that this is correct, any reference to your request in the context of the onreadystatechange handler may (and should) be referred to as this because the function is in fact a member of the xmlhttprequest object

samuurai
04-08-2008, 11:23 PM
Thanks for your help.. I ended up using mootools Ajax function. it has an option evalScripts which works like a dream.