简体   繁体   中英

Bootstrap - Dynamically added nested tabs

I just started learning front-end development & really need help with a practice project.

I am trying to create 2-layers nested tabs where the user can add tabs on the outer layer. Each outer tab will have inner tabs where the user can also add more inner tabs. Each tab will have the same content for now, so I'm using an iframe to accomplish this - if you have better suggestion, then I would very much like to hear it.

The issue I'm having right now is that I don't know how to bind the inner tabs to the outer tabs. Each of the outer tabs should have different number of tabs depending on how many inner tabs the user creates. I cannot seem to accomplish this & all of my outer tabs currently have the same inner tabs.

Any help/input would be very much appreciated! Thanks.

Here's my code snippet:

<div class="container">
    <!-- top level tabs --> 
        <ul class="nav nav-tabs" id="topNav">
            <li class="active"><a href="#top1" data-toggle="tab">Home</a><span>x</span></li>
            <li><a href="#" class="addTop" data-toggle="tab">+ Add Tab</a></li>
        </ul>
        <div class="tabbable">
            <!--bottomNav -->
            <ul class="nav nav-tabs" id="bottomNav">
                <li class="active"><a href="#bottom1" data-toggle="tab">Test</a><span>x</span></li>
                <li><a href="#" class="addBottom" data-toggle="tab">+ Add Tab</a></li>
            </ul>

                <div class="tab-content">
                    <div class="tab-pane active" id="bottom1"><br><iframe src="form.html" width="100%" height="60%" allowtransparency="true" frameBorder="0"></iframe></div>
                </div>
            </div>
        </div>   

My script:

$(document).ready(function() { 

$(".nav-tabs").on("click", "a", function(e){
      e.preventDefault();
       $(this).tab('show');
      })
    .on("click", "span", function () {
        var anchor = $(this).siblings('a');
        $(anchor.attr('href')).remove();
        $(this).parent().remove();
        $(".nav-tabs li").children('a').first().click();
    });
    /* Adding New Tabs */
    $('.addTop').click(function(e) {
        e.preventDefault();
        var id = $("#topNav").children().length; 
        $(this).closest('li').before('<li><a href="#top'+id+'">#'+ id + '</a><span>x</span></li>'); 
        //  $('.tab-content').append('<div class="tab-pane" id="top'+id+'">'+ '<br><iframe src="form.html" width="100%" height="60%" allowtransparency="true" frameBorder="0">' + '</iframe>' + '</div>');

  });
    $('.addBottom').click(function(e) {
        e.preventDefault();
        var id = $("#bottomNav").children().length; 
        $(this).closest('li').before('<li><a href="#bottom'+id+'">#'+ id + '</a><span>x</span></li>');         
        $('.tab-content').append('<div class="tab-pane" id="bottom'+id+'">'+ '<br><iframe src="form.html" width="100%" height="60%" allowtransparency="true" frameBorder="0">' + '</iframe>' + '</div>');

  });
});

There are ready made sollutions out there, but let us leave it for others to suggest.

In reply to your issue: Your addTop.onclick event only adds a new tab, but does not create new content.tabbable for the said tab.

When you ad a new tab you have to do 3 things:

  1. create a new tab.
  2. create a new content for the new tab.
  3. associate event.

Obviously you missed number 2 & 3.

Example:

$('.addTop').click(function(e){
    e.preventDefault();

    // create new tab
    var newTab = $('<li>New Tab</li>'); 
    $('#topNav').append(newTab);

    // create new content for the new tab
    var newTabContent = $('<div class="tabbable"></div>').hide();
    $('.container').append(newTabContent);

    // associate tab to content
    newTab.click(function(){
        newTabContent.show();
        // hide others
        $('.container > .tabbable').hide();
    });
});

Hope this could help. This is the solution without using iframe

You can see the effect in jsfiddle link below: http://jsfiddle.net/Lzfsgeq9/

Basically some points you need to be aware of are:

1.Use ahref to direct you subtab from parent tab

2.Use "on" event listener to deal with newly created element about event delegation issue

<div class="tabbable boxed parentTabs">
<ul id="topNav" class="nav nav-tabs">
    <li class="active"><a href="#top1">Tab 1</a>
    </li>
    <li><a href="#top2">Tab 2</a>
    </li>
    <li><a href="#" class="addTop" data-toggle="tab">+ Add Tab</a></li>
</ul>
<div class="tab-content">
    <div class="tab-pane fade active in" id="top1">
        <div class="tabbable">
            <ul id="bottomNav1" class="nav nav-tabs" data-parent="1">
                <li class="active"><a href="#bottom11">Tab 11</a>
                </li>
                <li><a href="#bottom12">Tab 12</a>
                </li>
                <li><a href="#" class="addBottom" data-toggle="tab">+ Add Tab</a></li>
            </ul>
        </div>
    </div>
    <div class="tab-pane fade" id="top2">
        <div class="tabbable">
            <ul id="bottomNav2" class="nav nav-tabs" data-parent="2">
                <li class="active"><a href="#bottom21">Tab 21</a>
                </li>
                <li><a href="#bottom22">Tab 22</a>
                </li>
                <li><a href="#" class="addBottom" data-toggle="tab">+ Add Tab</a></li>
            </ul>
        </div>
    </div>
</div>

    $("ul.nav-tabs").on("click","a",function (e) {
            e.preventDefault();  
            $(this).tab('show');
    });

    $('.addTop').click(function(e) {
            e.preventDefault();
            var id = $("#topNav").children().length; 
            $(this).closest('li').before('<li><a href="#top'+id+'">Tab'+ id + '</li>');
            createNewSubTab(id);
    });

    $('div.tab-content').on("click",".addBottom",function(e) {
        e.preventDefault();
        var parentId = $(this).closest('ul').data("parent");
        var id = $("#bottomNav" + parentId).children().length; 
        $(this).closest('li').before('<li><a href="#bottom'+parentId+id+'">Tab'+ parentId + id + '</li>'); 
   });

    var createNewSubTab = function(id){
        var bottomTabPane = $("<div></div>").attr({
            id: "top" + id,
            "class": "tab-pane fade"
        });
        var tabContainer = $("<div></div>").attr({
            "class":"tabbable"
        });
        var bottomPanel = $("<ul></ul>").attr({
                    id:"bottomNav"+id,
                    "class":"nav nav-tabs",
                    "data-parent": id
       });
       var bottomAdd = $("<li></li>").append("<a href='#' class='addBottom' data-toggle='tab'>+ Add Tab</a>");
       bottomTabPane.append(tabContainer);
       tabContainer.append(bottomPanel);
       bottomPanel.append(bottomAdd);
       $(".tab-content").append(bottomTabPane);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM