Rails/JavaScript issue

Hey all,

I have an application.js file in my javascripts folder of my Ruby on Rails application. The javascript is just a typical hide/show tabs effect, so when the user clicks on one link, the corresponding div is revealed and the other divs are hidden. Two pages require the javascript. However, while one page displays content of no tabs onload, the other page displays the content of the first tab onload. So the page that displays the content of no tab onload works fine. However, the page that displays the content of first tab onload is not working. I get the following error in FireBug:

document.getElementById("tabs") is NULL var tabListItems = document.getElementById("tabs").childNodes;

I think the issue is I'm calling multiple functions on page load (and hence since the one page doesn't have a tabs id it doesn't know what to do), even though I only need one function for each of the pages. But I wuld like to keep this tab effect in the same file. So I don't know what to do. Thanks for anyone's response: [CODE] window.onload = init;

var tabLinks = new Array(); var contentDivs = new Array();

function init() {   initProduct();   initAbout(); }

function initProduct() {   var tabListItems = document.getElementById("tabs").childNodes;   for(var i=0; i < tabListItems.length; i++) {     if(tabListItems[i].nodeName == "LI") {       var tabLink = getFirstChildWithTagName(tabListItems[i], "A");       var id = getHash(tabLink.getAttribute("href"));       tabLinks[id] = tabLink;       contentDivs[id] = document.getElementById(id);       tabLinks[id].className = "";       contentDivs[id].className = "tabContent hide";       tabLinks[id].onclick = showTab;       tabLinks[id].onfocus = function() { this.blur() };     }   } }

function initAbout() {   var tabListItems = document.getElementById("tabAbout").childNodes;   for(var i=0; i < tabListItems.length; i++) {     if(tabListItems[i].nodeName == "LI") {       tabLink = getFirstChildWithTagName(tabListItems[i], "A")       id = getHash(tabLink.getAttribute("href"));       tabLinks[id] = tabLink;       contentDivs[id] = document.getElementById(id);     }   }   var i = 0;   for(var id in tabLinks) {     tabLinks[id].onclick = showTab;     tabLinks[id].onfocus = function() { this.blur() }     if(i == 0) {       tabLinks[id].className = "selected"     }     i++   }   var i = 0;   for(var id in contentDivs) {     if(i != 0) {       contentDivs[id].className = "tabContent hide";     }     i++   } }

function showTab() {   document.getElementById("product").className = "tabContent hide"   var selectedId = getHash(this.getAttribute("href"));

  for(id in contentDivs) {     if(id == selectedId) {       tabLinks[id].className = "selected";       contentDivs[id].className = "tabContent";     }     else {       tabLinks[id].className = "";       contentDivs[id].className = "tabContent hide";     }   }

  return false; }

function getFirstChildWithTagName(element, tagName) {   for(var i=0; i < element.childNodes.length; i++) {     if(element.childNodes[i].nodeName == tagName) {       return element.childNodes[i];     }   } }

function getHash(url) {   var hashPos = url.lastIndexOf("#");   return url.substring(hashPos + 1); } [/CODE]

document.getElementById("tabs") is NULL var tabListItems = document.getElementById("tabs").childNodes;

I think the issue is I'm calling multiple functions on page load (and hence since the one page doesn't have a tabs id it doesn't know what to do), even though I only need one function for each of the pages. But I wuld like to keep this tab effect in the same file. So I don't know what to do.

1) check the battery in your watch; it's so not 1997 anymore. :slight_smile:

window.onload = init;

That line looks resurrected from a seriously ancient tutorial -- read up on EventListeners to understand why it's a poor approach, and how you should be invoking your functions.

2) defensive coding: you can either test first to see if there is an     element with the ID "tabs" or you can wrap the whole thing in     a try/catch block.

function initProduct() { var tabListItems = document.getElementById("tabs").childNodes;

    // ....

}

3) Either way, it's strictly a JS question and has nothing to do with     Rails.

FWIW,

In my initial post, I did say there was an element with an id of tabs, but that it was part of another page and not the page the error occured on. However,the same js file is being used for both pages. So that's the issue I'm trying to resolve here.

Yes, and I just explained how to do that. More than one way, actually.

And it still has nothing to do with Rails :slight_smile:

Also I don't think the getElementById() method was around in 1997.

Also I don't think the getElementById() method was around in 1997.

? Uh, well. I explicitly referenced the line

window.onload = init;

so, that has what now to do with getElementById ? :slight_smile: