# Rails/JavaScript issue

**URL:** <https://www.ruby-forum.com/t/rails-javascript-issue/189070>\
**Category:** Rails\
**Created:** [May 23, 2010, 11:21pm UTC](https://www.ruby-forum.com/t/rails-javascript-issue/189070 "2010-05-23T23:21:40Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![jmaenpaa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de053/32.png) [@jmaenpaa](https://www.ruby-forum.com/u/jmaenpaa)\
**Post date:** [May 23, 2010, 11:21pm UTC](https://www.ruby-forum.com/t/rails-javascript-issue/189070/1 "2010-05-23T23:21:40Z")

</div>

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:

```auto
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);
}
```

---

<div class="post-metadata">

**Author:** ![jmaenpaa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de053/32.png) [@jmaenpaa](https://www.ruby-forum.com/u/jmaenpaa)\
**Post date:** [May 24, 2010, 12:01am UTC](https://www.ruby-forum.com/t/rails-javascript-issue/189070/2 "2010-05-24T00:01:50Z")

</div>

On Sun, May 23, 2010 at 2:21 PM, John M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> 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. 🙂

> 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.

1. 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;  
> // …  
> }

1. Either way, it’s strictly a JS question and has nothing to do with  
Rails.

## FWIW,

Hassan S. ------------------------ removed\_email\_address@domain.invalid  
twitter: @hassan

---

<div class="post-metadata">

**Author:** ![jmaenpaa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de053/32.png) [@jmaenpaa](https://www.ruby-forum.com/u/jmaenpaa)\
**Post date:** [May 24, 2010, 12:27am UTC](https://www.ruby-forum.com/t/rails-javascript-issue/189070/3 "2010-05-24T00:27:50Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![jmaenpaa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de053/32.png) [@jmaenpaa](https://www.ruby-forum.com/u/jmaenpaa)\
**Post date:** [May 24, 2010, 12:31am UTC](https://www.ruby-forum.com/t/rails-javascript-issue/189070/4 "2010-05-24T00:31:49Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![jmaenpaa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de053/32.png) [@jmaenpaa](https://www.ruby-forum.com/u/jmaenpaa)\
**Post date:** [May 24, 2010, 12:32am UTC](https://www.ruby-forum.com/t/rails-javascript-issue/189070/5 "2010-05-24T00:32:51Z")

</div>

On Sun, May 23, 2010 at 3:27 PM, John M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> 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 🙂

–  
Hassan S. ------------------------ removed\_email\_address@domain.invalid  
twitter: @hassan

---

<div class="post-metadata">

**Author:** ![jmaenpaa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de053/32.png) [@jmaenpaa](https://www.ruby-forum.com/u/jmaenpaa)\
**Post date:** [May 24, 2010, 12:38am UTC](https://www.ruby-forum.com/t/rails-javascript-issue/189070/6 "2010-05-24T00:38:07Z")

</div>

On Sun, May 23, 2010 at 3:31 PM, John M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> 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 ? 🙂

–  
Hassan S. ------------------------ removed\_email\_address@domain.invalid  
twitter: @hassan
