UNPKG

6.04 kBJavaScriptView Raw
1
2export var TabList = {
3
4 _tabContents: {},
5
6 define(tab_content_id) {
7
8 // get tab content element
9 var tab_content = document.getElementById(tab_content_id);
10 if (tab_content === null) {
11 console.error('Bunny TabList error: tab content with ID "' + tab_content_id + '" not found.');
12 return false;
13 }
14
15 var tab_list_el = null;
16 var active_tab_panel = null;
17 var active_link = null;
18
19 // get tab panels of tab content
20 var tab_panels = [];
21 var tab_list_links = [];
22 tab_content.querySelectorAll('[role="tabpanel"]').forEach(function (tab_panel) {
23 if (tab_panel.id === '') {
24 console.error('Bunny TabList error: tab panel does not contain ID attribute.');
25 console.error(tab_panel);
26 return false;
27 }
28
29 // check if tab panel is active
30 if (tab_panel.classList.contains('active')) {
31 active_tab_panel = tab_panel;
32 }
33
34 // get tab list and link (UI control) for this tab content if exists
35 var nav_el = null;
36 for (var k = 0; k < document.links.length; k++) {
37 if (document.links[k].getAttribute('href') === '#' + tab_panel.id) {
38 nav_el = document.links[k];
39 tab_list_el = nav_el.parentNode.parentNode;
40 active_link = tab_list_el.getElementsByClassName('active')[0];
41 tab_list_links = tab_list_el.getElementsByTagName('a');
42 break;
43 }
44 }
45
46 // assign tab panel element and associated nav element
47 tab_panels[tab_panel.id] = {
48 el: tab_panel,
49 nav: nav_el
50 };
51 });
52
53 this._tabContents[tab_content_id] = {
54 el: tab_content,
55 tabPanels: tab_panels,
56 tabList: tab_list_el,
57 tabListLinks: tab_list_links,
58 activeTabPanel: active_tab_panel,
59 activeLink: active_link
60 };
61
62 this.assignTabLinkClickEvent(tab_content_id);
63
64 },
65
66 assignTabLinkClickEvent(tab_content_id) {
67 var self = this;
68 this.get(tab_content_id).tabListLinks.forEach(function(tab_link) {
69 var tab_panel_id = tab_link.getAttribute('href').substring(1);
70 tab_link.addEventListener('click', function(e){
71 e.preventDefault();
72 self.changeTab(tab_panel_id);
73 });
74 });
75 },
76
77 getTabContentIdByTabPanelId(tab_panel_id) {
78 for (var tab_content_id in this._tabContents) {
79 if (this._tabContents[tab_content_id].tabPanels[tab_panel_id] !== undefined) {
80 return tab_content_id;
81 }
82 }
83 return false;
84 },
85
86 changeTab: function(tab_panel_id) {
87
88 var tab_content_id = this.getTabContentIdByTabPanelId(tab_panel_id);
89 if (tab_content_id === false) {
90 console.error('Bunny TabList.changeTab() error: unable to get tab content ' +
91 'associated with tab panel with ID "' + tab_panel_id + '". ' +
92 'May be tab content is not defined and should be defined' +
93 ' with TabList.define() first or does not have ID');
94 return false;
95 }
96 var tab_content = this.get(tab_content_id);
97
98 var active_tab_panel = tab_content.activeTabPanel;
99
100 var active_link = tab_content.activeLink; // might be null if tab content is not associated with any nav
101 var nav_link = tab_content.tabPanels[tab_panel_id].nav; // if active_link null, this also null
102
103 if (active_link !== null) {
104 // remove active state from old active link
105 active_link.setAttribute('aria-expanded', 'false');
106 active_link.classList.remove('active');
107 // add active state to new link
108 nav_link.setAttribute('aria-expanded', 'true');
109 nav_link.classList.add('active');
110 }
111
112 // remove active state from old tab panel
113 if (active_tab_panel.classList.contains('fade')) {
114 active_tab_panel.classList.remove('active');
115 setTimeout(function() {
116 active_tab_panel.setAttribute('aria-expanded', 'false');
117 active_tab_panel.classList.remove('active');
118 }, 150);
119 } else {
120 active_tab_panel.setAttribute('aria-expanded', 'false');
121 active_tab_panel.classList.remove('active');
122 }
123 // add active state to new tab pane
124 var tab_panel = document.getElementById(tab_panel_id);
125 if (tab_panel.classList.contains('fade')) {
126 setTimeout(function() {
127 tab_panel.setAttribute('aria-expanded', 'true');
128 tab_panel.classList.add('active');
129 //tab_panel.classList.add('in');
130 }, 150);
131 } else {
132 tab_panel.setAttribute('aria-expanded', 'true');
133 tab_panel.classList.add('active');
134 }
135
136 if (active_link !== null) {
137 // set active link to a new link
138 tab_content.activeLink = nav_link;
139 }
140
141 // set active tab panel to new tab pane
142 tab_content.activeTabPanel = tab_panel;
143
144 },
145
146 get: function(tab_content_id) {
147 if (this._tabContents[tab_content_id] === undefined) {
148 console.error('Bunny TabList.get() error: tab content with ID "' + tab_content_id + '" is not defined. Define with TabList.define() first.');
149 return false;
150 }
151 return this._tabContents[tab_content_id];
152 }
153};
154
155document.addEventListener('DOMContentLoaded', function(){
156 document.getElementsByClassName('tab-content').forEach(function(tab_content) {
157 TabList.define(tab_content.id);
158 });
159}, false);