PDA

View Full Version : Ajaxed tabs



Narfix
05-23-2006, 11:36 AM
Hello !

I've been using with the script of the dymanic tab contents http://www.dynamicdrive.com/dynamicindex17/ajaxtabscontent/

Each of my tabs have their own js with tons of scripts in it.
I've modified the script to suit my needs so that it unloads every loaded script whenever I change tabs.
This works just nice so far.

But... in each of the js, there's a startup function that initialize various contents.
Thing is the first time you enter in the tab, it works perfect. But if you leave the tab, then come back again, the init function is not called anymore. :confused:

I call the init function with a call outside of any other functions.

Any idea ?

Thx !

jscheuer1
05-23-2006, 06:25 PM
The way ajaxtabs works is to incorporate the code from the body of the external page into the 'top' page. It becomes then, just one page. If your script is included there, or ready to be used in some other fashion, just run it after the content from the external page is loaded into the 'top' page.

One way would be to add a poll function testing for an element that will be loaded with the external content to the link that adds that content, when that element exists have the polling function exit and run the function from your script appropriate to the added content.

ddadmin
05-23-2006, 09:19 PM
John is right, any included .js/.css files is only done once, the first time you click on the tab. Otherwise, if the user clicks on the tab multiple times, you're essentially adding multiple copies of these external files to your page, which can bog things down.

If you want to temporarily disable this behavior so the external files are added everytime, locate the line:


loadedobjects+=file+" " //Remember this object as being already added to page

inside ajaxtabs.js, and change it to:


loadedobjects="" //Remember this object as being already added to page

Narfix
05-24-2006, 07:56 AM
This is how I do it.
curjs is used to keep track of which js I included last.
When I load a new tab, I remove the script from the head and load the new one but it will only execute the first time.
The code is included in the top page, not in the ones I load afterwards.


function loadobjs(file){
if (!document.getElementById) return;
var fileref="";

if (file.indexOf(".js")!=-1) {
fileref=document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", file);
fileref.setAttribute("id","curjs");

var old = document.getElementById('curjs');
if (old) {document.getElementsByTagName("head").item(0).removeChild(old);}

// alert(file + ' added.');
document.getElementsByTagName("head").item(0).appendChild(fileref);
}
}

jscheuer1
05-24-2006, 04:35 PM
Is this your solution or just more explanation of the problem?

I just tested your updated loadobjs() function and it works fine with a simple external script that runs an alert. So, either it is your solution, or the problem is likely with your external script. If you are still having problems, we would need to see a demo page:

Please post a link to the page on your site that contains the problematic script so we can check it out.

Or at the very least, your external script.

Narfix
05-29-2006, 07:40 AM
sorry for the late reply.. long weekend :)

I cannot post a link to the website since it's not publically available.. sorry

on top of each asp page I load, I've put :


<%
response.expires = 0
response.expiresabsolute = Now() - 1
response.addHeader "pragma","no-cache"
response.addHeader "cache-control","private"
response.ContentType="text/html"
response.Charset="ISO-8859-1"
%>

but that only only applies on the asp page I presume.

my jscript are built the following :

var agmCiv;
var agmNom;
var agmNomJF;
var agmPnom;
var agmPic;
var agmEmail;
var agmLogin;
var agmOrg;
var agmMat;
var agmFic;
var agmSup;

function cacheDOM() {
alert('Start caching');
agmNom = de('txtNom');
agmNomJF = de('txtNomJF');
agmPnom = de('txtPre');
agmPic = de('txtPic');
agmEmail = de('txtEml');
agmLogin = de('txtLog');
agmOrg = de('txtOrg');
agmMat = de('txtMat');
alert('Done caching');

}

function node(x,n,d) {
if(x.item(n).childNodes.item(0)!=null) {
return x.item(n).childNodes.item(0).nodeValue;
} else {
return d;
}
}

function agmDisplayAgent() {
if(http.readyState == 4) {
if(http.responseText.substr(0,1) == "<") {
var oXML = http.responseXML;
var oRoot = oXML.documentElement.childNodes.item(0).childNodes;
alert(node(oRoot, 0));
agmNom.value = node(oRoot,1);
throbber(false);
}
}
}

