views:

45

answers:

3

Hi. I have a tabbed setup on the page and I want to automatically make corresponding menu tab highlighted as well as corresponding content div show depending on # hash.

Example:

http://design.vitalbmx.com/user_menu/member_profile_so.html -- no hash, opens 1st tab

http://design.vitalbmx.com/user_menu/member_profile_so.html#setup -- #setup, should open "Setup" tab

As you can see it works for highlighting "Setup" tab. But content div does not change.

The script is below:

var tab_content_current = 1;
switch (window.location.hash) {
  case '#activity': tab_content_current = 1; break;
  case '#friends': tab_content_current = 2; break;
  case '#photos': tab_content_current = 3; break;
  case '#videos': tab_content_current = 4; break;
  case '#setup': tab_content_current = 5; break;
  case '#forum': tab_content_current = 6; break;
  case '#blog': tab_content_current = 7; break;
  case '#comments': tab_content_current = 8; break;
  case '#favorites': tab_content_current = 9; break;
  case '#profile-comments': tab_content_current = 10; break;
  default: tab_content_current = 1;
}
if (tab_content_current != 1) {
  change_active_tab (tab_content_current);
}
function tabs_toggle (id) {
  if (id != tab_content_current) {
    change_active_tab (id);
    tab_content_current = id;
  }
}
function change_active_tab (id) {
  $j('.profile_tabs li').removeClass('active');
  if (id < 8) $j('.profile_tab_'+id).addClass('active');
  $j('.profile_content').hide();
  $j('#profile_content_'+id).fadeIn();
}

Note that it works when you actually click menu tabs.

Any help to fix this problem would be greatly appreciated.

+1  A: 

That part of the code is not inside a jQuery ready() call, so the DOM is not yet loaded when it runs.

EDIT: The reason the tabs work, is that the script appears to be in the middle of the HTML content. The tas come before the script, and the content comes after. So that tabs are loaded, and the content sections are not.

Do this:

$(document).ready(function() {

  var tab_content_current = 1;
  switch (window.location.hash) {
    case '#activity': tab_content_current = 1; break;
    case '#friends': tab_content_current = 2; break;
    case '#photos': tab_content_current = 3; break;
    case '#videos': tab_content_current = 4; break;
    case '#setup': tab_content_current = 5; break;
    case '#forum': tab_content_current = 6; break;
    case '#blog': tab_content_current = 7; break;
    case '#comments': tab_content_current = 8; break;
    case '#favorites': tab_content_current = 9; break;
    case '#profile-comments': tab_content_current = 10; break;
    default: tab_content_current = 1;
  }
  if (tab_content_current != 1) {
    change_active_tab (tab_content_current);
  }
  function tabs_toggle (id) {
    if (id != tab_content_current) {
      change_active_tab (id);
      tab_content_current = id;
    }
  }
  function change_active_tab (id) {
    $j('.profile_tabs li').removeClass('active');
    if (id < 8) $j('.profile_tab_'+id).addClass('active');
    $j('.profile_content').hide();
    $j('#profile_content_'+id).fadeIn();
  }

});

Or just place the script at the end of the page. Good idea to use ready() anyway, though.

patrick dw
I was just about to ask this...
hunter
@hunter - Yeah, it appears to be the culprit. I updated my answer to point out that the script is in the middle of the page. The tabs come before, so they work, but the content comes after, so it doesn't.
patrick dw
it's not inside but $j value is already initialized so it does not have to be.Plus it would not change active tab if it was not called at all.
SODA
PS in headers I have $j = jQuery.noConflict();
SODA
@SODA - Please read my answer. This **is** the issue. Your script comes after the tabs, so the tabs work. But it comes before the content, so the content doesn't work. `ready()` has nothing to do with initializing `$j`. What `ready()` does, is it ensure that the DOM is loaded before your code runs.
patrick dw
@SODA - My answer has nothing to do with `$j`.
patrick dw
yeah I can see it. I moved script outside the containing DIV and it worked
SODA
You guys are the best thanks so much
SODA
+1  A: 

Move the script to the very bottom of the page, after the profile_content divs. That way they will be in the DOM before the scripts run. It is also best to put scripts at the bottom of the page for speed reasons.

Adam
Hey moving this piece of JS outside the #main-content div worked!
SODA
@SODA - That is effectively what `ready()` does, only more reliably with cross browser compatibility insurance.
patrick dw
+1  A: 

Try setting your <li> elements up like this:

<ul class="profile_tabs light"> 
    <li class="profile_tab_1 active"><a href="#activity">Activity</a></li> 

you can more easily write some jQuery to tab like so:

var tab_content_current = 1;
function GetIndex($obj) { return $(this).parent().children().index($obj); }

$j(function(){

    $j(".profile_tabs li").click(function(e){
        e.preventDefault();
        change_active_tab(GetIndex(this) + 1)
    });

    function change_active_tab (id) {
        tab_content_current = id;
        $j('.profile_tabs li').removeClass('active');
        if (id < 8) $j('.profile_tab_'+id).addClass('active');
        $j('.profile_content').hide();
        $j('#profile_content_'+id).fadeIn();
    }

    var hash = window.location.hash;
    if (hash != null && hash != "")
    {
        var $li = $(".profile_tabs li a[href=" + hash + "]");
        change_active_tab(GetIndex($li) + 1)
    }
});
hunter