239 lines
8.6 KiB
JavaScript
239 lines
8.6 KiB
JavaScript
|
!function ($) {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
// TABCOLLAPSE CLASS DEFINITION
|
||
|
// ======================
|
||
|
|
||
|
var TabCollapse = function (el, options) {
|
||
|
this.options = options;
|
||
|
this.$tabs = $(el);
|
||
|
|
||
|
this._accordionVisible = false; //content is attached to tabs at first
|
||
|
this._initAccordion();
|
||
|
this._checkStateOnResize();
|
||
|
|
||
|
|
||
|
// checkState() has gone to setTimeout for making it possible to attach listeners to
|
||
|
// shown-accordion.bs.tabcollapse event on page load.
|
||
|
// See https://github.com/flatlogic/bootstrap-tabcollapse/issues/23
|
||
|
var that = this;
|
||
|
setTimeout(function() {
|
||
|
that.checkState();
|
||
|
}, 0);
|
||
|
};
|
||
|
|
||
|
TabCollapse.DEFAULTS = {
|
||
|
accordionClass: 'visible-xs',
|
||
|
tabsClass: 'hidden-xs',
|
||
|
accordionTemplate: function(heading, groupId, parentId, active) {
|
||
|
return '<div class="panel panel-default">' +
|
||
|
' <div class="panel-heading">' +
|
||
|
' <h4 class="panel-title">' +
|
||
|
' </h4>' +
|
||
|
' </div>' +
|
||
|
' <div id="' + groupId + '" class="panel-collapse collapse ' + (active ? 'in' : '') + '">' +
|
||
|
' <div class="panel-body js-tabcollapse-panel-body">' +
|
||
|
' </div>' +
|
||
|
' </div>' +
|
||
|
'</div>'
|
||
|
|
||
|
}
|
||
|
};
|
||
|
|
||
|
TabCollapse.prototype.checkState = function(){
|
||
|
if (this.$tabs.is(':visible') && this._accordionVisible){
|
||
|
this.showTabs();
|
||
|
this._accordionVisible = false;
|
||
|
} else if (this.$accordion.is(':visible') && !this._accordionVisible){
|
||
|
this.showAccordion();
|
||
|
this._accordionVisible = true;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
TabCollapse.prototype.showTabs = function(){
|
||
|
var view = this;
|
||
|
this.$tabs.trigger($.Event('show-tabs.bs.tabcollapse'));
|
||
|
|
||
|
var $panelHeadings = this.$accordion.find('.js-tabcollapse-panel-heading').detach();
|
||
|
|
||
|
$panelHeadings.each(function() {
|
||
|
var $panelHeading = $(this),
|
||
|
$parentLi = $panelHeading.data('bs.tabcollapse.parentLi');
|
||
|
|
||
|
var $oldHeading = view._panelHeadingToTabHeading($panelHeading);
|
||
|
|
||
|
$parentLi.removeClass('active');
|
||
|
if ($parentLi.parent().hasClass('dropdown-menu') && !$parentLi.siblings('li').hasClass('active')) {
|
||
|
$parentLi.parent().parent().removeClass('active');
|
||
|
}
|
||
|
|
||
|
if (!$oldHeading.hasClass('collapsed')) {
|
||
|
$parentLi.addClass('active');
|
||
|
$('.tab-pane').removeClass('active');
|
||
|
$($panelHeading.attr('href')).addClass('active');
|
||
|
if ($parentLi.parent().hasClass('dropdown-menu')) {
|
||
|
$parentLi.parent().parent().addClass('active');
|
||
|
}
|
||
|
} else {
|
||
|
$oldHeading.removeClass('collapsed');
|
||
|
}
|
||
|
|
||
|
$parentLi.append($panelHeading);
|
||
|
});
|
||
|
|
||
|
if (!$('li').hasClass('active')) {
|
||
|
$('li').first().addClass('active')
|
||
|
}
|
||
|
|
||
|
var $panelBodies = this.$accordion.find('.js-tabcollapse-panel-body');
|
||
|
$panelBodies.each(function(){
|
||
|
var $panelBody = $(this),
|
||
|
$tabPane = $panelBody.data('bs.tabcollapse.tabpane');
|
||
|
$tabPane.append($panelBody.contents().detach());
|
||
|
});
|
||
|
this.$accordion.html('');
|
||
|
|
||
|
if(this.options.updateLinks) {
|
||
|
var $tabContents = this.getTabContentElement();
|
||
|
$tabContents.find('[data-toggle-was="tab"], [data-toggle-was="pill"]').each(function() {
|
||
|
var $el = $(this);
|
||
|
var href = $el.attr('href').replace(/-collapse$/g, '');
|
||
|
$el.attr({
|
||
|
'data-toggle': $el.attr('data-toggle-was'),
|
||
|
'data-toggle-was': '',
|
||
|
'data-parent': '',
|
||
|
href: href
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
|
||
|
this.$tabs.trigger($.Event('shown-tabs.bs.tabcollapse'));
|
||
|
};
|
||
|
|
||
|
TabCollapse.prototype.getTabContentElement = function(){
|
||
|
var $tabContents = $(this.options.tabContentSelector);
|
||
|
if($tabContents.length === 0) {
|
||
|
$tabContents = this.$tabs.siblings('.tab-content');
|
||
|
}
|
||
|
return $tabContents;
|
||
|
};
|
||
|
|
||
|
TabCollapse.prototype.showAccordion = function(){
|
||
|
this.$tabs.trigger($.Event('show-accordion.bs.tabcollapse'));
|
||
|
|
||
|
var $headings = this.$tabs.find('li:not(.dropdown) [data-toggle="tab"], li:not(.dropdown) [data-toggle="pill"]'),
|
||
|
view = this;
|
||
|
$headings.each(function(){
|
||
|
var $heading = $(this),
|
||
|
$parentLi = $heading.parent();
|
||
|
$heading.data('bs.tabcollapse.parentLi', $parentLi);
|
||
|
view.$accordion.append(view._createAccordionGroup(view.$accordion.attr('id'), $heading.detach()));
|
||
|
});
|
||
|
|
||
|
if(this.options.updateLinks) {
|
||
|
var parentId = this.$accordion.attr('id');
|
||
|
var $selector = this.$accordion.find('.js-tabcollapse-panel-body');
|
||
|
$selector.find('[data-toggle="tab"], [data-toggle="pill"]').each(function() {
|
||
|
var $el = $(this);
|
||
|
var href = $el.attr('href') + '-collapse';
|
||
|
$el.attr({
|
||
|
'data-toggle-was': $el.attr('data-toggle'),
|
||
|
'data-toggle': 'collapse',
|
||
|
'data-parent': '#' + parentId,
|
||
|
href: href
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
|
||
|
this.$tabs.trigger($.Event('shown-accordion.bs.tabcollapse'));
|
||
|
};
|
||
|
|
||
|
TabCollapse.prototype._panelHeadingToTabHeading = function($heading) {
|
||
|
var href = $heading.attr('href').replace(/-collapse$/g, '');
|
||
|
$heading.attr({
|
||
|
'data-toggle': 'tab',
|
||
|
'href': href,
|
||
|
'data-parent': ''
|
||
|
});
|
||
|
return $heading;
|
||
|
};
|
||
|
|
||
|
TabCollapse.prototype._tabHeadingToPanelHeading = function($heading, groupId, parentId, active) {
|
||
|
$heading.addClass('js-tabcollapse-panel-heading ' + (active ? '' : 'collapsed'));
|
||
|
$heading.attr({
|
||
|
'data-toggle': 'collapse',
|
||
|
'data-parent': '#' + parentId,
|
||
|
'href': '#' + groupId
|
||
|
});
|
||
|
return $heading;
|
||
|
};
|
||
|
|
||
|
TabCollapse.prototype._checkStateOnResize = function(){
|
||
|
var view = this;
|
||
|
$(window).resize(function(){
|
||
|
clearTimeout(view._resizeTimeout);
|
||
|
view._resizeTimeout = setTimeout(function(){
|
||
|
view.checkState();
|
||
|
}, 100);
|
||
|
});
|
||
|
};
|
||
|
|
||
|
|
||
|
TabCollapse.prototype._initAccordion = function(){
|
||
|
var randomString = function() {
|
||
|
var result = "",
|
||
|
possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||
|
for( var i=0; i < 5; i++ ) {
|
||
|
result += possible.charAt(Math.floor(Math.random() * possible.length));
|
||
|
}
|
||
|
return result;
|
||
|
};
|
||
|
|
||
|
var srcId = this.$tabs.attr('id'),
|
||
|
accordionId = (srcId ? srcId : randomString()) + '-accordion';
|
||
|
|
||
|
this.$accordion = $('<div class="panel-group ' + this.options.accordionClass + '" id="' + accordionId +'"></div>');
|
||
|
this.$tabs.after(this.$accordion);
|
||
|
this.$tabs.addClass(this.options.tabsClass);
|
||
|
this.getTabContentElement().addClass(this.options.tabsClass);
|
||
|
};
|
||
|
|
||
|
TabCollapse.prototype._createAccordionGroup = function(parentId, $heading){
|
||
|
var tabSelector = $heading.attr('data-target'),
|
||
|
active = $heading.data('bs.tabcollapse.parentLi').is('.active');
|
||
|
|
||
|
if (!tabSelector) {
|
||
|
tabSelector = $heading.attr('href');
|
||
|
tabSelector = tabSelector && tabSelector.replace(/.*(?=#[^\s]*$)/, ''); //strip for ie7
|
||
|
}
|
||
|
|
||
|
var $tabPane = $(tabSelector),
|
||
|
groupId = $tabPane.attr('id') + '-collapse',
|
||
|
$panel = $(this.options.accordionTemplate($heading, groupId, parentId, active));
|
||
|
$panel.find('.panel-heading > .panel-title').append(this._tabHeadingToPanelHeading($heading, groupId, parentId, active));
|
||
|
$panel.find('.panel-body').append($tabPane.contents().detach())
|
||
|
.data('bs.tabcollapse.tabpane', $tabPane);
|
||
|
|
||
|
return $panel;
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
// TABCOLLAPSE PLUGIN DEFINITION
|
||
|
// =======================
|
||
|
|
||
|
$.fn.tabCollapse = function (option) {
|
||
|
return this.each(function () {
|
||
|
var $this = $(this);
|
||
|
var data = $this.data('bs.tabcollapse');
|
||
|
var options = $.extend({}, TabCollapse.DEFAULTS, $this.data(), typeof option === 'object' && option);
|
||
|
|
||
|
if (!data) $this.data('bs.tabcollapse', new TabCollapse(this, options));
|
||
|
});
|
||
|
};
|
||
|
|
||
|
$.fn.tabCollapse.Constructor = TabCollapse;
|
||
|
|
||
|
|
||
|
}(window.jQuery);
|