Javascript tabs

Hi,
I have a site that uses javascript tabs. Everything works ok, when you click a tab it becomes active and fades in the content, click another tab and the previous tab is changed to inactive and the new tab becomes active and it’s content fades in.

However, I’d to amend the code so that if a user clicks on an “active” tab it hides/closes/deactivates that tab - i.e. if it’s inactive, clicking it will turn it on and display it’s contents, but if it’s already active, clicking it (the tab) will close the content and made the tab inactive.

My fours tabs are:

  • overview
  • prodinfo
  • fabrics
  • contype

Here’s my javascript code:

$(document).ready(function(){
	$(".tabmenu > li").click(function(e){
		switch(e.target.id){
			case "overview":
				//change status & style menu
				$("#overview").addClass("active");
				$("#prodinfo").removeClass("active");
				$("#fabrics").removeClass("active");
				$("#contype").removeClass("active");
				//display selected division, hide others
				$("div.overview").fadeIn();
				$("div.prodinfo").css("display", "none");
				$("div.fabrics").css("display", "none");
				$("div.contype").css("display", "none");				
			break;
			case "prodinfo":
				//change status & style menu
				$("#overview").removeClass("active");
				$("#prodinfo").addClass("active");
				$("#fabrics").removeClass("active");
				$("#contype").removeClass("active");
				//display selected division, hide others
				$("div.prodinfo").fadeIn();
				$("div.overview").css("display", "none");
				$("div.fabrics").css("display", "none");
				$("div.contype").css("display", "none");
			break;
			case "fabrics":
				//change status & style menu
				$("#overview").removeClass("active");
				$("#prodinfo").removeClass("active");
				$("#contype").removeClass("active");
				$("#fabrics").addClass("active");
				//display selected division, hide others
				$("div.fabrics").fadeIn();
				$("div.overview").css("display", "none");
				$("div.prodinfo").css("display", "none");
				$("div.contype").css("display", "none");
			break;
			case "contype":
				//change status & style menu
				$("#overview").removeClass("active");
				$("#prodinfo").removeClass("active");
				$("#fabrics").removeClass("active");
				$("#contype").addClass("active");
				//display selected division, hide others
				$("div.contype").fadeIn();
				$("div.overview").css("display", "none");
				$("div.prodinfo").css("display", "none");
				$("div.fabrics").css("display", "none");
			break;
		}
		//alert(e.target.id);				
		return false;
	});
	
	
});

…and here’s the html:

<div id="tabcontainer">
              <ul class="tabmenu">
                <li id="overview" class="active">Overview</li>
                <li id="prodinfo">Information</li>
                <li id="fabrics">Fabrics</li>
                <li id="contype">Type</li>
              </ul>
              <div class="clear"></div>

              <div class="tabcontent overview">
               overview content (active on page load)
              </div><!--end of overview-->

              <div class="tabcontent prodinfo" style="display:none;">
              content here
              </div><!--end of prodinfo-->

              <div class="tabcontent fabrics" style="display:none;">
              content here
              </div><!--end of fabrics-->

              <div class="tabcontent contype" style="display:none;">
              content here
              </div><!--end of contype-->
</div><!--end of tabcontainer-->  

Hope someone can help.

Many thanks.

Hi,

I would use anchors in the tabs and use the href to identify the tab to be chosen which means it will still work with Js off.

Something like this (although I expect the JS experts here can shorten this even further).


<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
</head>

<body>
<div id="tabcontainer">
		<ul class="tabmenu">
				<li id="overview"><a href="#tab1">Overview</a></li>
				<li id="prodinfo"><a href="#tab2">Information</a></li>
				<li id="fabrics"><a href="#tab3">Fabrics</a></li>
				<li id="contype"><a href="#tab4">Type</a></li>
		</ul>
		<div class="clear"></div>
		<div id="tab1" class="tabcontent overview"> overview content (active on page load) </div>
		<!--end of overview-->
		
		<div id="tab2" class="tabcontent prodinfo">Information content here </div>
		<!--end of prodinfo-->
		
		<div id="tab3" class="tabcontent fabrics">Fabrics content here </div>
		<!--end of fabrics-->
		
		<div id="tab4" class="tabcontent contype">Type content here </div>
		<!--end of contype--> 
</div>
<!--end of tabcontainer--> 

<script>
$(document).ready(function () {
    $(".tabcontent").hide(); //Hide all content
    $("ul.tabmenu li:first").addClass("active").show(); //Activate first tab
    $(".tabcontent:first").show(); //Show first tab content

    $(".tabmenu > li").click(function (e) {
        var activeTab = $(this).find("a").attr("href"); //Find the attribute value to identify the active tab + content
        if ($(this).hasClass('active')) {// checks if same tab clicked and just hides it
            $(activeTab).fadeOut(); //Fade out the active content
            $(this).removeClass('active');
        } else {
            $(".tabcontent").hide(); //Hide all tab content
            $("ul.tabmenu li").removeClass("active"); //Remove any "active" class
            $(this).addClass("active"); //Add "active" class to selected tab
            $(activeTab).fadeIn(); //Fade in the active content
        }
        return false;
    });
});
</script>
</body>
</html>


Thanks, I’ll give it a go and let you now how I get on.

Hi,
That worked great - thank you very much.
Is it possible to have one tab (id=“overview”) have an actual url (i.e. when someone click that one tab they go to a different web page) - but I still want it to look like (and be part of) the same group of tabs (part of the same <ul>) - is that something that can be done?

Thanks again.

Hi,

You could exclude the first-child from the the click routine.


<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
</head>

<body>
<div id="tabcontainer">
		<ul class="tabmenu">
				<li id="overview"><a href="[B]http://www.google.com[/B]">Overview</a></li>
				<li id="prodinfo"><a href="#tab2">Information</a></li>
				<li id="fabrics"><a href="#tab3">Fabrics</a></li>
				<li id="contype"><a href="#tab4">Type</a></li>
		</ul>
		<div class="clear"></div>
		<div id="tab1" class="tabcontent overview"> overview content (active on page load) </div>
		<!--end of overview-->
		
		<div id="tab2" class="tabcontent prodinfo">Information content here </div>
		<!--end of prodinfo-->
		
		<div id="tab3" class="tabcontent fabrics">Fabrics content here </div>
		<!--end of fabrics-->
		
		<div id="tab4" class="tabcontent contype">Type content here </div>
		<!--end of contype--> 
</div>
<!--end of tabcontainer--> 

<script>
$(document).ready(function () {
    $(".tabcontent").hide(); //Hide all content
    $("ul.tabmenu li:first").addClass("active").show(); //Activate first tab
    $(".tabcontent:first").show(); //Show first tab content

   [B] $(".tabmenu > li:not(:first-child)")[/B].click(function (e) {
        var activeTab = $(this).find("a").attr("href"); //Find the attribute value to identify the active tab + content
        if ($(this).hasClass('active')) {// checks if same tab clicked and just hides it
            $(activeTab).fadeOut(); //Fade out the active content
            $(this).removeClass('active');
        } else {
            $(".tabcontent").hide(); //Hide all tab content
            $("ul.tabmenu li").removeClass("active"); //Remove any "active" class
            $(this).addClass("active"); //Add "active" class to selected tab
            $(activeTab).fadeIn(); //Fade in the active content
        }
        return false;
    });
});
</script>
</body>
</html>


I’m not sure how that will work in a tab situation as you may leave the user a bit confused.

Thanks very much - that works great.