PDA

View Full Version : AJAX Tabs Question



gandalf97
09-19-2006, 07:29 PM
1) Script Title: Ajax Tabs Content script

2) Script URL (on DD): http://www.dynamicdrive.com/dynamicindex17/ajaxtabscontent/

3) Describe problem:
I have inherited a project that uses ajax tabs and have a couple of questions. The first question came up because the previous developer named a whole lot of text boxes "Text1", "Text2", ... "Text31" and so forth. These text boxes appear on about 6 tabs in various combinations. So "Text15" might be on tabs 1, 4, and 5 while "Text1" might be on all the tabs. We have a "ClearData" function that is written in JavaScript. Each text element is cleared in turn like this:
if (document.getElementById('Text1')) {
document.getElementById('Text1').value = ""
}
This code "works" but the problem is that it isn't really that reusable when we are going to implement a different set of tabs for each department. What I tried to do was to get a collection of elements and iterate through them, resetting all the "text" ones to "". This is the code:

var inputs = document.getElementsByTagName("input");
for(var i=0; i < inputs.length; i++) {
if(inputs[i].type == "text") {
inputs[i].value = "";
} else {
alert(inputs[i].id + ": " + inputs[i].type);
}
}

This code looks like it should work. The problem is that only the text elements that are on the currently selected tab are cleared, even if the same text element exists on another tab. So, this looks to me like I don't fully understand something about how these tabs work.

I had a similar problem getting content to update on tabs unless I modified the ajaxtabs script. So, I really need to understand the concept(s) that I am apparently missing. Thanks in advance.

Gandalf

jscheuer1
09-20-2006, 04:05 AM
Any tabs that aren't currently displayed aren't on the page. Any content on tabs not currently displayed cannot be influenced via javascript.

Once a tab is loaded onto the page, then and only then can its content be influenced via javascript.

The tabs are not some content on the page that you cannot see, they literally are not on the page when you cannot see them.

Some other useful information can be found here:

http://www.dynamicdrive.com/forums/showthread.php?t=13003

gandalf97
09-20-2006, 01:55 PM
John,

Thanks for the pointer to the other article. While I had already read it, now it is beginning to make more sense to me. I'm still trying to absorb all of the implications of only fetching content and not style/scripts. So, to clarify for me further, if the content is only fetched when a tab is clicked, what is the event that fires? Can you please explain a little better the sequence of events and what happens when? Thanks in advance.

Regards,
Gandalf

jscheuer1
09-20-2006, 05:05 PM
if the content is only fetched when a tab is clicked, what is the event that fires? Can you please explain a little better the sequence of events and what happens when?

That's a very good question. Technically, the answer would be the onclick, onmousedown and onmouseup events of the anchor element you clicked. I think you also want to know what functions are getting run. If you look into the ajaxtabs.js in its startajaxtabs function, you will see this code fragment:


ulistlink.onclick=function(){
ajaxpage(this.getAttribute("href"), this.getAttribute("rel"), this)
loadobjs(this.getAttribute("rev"))
return false
}

This is assigning functions to the tab links' onclick events. The important one is:


ajaxpage(this.getAttribute("href"), this.getAttribute("rel"), this)

It will perform an XMLHttpRequest to the page listed as the link's href attribute and get that page's content as text and load it as the innerHTML object of the element with the id of the link's rel attribute.

This is all fine and good because, content that wasn't on the page before, now is on the page. However, this new content is in its 'virgin' form. Since it wasn't on the page before, any scripts that we ran back then could have no effect on it. Now that this new content has arrived, if we want to run a function against it we can. To be able to do that in a timely fashion is what that other article explains.

But, as I bet you are beginning to see, if we click another tab link, its href'ed page's content will be fetched and loaded into the same space where we just loaded the other page's content, thus obliterating that previous content. If we load the first content back again, it will be 'virgin' again, any previous changes to it were lost when it was obliterated by the second batch of content. This will even happen if we load the same page's content over itself.

Whatever gets loaded into the innerHTML object of an element obliterates what was there before.

gandalf97
09-22-2006, 06:43 PM
John,

First of all, I'd like to thank you for your help. Because of you I am finally beginning to understand this stuff. You tend to explain things well.


This is all fine and good because, content that wasn't on the page before, now is on the page. However, this new content is in its 'virgin' form. Since it wasn't on the page before, any scripts that we ran back then could have no effect on it. Now that this new content has arrived, if we want to run a function against it we can. To be able to do that in a timely fashion is what that other article explains.

