Skip to content

Instantly share code, notes, and snippets.

@Nikolasgrizli
Last active August 18, 2019 23:03
Show Gist options
  • Save Nikolasgrizli/0b6ab779f765525435450241262d2910 to your computer and use it in GitHub Desktop.
Save Nikolasgrizli/0b6ab779f765525435450241262d2910 to your computer and use it in GitHub Desktop.
Bootstrap 4 tab desctop/accordion mobile
<div class="tab-accordio__wrapper">
<!-- heading -->
<ul id="tab-accordion" class="nav nav-tabs d-none d-sm-flex mt-3" role="tablist">
<li class="nav__item nav-item">
<a role="tab" class="nav-link active show" data-toggle="tab" href="#home"
aria-selected="true">
Heading 1
</a>
</li>
<li class="nav__item nav-item">
<a role="tab" class="nav-link" data-toggle="tab" href="#invites"
aria-selected="false">
Heading 2
</a>
</li>
</ul>
<!-- body -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane active show" id="home">
Content 1
Lorem ipsum dolor sit amet consectetur adipisicing elit. Impedit in voluptates,
veniam esse praesentium vero odit ullam sed saepe omnis quam dolor facere sit repudiandae,
sapiente iure distinctio earum consectetur?
</div>
<div role="tabpanel" class="tab-pane" id="invites">
Content 2
Lorem ipsum dolor sit amet consectetur adipisicing elit. Impedit in voluptates,
veniam esse praesentium vero odit ullam sed saepe omnis quam dolor facere sit repudiandae,
sapiente iure distinctio earum consectetur?
</div>
</div>
</div>
// heavily modified BS4 version of https://github.com/openam/bootstrap-responsive-tabs
// need dept - jquery & bootstrap js
var fakewaffle = (function($, fakewaffle) {
'use strict';
fakewaffle.responsiveTabs = function(collapseDisplayed) {
fakewaffle.currentPosition = 'tabs';
var tabGroups = $('#tab-accordion');
var hidden = '';
var visible = '';
var activeTab = '';
hidden = ' d-none d-md-flex';
visible = ' d-md-none';
$.each(tabGroups, function(index) {
var collapseDiv;
var $tabGroup = $(this);
var tabs = $tabGroup.find('li a');
if ($tabGroup.attr('id') === undefined) {
$tabGroup.attr('id', 'tabs-' + index);
}
collapseDiv = $('<div></div>', {
'class': 'card-soup responsive' + visible,
'id': 'collapse-' + $tabGroup.attr('id')
});
$.each(tabs, function() {
var $this = $(this);
var oldLinkClass = $this.attr('class') === undefined ? '' : $this.attr('class');
var newLinkClass = 'accordion-toggle';
var oldParentClass = $this.parent().attr('class') === undefined ? '' : $this.parent().attr('class');
var newParentClass = 'card';
var newHash = $this.get(0).hash.replace('#', 'collapse-');
if (oldLinkClass.length > 0) {
newLinkClass += ' ' + oldLinkClass;
}
if (oldParentClass.length > 0) {
oldParentClass = oldParentClass.replace(/\bactive\b/g, '');
newParentClass += ' ' + oldParentClass;
newParentClass = newParentClass.replace(/\s{2,}/g, ' ');
newParentClass = newParentClass.replace(/^\s+|\s+$/g, '');
}
if ($this.parent().hasClass('active')) {
activeTab = '#' + newHash;
}
collapseDiv.append(
$('<div>').attr('class', newParentClass).html(
$('<div>').attr('class', 'card-header').html(
$('<h4>').attr('class', 'card-title').html(
$('<a>', {
'class': newLinkClass,
'data-toggle': 'collapse',
'data-parent': '#collapse-' + $tabGroup.attr('id'),
'href': '#' + newHash,
'html': $this.html()
}).removeClass('collapse')
)
)
).append('<div class="collapse" id="'+ newHash +'"></div>')
);
});
$tabGroup.next().after(collapseDiv);
$tabGroup.addClass(hidden);
$('.tab-content.responsive').addClass(hidden);
if (activeTab) {
$(activeTab).collapse('show');
}
});
fakewaffle.checkResize();
fakewaffle.bindTabToCollapse();
};
fakewaffle.checkResize = function() {
if ($('.card-soup.responsive').is(':visible') === true && fakewaffle.currentPosition === 'tabs') {
fakewaffle.tabToPanel();
fakewaffle.currentPosition = 'panel';
} else if ($('.card-soup.responsive').is(':visible') === false && fakewaffle.currentPosition === 'panel') {
fakewaffle.panelToTab();
fakewaffle.currentPosition = 'tabs';
}
};
fakewaffle.tabToPanel = function() {
var tabGroups = $('#tab-accordion');
$.each(tabGroups, function(index, tabGroup) {
// Find the tab
var tabContents = $(tabGroup).next('.tab-content').find('.tab-pane');
$.each(tabContents, function(index, tabContent) {
// Find the id to move the element to
var destinationId = $(tabContent).attr('id').replace(/^/, '#collapse-');
// Convert tab to panel and move to destination
$(tabContent)
.removeClass('tab-pane')
.addClass('card-body fw-previous-tab-pane')
.appendTo($(destinationId));
});
});
};
fakewaffle.panelToTab = function() {
var panelGroups = $('.card-soup.responsive');
$.each(panelGroups, function(index, panelGroup) {
var destinationId = $(panelGroup).attr('id').replace('collapse-', '#');
var destination = $(destinationId).next('.tab-content')[0];
// Find the panel contents
var panelContents = $(panelGroup).find('.card-body.fw-previous-tab-pane');
// Convert to tab and move to destination
panelContents
.removeClass('card-body fw-previous-tab-pane')
.addClass('tab-pane')
.appendTo($(destination));
});
};
fakewaffle.bindTabToCollapse = function() {
var tabs = $('.nav-tabs.responsive').find('li a');
var collapse = $('.card-soup.responsive').find('.card-collapse');
// Toggle the panels when the associated tab is toggled
tabs.on('shown.bs.tab', function(e) {
if (fakewaffle.currentPosition === 'tabs') {
var $current = $(e.currentTarget.hash.replace(/#/, '#collapse-'));
$current.collapse('show');
if (e.relatedTarget) {
var $previous = $(e.relatedTarget.hash.replace(/#/, '#collapse-'));
$previous.collapse('hide');
}
}
});
// Toggle the tab when the associated panel is toggled
collapse.on('shown.bs.collapse', function(e) {
if (fakewaffle.currentPosition === 'panel') {
// Activate current tabs
var current = $(e.target).context.id.replace(/collapse-/g, '#');
$('a[href="' + current + '"]').tab('show');
// Update the content with active
var panelGroup = $(e.currentTarget).closest('.card-soup.responsive');
$(panelGroup).find('.card-body').removeClass('active');
$(e.currentTarget).find('.card-body').addClass('active');
}
});
};
$(window).resize(function() {
fakewaffle.checkResize();
});
return fakewaffle;
}(window.jQuery, fakewaffle || {}));
window.addEventListener('load', function(){
fakewaffle.responsiveTabs();
});
// tabs
.profile-body{
@media only screen and (max-width: 767px) {
.card-soup{
.card,
.card-title{
margin-bottom: 0;
}
.card.nav-item:not(:first-child) .card-header {
margin-top: -1px;
}
.card-header{
background-color: #fff;
padding: 0;
margin-bottom: 0;
border: 1px solid rgba(0,0,0,.125);
& ~ .collapse{
border-left: 1px solid rgba(0,0,0,.125);
border-right: 1px solid rgba(0,0,0,.125);
}
}
.accordion-toggle{
display: block !important;
color: #495057;
background-color: #fff;
border-color: #dee2e6 #dee2e6 #fff;
font-size: 14px;
font-weight: 700;
padding: 7px 21px 8px;
}
.nav-link {
position: relative;
}
.nav-link::after {
content: "";
position: absolute;
top: ~"calc(50% - 8px)";
right: 5px;
width: 17px;
height: 17px;
background-image: url("../img/svg/chevron-down.svg");
background-size: cover;
transform: rotate(180deg);
transition: transform 0.22s ease;
}
.nav-link.collapsed::after {
transform: rotate(0deg);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment