Praveen
Praveen

Reputation: 1802

how do i use piece of jQuery code multiple times per page

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

Answers (4)

user1795160
user1795160

Reputation:

Some time ago I worked on something similar:

http://jsfiddle.net/js9kurec/

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

PaulBinder
PaulBinder

Reputation: 2052

Late to the party but I think this may be a bit cleaner way to do it.

JSFIDDLE

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

Dave Salomon
Dave Salomon

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

Blake A. Nichols
Blake A. Nichols

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

Related Questions