But, as I bet you are beginning to see, if we click another tab link, its href'ed page's content will be fetched and loaded into the same space where we just loaded the other page's content, thus obliterating that previous content. If we load the first content back again, it will be 'virgin' again, any previous changes to it were lost when it was obliterated by the second batch of content. This will even happen if we load the same page's content over itself.


Ah. The light is beginning to get brighter. The examples I have been looking at are all static content so what you say above wasn't immediately obvious to me because my app is trying to load asp pages on the tabs. More on that in a minute...

I re-read the article you pointed me to and now it makes a lot more sense. I do have a couple of questions about it though. I do have an onload event function to initialize a part of the screen outside the ajax content area. Is that the code you suggest I rip out?

Maybe it would help if I just try to explain what I am trying to do and see what suggestions you have.

Basically I am creating information "dashboards" for several departments. Common to 99% of the "dashboards" are a set of list boxes on the left side of the screen which are basically search criteria for our database. Each box populates when something is chosen from the one above with only the appropriate "next" choices. When enough criteria are chosen, the "selected" ajax tab populates with content based on those criteria. So, what we really want to do is have two things trigger an update to the ajaxcontentarea... first, selecting enough criteria on the navigation area and second, switching tabs. When we switch tabs, we don't really want "virgin" content, what we want is the appropriate content based on the database criteria on the left.

The other developer working on this wants to modify the ajaxtabs function for every "dashboard" so that the data gets refreshed. Her approach seems to work but she can't say why. I don't like that approach because I would prefer only one ajaxtabs for the entire project and I suspect having to change it for each "dashboard" indicates that niether one of us really understands how this script was intended to be used. Here is an example of the modified code:



ulistlink.onclick=function(){
ajaxpage(this.getAttribute("href"), this.getAttribute("rel"), this)
loadobjs(this.getAttribute("rev"))
var strCriteria1 = document.getElementById('Criteria1').value;
var strCriteria2 = document.getElementById('Criteria2').value;
var strCriteria3 = document.getElementById('Criteria3').value;
var strCriteria4 = document.getElementById('Criteria4').value;
var strCriteria5 = document.getElementById('Criteria5').value;


So, for each tab change, we get the current values of the database search criteria.



loadXMLDoc('TAG1','getPage1XML.asp?Criteria1=' + strCriteria1 + '&Criteria2=' + strCriteria2 + '&Criteria3=' + strCriteria3 + '&Criteria4= '+strCriteria4 + '&Criteria5=' + strCriteria5);
loadXMLDoc('TAG2','getPage2XML.asp?Criteria1=' + strCriteria1 + '&Criteria2=' + strCriteria2 + '&Criteria3=' + strCriteria3 + '&Criteria4= '+strCriteria4 + '&Criteria5=' + strCriteria5);
loadXMLDoc('TAG3','getPage3XML.asp?Criteria1=' + strCriteria1 + '&Criteria2=' + strCriteria2 + '&Criteria3=' + strCriteria3 + '&Criteria4= '+strCriteria4 + '&Criteria5=' + strCriteria5);


I cut 3 more similar lines from the code, but you get the idea. This particular example calls our loadXMLDoc function 6 times every time a link is clicked to change tabs. :eek: Basically, loadXML takes 2 parameters... a "src" and a url. It creates our XMLHttpRequest object and then based on the "src" (TAG1, TAG2, TAG3...) it assigns a different event procedure to the "onreadystatechange" event of the request object. It then does a req.open("GET", url, false) to generate our XML data (synchronously). When we come back from that call and the content is fetched, the correct event procedure is called and the content is stuck into the html for the tab. In a nutshell, this is the process.

I hope I didn't muddy the waters too much but I wanted to give you a better idea of where I'm trying to go. I am interested in any suggestions or comments. I'd be happy to clarify anything I can if I wasn't clear enough.

Regards,
Gandalf

jscheuer1
09-23-2006, 05:56 AM
Nobody knows everything. Some of that stuff is a bit over my head but, that has never really stopped me in the past. I get the impression that you are loading up pages just in case they might be needed. If the content of these pages is likely to be different from hour to hour, then this is unavoidable I would suppose. However, if the interval is longer and known, I'd have them generated and available. On the other hand, if your current system is creating content that will never be shown to the user unless he/she backs up a level and makes a different choice, then the process for selecting which content pages to assemble needs to be refined.