Reputation: 1802
I can only use below code for a single instance of tabs per page. I'm fairly new to programming and JS so I would like some pointers in terms of how I would go about this.
$(document).ready(function(){
$('#tab-content div').hide();
$('#tab-content div:first').show();
$('#nav li').click(function() {
$('#nav li a').removeClass("active");
$(this).find('a').addClass("active");
$('#tab-content div').hide();
var indexer = $(this).index();
$('#tab-content div:eq(' + indexer + ')').fadeIn();
});
})
jsfiddle: http://jsfiddle.net/R85tE/309/
I don't want to have to work with manually adding separate IDs to the JS to activate the tabs. All I want to do is have multiple tabbed areas on the same page, and use a class in the JS to work them all.
Upvotes: 0
Views: 284
Reputation:
Some time ago I worked on something similar:
I did some documentary work to explain what it does; in a nutshell, it creates a navigation from the given tabs and adds the needed functionality to switch them.
$(document).ready(function() {
// you might want to add this to an external js file or so
initializeTabgroups = function() {
$('div.tabgroup div.tabs').each(function() { // for each tabgroup
var children = []; // were getting data-id and data-title for each child
$(this).children().each(function() {
children.push({ id: $(this).data('id'), title: $(this).data('title') });
$(this).hide(); // hide all children
});
$(this).children().first().addClass('active').show(); // show the first child
$(this).before(function() { // create a control panel
var pre = $('<div></div>').addClass('control');
children.forEach(function(obj) { // add a link for each tab
pre.append(
$('<a href="#" data-trigger="' + obj.id + '">' + obj.title + '</a>')
);
});
return pre;
}());
var self = $(this).parent();
$(self).find('div.control a').each(function() { // add the click functions for each element
$(this).click(function() {
// change the content
$(self).find('div.tabs div.tab[data-id!="' + $(this).data('trigger') + '"]').hide();
$(self).find('div.tabs div.tab[data-id="' + $(this).data('trigger') + '"]').fadeIn();
// change the navbar active classes
$(self).find('div.control a[data-trigger!="' + $(this).data('trigger') + '"]').removeClass('active');
$(self).find('div.control a[data-trigger="' + $(this).data('trigger') + '"]').addClass('active');
});
});
// add the active class to the first control link
$(self).find('div.control a').first().addClass('active');
});
};
initializeTabgroups();
});
I'm aware of the fact that this is not a perfect solution, but I thought you might want to have a look at an alternative solution.
Upvotes: 0
Reputation: 2052
Late to the party but I think this may be a bit cleaner way to do it.
Javascript
$('.tab-content div').hide();
$('.tab1').show();
$('.nav li').click(function() {
var clickedObject = $(this);
clickedObject.closest('.nav').find('.active').removeClass("active");
clickedObject.find('a').addClass("active");
var closestTabMenu = clickedObject.closest('.tabmenu');
closestTabMenu.find('.tab-content div').hide();
var indexer = $(this).index(); //gets the current index of (this) which is #nav li
closestTabMenu.find('.tab-content div:eq(' + indexer + ')').fadeIn();
});
you just need to change you html to use classes and not IDs
HTML
<div class="tabmenu">
<ul class="nav">
<li><a href="#" class="active">Tab 1</a></li>
<li><a href="#">Tab 2</a></li>
<li><a href="#">Tab 3</a></li>
<li><a href="#">Tab 4</a></li>
</ul>
<div class="tab-content">
<div class="tab1">
<p>This is a very simple jQuery tabbed navigation.</p>
</div>
<div class="tab2">
<p>This can contain anything.</p>
</div>
<div class="tab3">
<p>Like photos:</p><br />
<img src="http://www.catname.org/images/cat04.jpg" alt=""/>
</div>
<div class="tab4">
<p>Or videos:</p><br />
<iframe width="250" height="180" src="http://www.youtube.com/embed/TZ860P4iTaM" frameborder="0" allowfullscreen></iframe>
</div>
</div>
</div>
<div class="tabmenu">
<ul class="nav">
<li><a href="#" class="active">Tab 1</a></li>
<li><a href="#">Tab 2</a></li>
<li><a href="#">Tab 3</a></li>
<li><a href="#">Tab 4</a></li>
</ul>
<div class="tab-content">
<div class="tab1">
<p>second menu</p>
</div>
<div class="tab2">
<p> second menuThis can contain anything.</p>
</div>
<div class="tab3">
<p> second menu Like photos:</p><br />
<img src="http://www.catname.org/images/cat04.jpg" alt=""/>
</div>
<div class="tab4">
<p>second menu Or videos:</p><br />
<iframe width="250" height="180" src="http://www.youtube.com/embed/TZ860P4iTaM" frameborder="0" allowfullscreen></iframe>
</div>
</div>
</div>
Upvotes: 1
Reputation: 3297
Perhaps you're looking more to traverse the elements within your function, which you are doing a little bit?
$('.tabmenu div div:first').show();
$('.tabmenu ul li').click(function() {
var $self = $(this);
var $nav = $(this).parent();
var $tabCtl = $nav.parent();
$nav.find('a').removeClass("active");
$self.find('a').addClass("active");
$tabCtl.children('div').children('div').hide();
var indexer = $self.index(); //gets the current index of (this) which is #nav li
$tabCtl.children('div').children('div:eq(' + indexer + ')').fadeIn(); //uses whatever index the link has to open the corresponding box
});
http://jsfiddle.net/daveSalomon/R85tE/339/
Note that your original code has duplicate ID's - this is a big no-no!
It might help to read about jQuery Traversal methods and jQuery Selectors.
Upvotes: 1
Reputation: 870
You need to set the ID of your tab-content and nav on the second panel to another id (you can't have more than 1 id per page). So change the second nav and tab to nav2 and tab2-content.
$('#tab-content div').hide();
$('#tab-content div:first').show();
$('#nav li').click(function() {
$('#nav li a').removeClass("active");
$(this).find('a').addClass("active");
$('#tab-content div').hide();
var indexer = $(this).index();
$('#tab-content div:eq(' + indexer + ')').fadeIn();
});
$('#tab2-content div').hide();
$('#tab2-content div:first').show();
$('#nav2 li').click(function() {
$('#nav2 li a').removeClass("active");
$(this).find('a').addClass("active");
$('#tab2-content div').hide();
var indexer = $(this).index();
$('#tab2-content div:eq(' + indexer + ')').fadeIn();
});
Edit: Robust Function
function initTabPanel( navid, tabid ) {
$('#' + tabid + ' div').hide();
$('#' + tabid + ' div:first').show();
$('#' + navid + ' li').click(function() {
$('#' + navid + ' li a').removeClass("active");
$(this).find('a').addClass("active");
$('#' + tabid + ' div').hide();
var indexer = $(this).index();
$('#' + tabid + ' div:eq(' + indexer + ')').fadeIn();
});
}
// Initialzing the two tab panels
initTabPanel( 'nav', 'tab-content' );
initTabPanel( 'nav2', 'tab2-content' );
Upvotes: 2