function jsinit() {
// correctPNG();
alert('jsinit');
cacheDOM();
url = "/ag/ag.asp?p=2&uti=" + Uti();
http.open('GET', url, true);
http.onreadystatechange = agmDisplayAgent;
throbber(true);
http.send(null);
}

jsinit();

On the first load of the page, I get the 3 alerts on the cacheDom function and in the jsinit. When I exit it and come back, I don't have any of them anymore.
Some of the functions there are declared in the top js.

jscheuer1
05-29-2006, 09:03 AM
OK, I had to rewrite your script a bit because it either is incomplete or relies on other loaded code that you did not supply, I changed it to this:


function de(txt){
return txt
}

var agmCiv;
var agmNom;
var agmNomJF;
var agmPnom;
var agmPic;
var agmEmail;
var agmLogin;
var agmOrg;
var agmMat;
var agmFic;
var agmSup;

function cacheDOM() {
alert('Start caching');
agmNom = de('txtNom');
agmNomJF = de('txtNomJF');
agmPnom = de('txtPre');
agmPic = de('txtPic');
agmEmail = de('txtEml');
agmLogin = de('txtLog');
agmOrg = de('txtOrg');
agmMat = de('txtMat');
alert('Done caching');

}

function node(x,n,d) {
if(x.item(n).childNodes.item(0)!=null) {
return x.item(n).childNodes.item(0).nodeValue;
} else {
return d;
}
}

function agmDisplayAgent() {
if(http.readyState == 4) {
if(http.responseText.substr(0,1) == "<") {
var oXML = http.responseXML;
var oRoot = oXML.documentElement.childNodes.item(0).childNodes;
alert(node(oRoot, 0));
agmNom.value = node(oRoot,1);
throbber(false);
}
}
}

function jsinit() {
// correctPNG();
alert('jsinit');
cacheDOM();
/* url = "/ag/ag.asp?p=2&uti=" + Uti();
http.open('GET', url, true);
http.onreadystatechange = agmDisplayAgent;
throbber(true);
http.send(null);*/
}

jsinit();

I also, tried out your 'solution' from the previous post some more and it produced errors in FF and wouldn't work at all there, even though it still worked in IE for the simple alert as mentioned before. This seemed to indicate a problem with it. So, I got rid of it and wrote this updated loadobjs() function (additions red):


function loadobjs(revattribute){
if (revattribute!=null && revattribute!=""){ //if "rev" attribute is defined (load external .js or .css files)
var objectlist=revattribute.split(/\s*,\s*/) //split the files and store as array
for (var i=0; i<objectlist.length; i++){
var file=objectlist[i]
var fileref=""
if (loadedobjects.indexOf(file)!==-1&&file.indexOf(".js")!=-1){
var scripts=document.getElementsByTagName('script')
for (var i_tem = 0; i_tem < scripts.length; i_tem++)
if (scripts[i_tem].src==file)
scripts[i_tem].parentNode.removeChild(scripts[i_tem])
var re=file+' '
loadedobjects=loadedobjects.replace(re, '')
}
if (loadedobjects.indexOf(file)==-1){ //Check to see if this object has not already been added to page before proceeding
if (file.indexOf(".js")!=-1){ //If object is a js file
fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", file);
}
else if (file.indexOf(".css")!=-1){ //If object is a css file
fileref=document.createElement("link")
fileref.setAttribute("rel", "stylesheet");
fileref.setAttribute("type", "text/css");
fileref.setAttribute("href", file);
}
}
if (fileref!=""){
document.getElementsByTagName("head").item(0).appendChild(fileref)
loadedobjects+=file+" " //Remember this object as being already added to page
}
}
}
}

Basically, this will remove any previously loaded script and reload it at the time it is requested, as if it had never been loaded. Except, of course, if it had altered any global variables the other time(s) it ran, those may still be in the state it left them in.

Using your method, I was having the same problem you were, with the above version, all three alerts fired each time. If you are still having problems, it is because your external script has errors. I'd use FF's javascript console to track them down, its output is much clearer (usually) than IE's error messages.

Narfix
05-29-2006, 11:46 AM
Oh my !! It works like a charm now !!
Thanks a lot for your help !


