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">Home<span>x</span></li>
<li>+ Add Tab</li>
</ul>
<div class="tabbable">
<!--bottomNav -->
<ul class="nav nav-tabs" id="bottomNav">
<li class="active">Test<span>x</span></li>
<li>+ Add Tab</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>#'+ id + '<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>#'+ id + '<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:
create a new tab.
create a new content for the new tab.
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">Tab 1
</li>
<li>Tab 2
</li>
<li>+ Add Tab</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">Tab 11
</li>
<li>Tab 12
</li>
<li>+ Add Tab</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">Tab 21
</li>
<li>Tab 22
</li>
<li>+ Add Tab</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);
}
Related
i know there are a lot themes about that, but i dont know why, noone of them are working
I am using AdminLTE3, i have tabs, i want to stay on selected tab after refresh
my code (not working, but should work):
#extends('adminlte::page')
#section('title', 'Mans Profils')
#section('content_header')
#stop
#section('content')
<div class="container">
<ul class="nav nav-tabs">
<li class="active"><a data-target="#home" data-toggle="tab">Home</a></li>
<li>About</li>
<li>Contacts</li>
</ul>
</div>
<div class="tab-content">
<div class="tab-pane active" id="home">Home</div>
<div class="tab-pane" id="about">About</div>
<div class="tab-pane" id="contacts">Contacts</div>
</div>
#stop
#section('css')
#stop
#section('js')
<script>
$(function() {
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
localStorage.setItem('lastTab', $(this).attr('href'));
});
var lastTab = localStorage.getItem('lastTab');
if (lastTab) {
$('[href="' + lastTab + '"]').tab('show');
}
});
</script>
#stop
No need to use localsStorage for that sake. just put condition over window.location.search
whichever tab has been clicked append window.location.search with that tab variable.
on reload check whether window.location.search string contains your tab variable then call the same code which is inside your tab click.
I'm having an issue with my site. It has a page with two tabs. In the second tab, there is a pagination and I'm using bootstrap. The issue I'm having is when I click a different page on the pagination, it goes back to the 1st tab.
I have tried to fix it using hash links. When I do that, it flashes the 1st tab for milliseconds and then shows the 2nd tab which is not what I want. I want it to show the same tab even after clicking the pagination. Also, note that I'm using Ajax.
<ul class="nav nav-tabs" id="resumes-tab">
<li class="active"><a data-toggle="tab" href="#shortlisted-resumes-list" aria-expanded="true">Shortlisted</a></li>
<li class=""><a data-toggle="tab" href="#download-resumes-list" aria-expanded="false">Downloads</a></li>
</ul>
<div class="tab-content">
<div id="shortlisted-resumes-list" class="tab-pane fade active in">
<div class="cs-resumes" data-adminurl="https://example.com/wp-admin/admin-ajax.php"></div>
</div>
<div id="download-resumes-list" class="tab-pane fade">
<div class="cs-resumes" data-adminurl="https://example.com/wp-admin/admin-ajax.php">
<nav>
<ul class="pagination">
<li><a aria-label="Previous"><span aria-hidden="true"><i class="icon-angle-left"></i>Previous</span></a></li>
<li><a class="active">1</a></li>
<li><span aria-hidden="true">Next <i class="icon-angle-right"></i></span></li>
</ul>
</nav>
</div>
</div>
</div>
Here's my jQuery snippet
<script>
// Javascript to enable link to tab
var hash = document.location.hash;
var prefix = "";
if (hash) {
jQuery('.nav-tabs a[href="' + hash.replace(prefix, "") + '"]').tab('show');
}
// Change hash for page-reload
jQuery('.nav-tabs a').on('shown.bs.tab', function (e) {
var hash = document.location.hash;
window.location.hash = e.target.hash.replace("#", "#" + prefix);
jQuery("html, body").animate({ scrollTop: $(".cs-dash-resumes-tabs").offset().top }, "slow");
});
</script>
Why does this happen? Because I'm using Ajax?
I did see a page somewhere on internet, which made impressive tabs like below:
All|Fashion|Jewerry|Food
When user clicks on All then it will show all items.
when user clicks om Fashion or else then i will show only items of its category.
I remember that each item have something like All Fashion/All Food so that the tab control panel would show/hide item.
I tried to find some tutorial about tab on bootstrap. But i did not see any example like that in document.
Could someone please show how to do that with bootstrap and without bootstrap???
The reasons's is i am only good with back-end.
I am learning front-end.
Thanks in advance.
i did
it without bootstrap
html:
<ul id='list_tabs'>
<li><a data-filter='*' href='#'>All</a></li>
<li><a data-filter='meat' href='#'>meat</a></li>
<li><a data-filter='fish' href='#'>fish</a></li>
</ul>
<ul id='list_products'>
<li data-category='fish meat'>product 1 </li>
<li data-category='fish'>product 2 </li>
<li data-category='meat'>product 3 </li>
</ul>
My Javascript:
$(document).ready(function(){
$('#list_tabs').click(function(event){
var filter = $(event.target).attr('data-filter');
$('#list_products li').each(function(){
var item = $(this);
if(filter=='*'||(item.attr('data-category').indexOf(filter)!= -1))
item.show();
else
item.hide();
});
});
});
I'm still looking into how to do it with bootstrap.
Thank everyone for helping.
P/s: I did saw same control like that in this site
I am looking into it. But i still hope someone could help me.
I loved checking this too. You can improvise as you learn. I give you a setup for you to start here.
// optional code: Throw event on tab change and work with it.
$('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
var elem = $(e.target),
target = elem.attr("href");
if (target === hashify('Tab_1') || target === hashify('Tab_3') || target === hashify('Tab_5')) {
$(hashify('testImage')).attr('src', 'http://cdn.sstatic.net/Sites/stackoverflow/img/apple-touch-icon#2.png?v=73d79a89bded&a');
}
else {
$(hashify('testImage')).attr('src', 'https://assets-cdn.github.com/images/modules/logos_page/GitHub-Mark.png');
}
});
function hashify(str){
return '#' + str;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<ul id="myTab" class="nav nav-tabs">
<li class="active">Tab 1
</li>
<li class="">Tab 2
</li>
<li class="">Tab 3
</li>
<li class="">Tab 4
</li>
<li class="">Tab 5
</li>
</ul>
<div id="myTabContent" class="tab-content">
<div class="tab-pane active in" id="Tab_1">
Tab 1
</div>
<div class="tab-pane" id="Tab_2">
Tab 2
</div>
<div class="tab-pane" id="Tab_3">
Tab 3
</div>
<div class="tab-pane" id="Tab_4">
Tab 4
</div>
<div class="tab-pane" id="Tab_5">
Tab 5
</div>
<img id = "testImage" src = "http://cdn.sstatic.net/Sites/stackoverflow/img/apple-touch-icon#2.png?v=73d79a89bded&a" alt="Logo" height="150" width="150">
</div>
<
I have the following Bootstrap nav tabs:
<div class="row spiff_tabs_body">
<!-- Nav tabs -->
<ul class="nav nav-tabs spiff_tabs" role="tablist">
<li role="presentation" class="active">
Potential Spiff
</li>
<li role="presentation">
Instant Spiff
</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="delayedspiff"></div>
<div role="tabpanel" class="tab-pane" id="instantspiff"></div>
</div>
</div>
</div>
</div>
I need to be able to check which tab is selected and then display an alert. I have the following javascript in my view:
<script>
$(function () {
FormGet('dashboard/delayedspiff', 'delayedspiff');
});
</script>
<script>
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
// here is the new selected tab id
var selectedTabId = e.target.id;
var id = $('.tab-content .active').attr('id');
if (id == "delayedspiff") {
alert("delayedspiff");
} else {
alert("instantspiff");
}
});
</script>
When I click the tabs it works, but the alert always displays delayedspiff. I need to dislay instantspiff when they click on the instantspiff tab. Can anyone see what I'm doing wrong?
You just need to remove class active from all tabs and add it to the tab which was clicked.
EDIT: In order to get the id of clicked tab, try using an attribute data-id on the tab selections.
<li role="presentation" class="active">
Potential Spiff
</li>
<li role="presentation">
Instant Spiff
</li>
<script>
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
var wrongid = $('.tab-content .active').attr('id');
$('a[data-toggle="tab"]').removeClass("active"); // remove class active from all tabs
$(this).addClass("active"); // add class active to the current tab
var correctid = $(this).data("id"); // get the attribute data-id of the clicked tab
alert($('.tab-content .active')[0].outerHTML); // shows why you are getting the incorrect id
if (correctid == "delayedspiff")
alert("delayedspiff");
else
alert("instantspiff");
});
</script>
Updated fiddle : https://jsfiddle.net/DTcHh/14313/
I did the following code, to be able to change the class of an li tag and then change the CSS of it.
I created a cookie variable that help me to select the good li tag. but I have a gap when I click.
I have three tabs : device, links and sites.
for example if I click on devices and had click on sites before, sites will be selected.
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery('.tabs .tab-links a').on('click', function(e) {
jQuery.cookie("select", jQuery(this).parent('li').attr('id'));
});
jQuery('#' + jQuery.cookie("select")).addClass('active').siblings().removeClass('active');
});
</script>
<div class="tabs" >
<ul class="tab-links">
<li id="device">Devices</li>
<li id="link">Links</li>
<li id="site">Sites</li>
</ul>
</div>
Since clicking the link takes you to a new page, there is no need to do this programmatically.
The page /netmg/controller/device/search should have
<li id="device" class="active">...</li>
<li id="link">...</li>
<li id="site">...</li>
The page /netmg/controller/link/search should have
<li id="device">...</li>
<li id="link" class="active">...</li>
<li id="site">...</li>
The page /netmg/controller/site/search should have
<li id="device">...</li>
<li id="link">...</li>
<li id="site" class="active">...</li>
You can put that in the HTML.
If, instead, you want to make it all one page and the href attribute indicates what content is displayed, say, in a <div id="deviceContent"></div> or similar, you could use this:
<script>
jQuery(document).ready(function() {
jQuery('.tab-links li a').click(function(e){
e.preventDefault();
var newdiv = jQuery(this).attr('href');
jQuery('.tab-links li').removeClass('active');
jQuery(this).parent('li').addClass('active');
jQuery('.contents div').hide();
jQuery(newdiv).show()
});
});
</script>
<div class="tabs" >
<ul class="tab-links">
<li id="device" class="active">Devices</li>
<li id="link">Links</li>
<li id="site">Sites</li>
</ul>
</div>
<div class="contents">
<div id="deviceContent"><!-- insert some contents -->a</div>
<div id="linkContent"><!-- insert some contents --> b</div>
<div id="siteContent"><!-- insert some contents -->c</div>
</div>
For a demo, see this fiddle.