I have made custom tabs with a function in JQuery. This is my custom tabs:
<div class="row">
<div class="col-4 master-advanced-left-tab master-advanced-left-tab-active">
<p>Item 1</p>
</div>
<div class="col-4 master-advanced-left-tab">
<p>Item 2</p>
</div>
<div class="col-4 master-advanced-left-tab">
<p>Item 3</p>
</div>
</div>
<div class="item1">
Show content from item 1
</div>
<div class="item2">
Show content from item 2
</div>
<div class="item3">
Show content from item 3
</div>
This is the custom styling I made with the tabs:
.master-advanced-left-tab {
overflow: hidden;
cursor: pointer;
padding-bottom: 10px;
padding-top: 10px;
}
.master-advanced-left-tab > p {
text-overflow: ellipsis;
height: 20px;
}
.master-advanced-left-tab-active {
color: #1C72DF;
border-bottom: 3px #1C72DF solid;
}
And this is my function to activate the tabs (working)
$('.master-advanced-left-tab').removeClass('master-advanced-left-tab-active');
elem.addClass('master-advanced-left-tab-active');
switch (elem.data('id')) {
case 'item1':
//show div for item1
break;
case 'item2':
//show div for item2
break;
default:
}
When I switch from tab I want to show the content from the class. I have tried with the toggle() function from JQuery. Also I have checked this stackoverflow post:
Bootstrap tab activation with JQuery
This is what I want but it didn't work for my solution because I don't use the nav tabs of bootstrap.
How can I show the content from each nav tab?
To show content you can simply call show() on it. You can also make your logic more DRY and extensible by converting the clickable div elements to a and using the href attribute to target the content to be displayed. This saves you having to write endless if conditions or switch cases, as it will work for an infinite number of tabs. It also means that, if required, you can open tabs when the page loads via the fragment of the URL. Try this:
let $tabs = $('.tab-content');
let $triggers = $('.master-advanced-left-tab').on('click', function(e) {
e.preventDefault();
$triggers.removeClass('master-advanced-left-tab-active');
var $elem = $(this).addClass('master-advanced-left-tab-active');
$tabs.hide();
$tabs.filter($elem.attr('href')).show();
});
$triggers.first().trigger('click');
.master-advanced-left-tab {
display: block;
overflow: hidden;
cursor: pointer;
padding-bottom: 10px;
padding-top: 10px;
}
.master-advanced-left-tab>p {
text-overflow: ellipsis;
height: 20px;
}
.master-advanced-left-tab-active {
color: #1C72DF;
border-bottom: 3px #1C72DF solid;
}
.tab-content {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
<a href="#item1" class="col-4 master-advanced-left-tab">
<p>Item 1</p>
</a>
<a href="#item2" class="col-4 master-advanced-left-tab">
<p>Item 2</p>
</a>
<a href="#item3" class="col-4 master-advanced-left-tab">
<p>Item 3</p>
</a>
</div>
<div class="tab-content" id="item1">
Show content from item 1
</div>
<div class="tab-content" id="item2">
Show content from item 2
</div>
<div class="tab-content" id="item3">
Show content from item 3
</div>
hide and show the method can be used for this purpose, Hope this helps
$('.master-advanced-left-tab').click(function(e){
$(this).addClass('master-advanced-left-tab-active').siblings().removeClass('master-advanced-left-tab-active')
var class1 = $(this).attr('data-id')
$('.'+class1+'').removeClass('hide').siblings().addClass('hide')
})
.master-advanced-left-tab {
overflow: hidden;
cursor: pointer;
padding-bottom: 10px;
padding-top: 10px;
}
.master-advanced-left-tab > p {
text-overflow: ellipsis;
height: 20px;
}
.master-advanced-left-tab-active {
color: #1C72DF;
border-bottom: 3px #1C72DF solid;
}
.hide
{
display:none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<div class="row">
<div class="col-4 master-advanced-left-tab master-advanced-left-tab-active" data-id="item1">
<p>Item 1</p>
</div>
<div class="col-4 master-advanced-left-tab" data-id="item2">
<p>Item 2</p>
</div>
<div class="col-4 master-advanced-left-tab" data-id="item3">
<p>Item 3</p>
</div>
</div>
<div class="wrap">
<div class="item1 ">
Show content from item 1
</div>
<div class="item2 hide">
Show content from item 2
</div>
<div class="item3 hide">
Show content from item 3
</div>
</div>
You can see my code:
<div class="row">
<div class="col-4 master-advanced-left-tab master-advanced-left-tab-active" data-id="item1">
<p>Item 1</p>
</div>
<div class="col-4 master-advanced-left-tab" data-id="item2">
<p>Item 2</p>
</div>
<div class="col-4 master-advanced-left-tab" data-id="item3">
<p>Item 3</p>
</div>
</div>
<div class="content-item item1 active">
Show content from item 1
</div>
<div class="content-item item2">
Show content from item 2
</div>
<div class="content-item item3">
Show content from item 3
</div>
Css: add more some line:
.content-item {
display: none
}
.content-item.active {
display: block
}
Then JS:
$('.master-advanced-left-tab').click(function (){
let elem = $(this);
$('.master-advanced-left-tab').removeClass('master-advanced-left-tab-active');
$('.content-item').removeClass('active');
elem.addClass('master-advanced-left-tab-active');
switch (elem.data('id')) {
case 'item1':
$('.item1').addClass('active')
break;
case 'item2':
$('.item2').addClass('active')
break;
default:
$('.item3').addClass('active')
}
})
This is a demo: https://codepen.io/phuongnm153/pen/vYBXBGM
Instead of swith you can use something more responsive like this:
function changeTab(element) {
// remove 'active' class from item and tab to prevent multiple
// tab selection
$('.master-advanced-left-tab').removeClass('active');
$('.tab').removeClass('active');
// add class 'active' to clicked item and proper tab
// tab class is taken from 'data-tab' property from item in html
$(element).addClass('active');
$('.tab.' + $(element).data('tab')).addClass('active');
}
// change tab to first at init to prevent none tab selected
// You can replace this by adding class 'active' to
// 'master-advanced-left-tab' and 'tab' item in html
changeTab( $('.master-advanced-left-tab:first-child') );
// not much to explain
$('.master-advanced-left-tab').on('click', function(){
changeTab(this);
})
.master-advanced-left-tab {
overflow: hidden;
cursor: pointer;
padding-bottom: 10px;
padding-top: 10px;
}
.master-advanced-left-tab > p {
text-overflow: ellipsis;
height: 20px;
}
/* changed from .master-advanced-left-tab-active to shorten code */
.master-advanced-left-tab.active {
color: #1C72DF;
border-bottom: 3px #1C72DF solid;
}
.tab {
height: 0;
overflow:hidden;
}
.tab.active {
height: auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
<!-- property 'data-tab' for js function to select proper tab -->
<div data-tab="item1" class="col-4 master-advanced-left-tab">
<p>Item 1</p>
</div>
<div data-tab="item2" class="col-4 master-advanced-left-tab">
<p>Item 2</p>
</div>
<div data-tab="item3" class="col-4 master-advanced-left-tab">
<p>Item 3</p>
</div>
</div>
<div class="tab item1">
Show content from item 1
</div>
<div class="tab item2">
Show content from item 2
</div>
<div class="tab item3">
Show content from item 3
</div>
Related
I created a simple tab filter, but I can't get it to work correctly. When the page first reloads i want the tab content to be hidden and I want the "more" to show on all the tabs, so far that's working. When you click on "more" the tab content should display, and "more" for that current tab should be hidden. I also need the tabs to toggle so i you click the tab again it should hide the tab content and show "more". Right now that issues that i'm having are that when you click on a tab the tab content of the other tabs show, but not the content of that tab, and also "more" doesn't show unless you click on another tab. Thanks!!
$(document).ready(function () {
$('.tab').click(function () {
var tabID = $(this).data('tabid');
$('.iconsContainer').children().removeClass('current');
$(this).addClass('current');
$('.tripctychContent-container').children().toggleClass('hideText');
$('.iconContainerMore').removeClass('hideText');
$('.iconContainerMore', this).toggleClass('hideText');
$('.tripctychContent-container').find("[data-blockid=" + tabID + "]").toggleClass('hideText');
});
});
.hideText{
display: none;
}
.tab{
cursor: pointer;
}
.iconsContainer{
display: flex;
justify-content: space-between;
}
.tab p:first-of-type:hover{
background: black;
}
.tab p:first-of-type{
padding: 15px 30px;
background: blue;
color: white;
}
.current p:first-of-type{
background: black !important;
}
.tripctychContent-container p{
background: red;
color: white;
}
p{
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="iconsContainer">
<a class="tab" data-tabid="topic1">
<div>
<p>Topic 1 title</p>
<p class="iconContainerMore">More</p>
</div>
</a>
<a class="tab" data-tabid="topic2">
<div>
<p>Topic 2 title</p>
<p class="iconContainerMore">More</p>
</div>
</a>
<a class="tab" data-tabid="topic3">
<div>
<p>Topic 3 title</p>
<p class="iconContainerMore">More</p>
</div>
</a>
</div>
<div class="tripctychContent-container">
<div class="field--name-field-topic-1-content hideText" data-blockid="topic1">
<p>Topic 1 body</p>
</div>
<div class="field--name-field-topic-2-content hideText" data-blockid="topic2">
<p>Topic 2 body</p>
</div>
<div class="field--name-field-topic-3-content hideText" data-blockid="topic3">
<p>Topic 3 body</p>
</div>
</div>
HERE!
just update the JS:
$(document).ready(function () {
$('.tab').click(function () {
var tabID = $(this).data('tabid');
//alert(tabID);
$('.iconsContainer').children().removeClass('current');
$(this).addClass('current');
//$('.tripctychContent-container').toggleClass('hideText');
$('.iconContainerMore').removeClass('hideText');
$('.iconContainerMore', this).toggleClass('hideText');
$( ".tripctychContent-container>div").hide();
$( ".tripctychContent-container>div[data-blockid=" + tabID + " ]" ).show();
$('.tripctychContent-container').find("[data-blockid=" + tabID + "]").toggleClass('hideText');
});
});
You don't need to removeClass explicitly if you are already using toggleClass for the same.
A little change in your JS function in the end.
$(document).ready(function () {
$('.tab').click(function () {
var tabID = $(this).data('tabid');
alert(tabID);
$('.iconsContainer').children().removeClass('current');
$(this).addClass('current');
$('.tripctychContent-container').children().toggleClass('hideText');
$('.iconContainerMore').removeClass('hideText');
$('.iconContainerMore', this).toggleClass('hideText');
$('.field-class').hide()
$("[data-blockid=" + tabID + "]").show();
});
});
And have assigned a common class to all the tab content
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="iconsContainer">
<a class="tab" data-tabid="topic1">
<div>
<p>Topic 1 title</p>
<p class="iconContainerMore">More</p>
</div>
</a>
<a class="tab" data-tabid="topic2">
<div>
<p>Topic 2 title</p>
<p class="iconContainerMore">More</p>
</div>
</a>
<a class="tab" data-tabid="topic3">
<div>
<p>Topic 3 title</p>
<p class="iconContainerMore">More</p>
</div>
</a>
</div>
<div class="tripctychContent-container">
<div class="field-class hideText" data-blockid="topic1">
<p>Topic 1 body</p>
</div>
<div class="field-class hideText" data-blockid="topic2">
<p>Topic 2 body</p>
</div>
<div class="field-class hideText" data-blockid="topic3">
<p>Topic 3 body</p>
</div>
</div>
Hope this helps!
I have this script so that I can make tabs very easy. But I can't have two, three, four and so on - tab function on the same page. I've tried to wrap into an each.function, but I just don't work for me. The tab changes on both rows at the same time :/
I use WordPress so the HTML markup is a little long so I've created a Codepen.
I also want this: if you click on the selected tab, I want it to be not active, like an accordion.
Markup here:
(function($) {
$('.section .row').each(function() {
$(this).find('.nav_wrap .tab').on('click', function() {
show_content($(this).index());
});
});
show_content(99); // choose 0 to start with first tab
function show_content(index) {
$('.row').each(function() {
// Make the content visible
$(this).find('.content_wrap .content.visible').removeClass('visible');
$(this).find('.content_wrap .content:nth-of-type(' + (index + 1) + ')').addClass('visible');
// Set the tab to selected
$(this).find('.nav_wrap .tab.selected').removeClass('selected');
$(this).find('.nav_wrap .tab:nth-of-type(' + (index + 1) + ')').addClass('selected');
});
}
})(jQuery);
.row {
background: lightblue;
margin-bottom: 80px;
}
.nav_wrap, .content_wrap {
display: flex;
}
.tab, .content {
padding: 20px;
}
.tab {
cursor: pointer;
}
.tab:hover,
.tab.selected {
background:pink;
}
.content_wrap .content {
display: none;
}
.content_wrap .content.visible {
display: flex;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="section">
<div class="row">
<div class="nav_wrap">
<div class="tab">Tab 1</div>
<div class="tab">Tab 2</div>
<div class="tab">Tab 3</div>
</div>
<div class="content_wrap">
<div class="content">Tab 1 content goes here</div>
<div class="content">Tab 2 content goes here</div>
<div class="content">Tab 3 content goes here</div>
</div>
</div>
<div class="row">
<div class="nav_wrap">
<div class="tab">Tab 1</div>
<div class="tab">Tab 2</div>
<div class="tab">Tab 3</div>
</div>
<div class="content_wrap">
<div class="content">Tab 1 content goes here</div>
<div class="content">Tab 2 content goes here</div>
<div class="content">Tab 3 content goes here</div>
</div>
</div>
</div>
Find the index of clicked element and add class to next content of clicked element based on clicked element index. Here I have updated your above code into one function. And I have checked if the clicked has selected class or not with hasClass() method. I guess this is what you are looking for.
(function($) {
$('.nav_wrap .tab').on('click', function() {
if(!$(this).hasClass('selected')) {
$(this).parent().find('.selected').removeClass('selected');
}
$(this).toggleClass('selected');
if(!$(this).parent().next().find('.content').eq($(this).index()).hasClass('visible')) {
$(this).parent().next().find('.visible').removeClass('visible');
} $(this).parent().next().find('.content').eq($(this).index()).toggleClass('visible');
});
})(jQuery);
.row {
background: lightblue;
margin-bottom: 80px;
}
.nav_wrap, .content_wrap {
display: flex;
}
.tab, .content {
padding: 20px;
}
.tab {
cursor: pointer;
}
.tab:hover,
.tab.selected {
background:pink;
}
.content_wrap .content {
display: none;
}
.content_wrap .content.visible {
display: flex;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="section">
<div class="row">
<div class="nav_wrap">
<div class="tab">Tab 1</div>
<div class="tab">Tab 2</div>
<div class="tab">Tab 3</div>
</div>
<div class="content_wrap">
<div class="content">Tab 1 content goes here</div>
<div class="content">Tab 2 content goes here</div>
<div class="content">Tab 3 content goes here</div>
</div>
</div>
<div class="row">
<div class="nav_wrap">
<div class="tab">Tab 1</div>
<div class="tab">Tab 2</div>
<div class="tab">Tab 3</div>
</div>
<div class="content_wrap">
<div class="content">Tab 1 content goes here</div>
<div class="content">Tab 2 content goes here</div>
<div class="content">Tab 3 content goes here</div>
</div>
</div>
</div>
I'm trying use append to give each button it's own div (.modal-item) that can be created and removed inside of the .modal container when the button is clicked. Each .item has it's own button and different content nested inside.
What I need as an example: If I click the button labelled Btn 1, I want a .modal-item div created inside of .modal that has the content from the Btn 1 .item. If I click Btn 1 again, it is removed. The same goes for each of the buttons.
The buttons should act as a checkbox for creating and removing the .modal-items. So in other words, the adding/removing of each .modal-item is handled by it's button.
$(function() {
$('#btn').click(function() {
var newDiv = $('<div class="modal-item"><h4><a>Dynamic Title</a></h4> </div>');
$('.modal').append(newDiv);
});
});
.container {
display: flex;
border: 1px solid blue;
}
.item,
.modal-item {
width: 100px;
border: 1px solid;
}
.modal {
display: flex;
border: 1px solid green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="item">
<button id="btn">Btn 1</button>
<h4> Test 1 </h4>
<div class="subtitle"> Title 1 </div>
<div class="info"> This is Info / Description 1. </div>
</div>
<div class="item">
<button id="btn">Btn 2</button>
<h4> Test 2 </h4>
<div class="subtitle"> Title 2 </div>
<div class="info"> This is Info / Description 2. </div>
</div>
<div class="item">
<button id="btn">Btn 3</button>
<h4> Test 3 </h4>
<div class="subtitle"> Title 3 </div>
<div class="info"> This is Info / Description 3. </div>
</div>
</div>
<div class="modal"></div>
1st: id must be unique so you need to change id="btn" to class="btn"
2nd: by using data attribute for each btn and pass it to the modal-item div it can be done
$(function() {
$('.btn').click(function() {
var newDiv = $('<div data-btn="'+$(this).attr("data-btn")+'" class="modal-item"><h4><a>Dynamic Title'+ ($(this).closest('.item').index() + 1) +'</a></h4> </div>');
if($('.modal .modal-item[data-btn="'+$(this).attr("data-btn")+'"]').length < 1 ){
$('.modal').append(newDiv);
}else{
$('.modal .modal-item[data-btn="'+$(this).attr("data-btn")+'"]').remove();
}
});
});
.container {
display: flex;
border: 1px solid blue;
}
.item,
.modal-item {
width: 100px;
border: 1px solid;
}
.modal {
display: flex;
border: 1px solid green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="item">
<button class="btn" data-btn="btn1">Btn 1</button>
<h4> Test 1 </h4>
<div class="subtitle"> Title 1 </div>
<div class="info"> This is Info / Description 1. </div>
</div>
<div class="item">
<button class="btn" data-btn="btn2">Btn 2</button>
<h4> Test 2 </h4>
<div class="subtitle"> Title 2 </div>
<div class="info"> This is Info / Description 2. </div>
</div>
<div class="item">
<button class="btn" data-btn="btn3">Btn 3</button>
<h4> Test 3 </h4>
<div class="subtitle"> Title 3 </div>
<div class="info"> This is Info / Description 3. </div>
</div>
</div>
<div class="modal"></div>
below is my current html layout, inside my .container class I have two <span> tags with classes of .download-btn and .save-btn. I want, whenever page load, remove those <span> from there and postioning near <div class="share"></div>
tag.
current layout
<div class="container">
<div class="col-md-6 col-center">
<span class="download-btn">download</span>
<span class="save-btn">save</span>
</div>
<div id="options">
<div class="share"></div>
</div>
expected layout when page load
<div class="container">
<div class="col-md-6 col-center">
</div>
<div id="options">
<span class="download-btn">download</span>
<span class="save-btn">save</span>
<div class="share"></div>
</div>
</div>
pls advice how to proceed using js ?
Using jQuery,
It can be done in a one line of code.
$("#options").prepend($(".save-btn")).prepend($(".download-btn"));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="col-md-6 col-center">
<span class="download-btn">download</span>
<span class="save-btn">save</span>
</div>
<div id="options">
<div class="share"></div>
</div>
</div>
Use prepend() to move the buttons to the beginning of the element with ID options:
$('#options').prepend($('.download-btn, .save-btn'));
In this example I'm removing this two buttons from their places, and append them before <div class="share"></div> (and I have added content "share" to this div to see the difference):
var downloadBtn = $('.download-btn');
var saveBtn = $('.save-btn');
$('.share').before(saveBtn).before(downloadBtn);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="col-md-6 col-center">
<span class="download-btn">download</span>
<span class="save-btn">save</span>
</div>
<div id="options">
<div class="share">share</div>
</div>
Use button for for the buttons. It's semantically correct and accessible.
$(window).on('load', function() {
var download = $('.download-btn'),
save = $('.save-btn'),
options = $('#options');
download.remove();
save.remove();
options.prepend(download, save);
});
.container {
border: .1rem solid red;
min-height: 5rem;
margin-bottom: 1rem;
}
#options {
border: .1rem solid blue;
min-height: 100px;
}
button {
padding: 1rem;
background-color: #ddd;
display: inline-block;
margin: .5rem;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="col-md-6 col-center">
<button class="download-btn">download</button>
<button class="save-btn">save</button>
</div>
</div>
<div id="options">
<div class="share"></div>
</div>
I have 4 divs with same Class and Id. What I am looking for is to remove display-none-class on that specific div whenever #button is clicked.
What I have done now is to give an additional class name to each div so they are more "recognizable" for jQuery.
Here is my code:
html
<div class="parentdiv">
<h3 id="button">remove class</h3>
<div class="display-none" id="element">
Show me on button click
</div>
</div>
jquery
$('h3#button').each(function(i){
$(this).addClass('remove-btn-' + (i+1));
});
$('div#element').each(function(i){
$(this).addClass('remove-this-' + (i+1));
});
So What I am looking for is to loop through remove-this-1, remove-this-2 etc and remove display-none class when ever remove-btn-1, remove-btn-2 etc is clicked.
Use one more class to the div which has display-none class
give same class to each button
wrap them in a parent them
use this to achieve your goal
Whenever you click on the button, it will look for class box of current clicked the button. For demo purpose - I have applied CSS to display-none class, So that you can see changes.
$(document).ready(function(){
$('.button').click(function(){
$(this).prev('.box').removeClass('display-none');
});
});
.display-none {
display: inline-block;
padding: 5px;
background: tomato;
color: #fff;
border-radius: 3px;
}
.button {
display: inline-block;
padding: 5px;
background: steelblue;
color: #fff;
border-radius: 3px;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
<div class="display-none box">Lorem ispum 0...</div>
<p class="button">Remove Class</p>
</div>
<div class="parent">
<div class="display-none box">Lorem ispum 1...</div>
<p class="button">Remove Class</p>
</div>
<div class="parent">
<div class="display-none box">Lorem ispum 2...</div>
<p class="button">Remove Class</p>
</div>
<div class="parent">
<div class="display-none box">Lorem ispum 3...</div>
<p class="button">Remove Class</p>
</div>
Are you looking for something like this
$('.button').click(function(){
$(this).next().removeClass('display-none');
});
.display-none{
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parentdiv">
<h3 class="button">remove class</h3>
<div class="display-none element">
Show me on button click 1
</div>
</div>
<div class="parentdiv">
<h3 class="button">remove class</h3>
<div class="display-none element">
Show me on button click 2
</div>
</div>
<div class="parentdiv">
<h3 class="button">remove class</h3>
<div class="display-none element">
Show me on button click 3
</div>
</div>
<div class="parentdiv">
<h3 class="button">remove class</h3>
<div class="display-none element">
Show me on button click 4
</div>
</div>
First of all the id (#) value has to be unique. I suggest you creating unique ids.
For removing a class from an element with jquery you can use the .removeClass('class_name')