By the way it wasn't a solution, just what I was using. I don't need the load any css just a jscript.

Narfix
05-31-2006, 01:02 PM
Just a little info for anybody who read this thread and using the original script or a modified one.

If you execute something at the jscript load, you shall not load your jscript at the same time you send your request as in the originals script. You have to wait for the page to complete loading before loading the jscript.

I had numerous errors with unknown objects.
The script was already trying to run things but the page just wasn't there yet.

To make it clearer, you should load the script in the loadpage. The somewhat code :


function loadpage(page_request, containerid){
if (page_request.readyState == 4 && (page_request.status==200 || window.location.href.indexOf("http")==-1))
document.getElementById(containerid).innerHTML=page_request.responseText
loadobj(objtobeloaded);
}

jscheuer1
05-31-2006, 04:59 PM
That's right, Narfix. As I originaly stated:


One way would be to add a poll function testing for an element that will be loaded with the external content to the link that adds that content, when that element exists have the polling function exit and run the function from your script appropriate to the added content.

With that approach, the script only needs to be loaded once and could even be hard coded (without its 'run command', jsinit() in your example, being executed) onto the 'top' page. An example of a poll is:


function pollContent(){
if (!document.getElementById)
return;
if (document.getElementById('someID'))
jsinit();
else
setTimeout("pollContent()",200)
}

where jsinit() is the function you want to run and someID is the unique id of some element in the loading content, best near the end of the loading content. This could be run at the same time you run ajaxpage or ajaxtabs or whatever ajax content loading script one is using, ex using ajaxtabs:


<a href="external.htm" rel="contentarea" onclick="pollContent();return true;">DHTML</a>

nelsontimken
05-31-2006, 05:12 PM
Has anyone noticed that the borders surrounding the tabbed content often disappear when the content is placed on your site?

Example:

http://www.protestantlawyersny.org/application.htm

Im wondering why this happens.

jscheuer1
05-31-2006, 05:29 PM
Has anyone noticed that the borders surrounding the tabbed content often disappear when the content is placed on your site?

Example:

http://www.protestantlawyersny.org/application.htm

Im wondering why this happens.

I've tried your page in three different browsers and do not see any problem with borders. BTW, when starting a new question, please start a new thread.

nelsontimken
05-31-2006, 05:32 PM
Sorry about the thread.

The borders surrounding the perimeter of the tabbed content are not showing for me.

jscheuer1
05-31-2006, 05:34 PM
How can I duplicate/see this problem? What browser are you using? What type of computer?

nelsontimken
05-31-2006, 05:41 PM
I'm using Internet Explorer 7 on a Dell PC -


I see no borders around the tabs or the content on the page:

http://www.protestantlawyersny.org/application.htm

I wish I could attach a screen shot but I cant.

jscheuer1
05-31-2006, 06:59 PM
Until the official release of IE7, best to use v6. Once the official release is made (not the current beta) if the problem persists, there will be ways of dealing with it. Until then, it is silly to redesign for a beta browser, instead report it as a bug to the beta developers.

Most likely the beta is using a more standards compliant way of rendering your border that you may have already incorporated a workaround for IE6 that v7 is now erroneously following. Whatever the cause, until v7 is out of beta release, it is a bug in the beta release. And, if not due to the above reason, should be corrected by the developers and might be even if the above is the cause. Developers cannot correct for problems that they are unaware of so, in any case, it should be reported to MS.

Narfix
06-02-2006, 07:46 AM
That's right, Narfix. As I originaly stated:



With that approach, the script only needs to be loaded once and could even be hard coded (without its 'run command', jsinit() in your example, being executed) onto the 'top' page. An example of a poll is:


Sorry at that time I didn't get what you meant. Afterwards I did. :o

I prefer moving the load of the js in the loadpage but it's just a matter of personnal preference in the code. ( and since I don't have a common ID on all my loaded pages so testing for one would be tricky)

Thanks a lot for the help you provided !

jscheuer1
06-02-2006, 08:10 AM
Sorry at that time I didn't get what you meant. Afterwards I did. :o

I prefer moving the load of the js in the loadpage but it's just a matter of personnal preference in the code. ( and since I don't have a common ID on all my loaded pages so testing for one would be tricky)

