123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- !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);
|