Thanks a lot for the help you provided !

You're welcome. No need to be sorry, there is so much to all of this and I don't think anyone gets it all the first time. And there are various ways to do most things, it is, as you say, a matter of preference, as long as the method you choose works. A variation on the poll that might be good for the situation you are talking about is to use the the content loading function of ajaxtabs itself to tell you when the content is loaded and then run your script, something like from ajaxtabs.js (additions red):


page_request.onreadystatechange=function(){
loadpage(page_request, containerid, url)

and:


function loadpage(page_request, containerid, url){
if (page_request.readyState == 4 && (page_request.status==200 || window.location.href.indexOf("http")==-1)) {
document.getElementById(containerid).innerHTML=page_request.responseText
if (url=='page.htm')
jsinit();
}
}

Where page.htm is the page with the content on it that we want to run the function jsinit() on. If there is more than one page, they could all be included through a check of a common fragment of their filename:


if (url.indexOf('pagenamefragment')>-1)

Say you have pagejs1.htm and pagejs2.htm, then the fragment could be pagejs.

Of course, this would have to somewhat customized to a particular set of pages and a particular function to run.

klbollwahn
08-01-2006, 05:52 PM
I have a content page that requires a javascript and stylesheet that doesn't load properly. It also requires the following added to the <body> tag
<body onload="visibilitytoggle()">. I've added this to the parent page. I then added the "rev" attribute to the as follows:
<li><a href="../topics/FAQ_Tmplt.html" rel="ajaxcontentarea" rev=../css/hotspot.css, ../js/hotspot.js">FAQ</a></li>.

Any ideas?

Thanks

jscheuer1
08-01-2006, 06:08 PM
Read all of the above.

klbollwahn
08-01-2006, 06:51 PM
Let me try this again. I'm new at this and not a programmer. I'm trying, without success, to use the following script on one of my tabs:

http://www.interactionarchitect.com/articles/toggle.htm

I've used it successfully with another ajax script:

http://www.dynamicdrive.com/dynamicindex17/ajaxincludes.htm

Where am I going wrong?

jscheuer1
08-02-2006, 08:23 PM
If a script that you are using in an AJAX tab needs to normally run onload, it cannot simply be loaded with loadobjs() and/or the rev attribute. You need to create a polling function and run that poll at the time that the tab is loaded, as described above. To be more specific, I would have to see your page.

koba100
05-27-2009, 05:44 PM
.js link doesn't work in FF and Google Chrome :((((

This is really amazing script but I faced some problem in FF and Google chrome, which I can't decide. So, please, if there is someone more experienced in it and smarter than me, help me... :(

So, I have this site where I wan't to include two different php files. They both have live-search fields, but in different languages: in English and in Georgian. So, here is what I'm doing:



<button id="mybutton" onclick="javascript:ajaxpage('english_autosuggest.php', 'search7'); loadobjs('english.css', 'english.js')">English</button>

<button id="mybutton2" onclick="javascript:ajaxpage('georgian_autosuggest.php', 'search7'); loadobjs('georgian.css','georgian.js', 'georgianlanguage.js');"> Georgian</button>

<script type="text/javascript">
ajaxpage('english_autosuggest.php', 'search7'); loadobjs('english.css', 'english.js')
</script>

<div id="search7">
</div>


Everything this works perfectly in IE6 but when I test the site in FF and Google chrome I experience the trouble with loading the "georgianlanguage.js". This is javascript file which let's me to write in search field in Georgian language.

and here is the "georgian.php" code:



<div id="search-wrap" >

<input name="checkbox" type="checkbox" id="geokeys" checked="CHECKED" style="display:none"/>

<input name="search-q" id="search-q" type="text" onKeyUp="javascript:autosuggest()" onKeyPress="return makeGeo(this,event);" autocomplete="off" charset="utf-8";/>

<div id="results"></div>


Everything had worked without trouble in any browsers when I was using iframes for inserting georgian.php and english.php but since I replaced it with div tags, I faced this problem. :( For the record: I have already changed
loadedobjects=""

So, please someone give me some advice... or at least tell me where should I search for the solution. :(((((

Thank you very much for your time.
Koba