PageSourceSearch

https://applulbayt.web.id/wp-content/themes/hybridmag/assets/js/tab-widget.js?ver=1.1.4

js applulbayt.web.id collected 2026-09-24 15:01:43 UTC 6,636 bytes, 231 lines download raw bytes

1/**
2 * Tabs
3 * 
4 * @since HybridMag 1.0.0
5 */
6 (function() {
7
8    var uiwCounter = 0;
9    
10    // Counter to be used to create a unique id.
11    function incrementCounter() {
12        uiwCounter = uiwCounter + 1;
13        return uiwCounter;
14    }
15
16    // Creates a uniqueId.
17    function uniqueId() {
18        var count = incrementCounter();
19        return "th-id-" + count.toString();
20    }
21
22    /**
23     * Tabs constructor function.
24     * 
25     * @param {*} element 
26     */
27    function Tabs(element) {
28        this.element = element;
29        this.tablist = element.querySelector('ul');
30        this.tabs = this.tablist.querySelectorAll('a');
31        this.panels = [];
32
33        this.setup();
34        this.addListeners();
35        // Always open the first tab at start.
36        this.openTab(this.tabs[0], false);
37    }
38
39    // Initial Setup for the whole tab widget.
40    Tabs.prototype.setup = function() {
41
42        // Set the tablist role.
43        this.tablist.setAttribute("role", "tablist");
44
45        for( var i = 0; i < this.tabs.length; i++ ) {
46            var tab = this.tabs[i];
47            var panelId = tab.getAttribute('href');
48            var ariaControl = panelId.substring(1);
49
50            var uid = uniqueId();
51            this.setupTab(tab, uid, ariaControl);
52
53            var panel = this.element.querySelector(panelId);
54
55            // If there is not a panel just ignore.
56            if( panel != null ) {
57                panel = this.setupPanel(panel, uid);
58                this.panels.push(panel);
59            }
60        }
61    };
62
63    // Initial setup for tabs.
64    Tabs.prototype.setupTab = function(tab, uniqueId, ariaControl) {
65        var listitem = tab.parentElement;
66
67        tab.setAttribute("id", uniqueId);
68
69        listitem.setAttribute("role", "tab");
70        listitem.setAttribute("aria-labelledby", uniqueId);
71        listitem.setAttribute("aria-controls", ariaControl);
72    };
73
74    // Initial setup for panels.
75    Tabs.prototype.setupPanel = function(panel, uniqueId) {
76        panel.setAttribute("aria-labelledby", uniqueId);
77        panel.setAttribute("role", "tabpanel")
78        return panel;
79    };
80
81    // Add event listeners.
82    Tabs.prototype.addListeners = function() {
83        var self = this;
84        for( var i = 0; i < this.tabs.length; i++ ) {
85            this.tabs[i].addEventListener('click', function(event) {
86                event.preventDefault();
87                self.openTab(this);
88            }); 
89            this.tabs[i].addEventListener('keydown', function(event) {
90                self.keyDownEventListener(event);
91            });
92        }
93    };
94
95    // Key up event listener.
96    Tabs.prototype.keyDownEventListener = function(event) {
97
98        if( event.keyCode == 39 ) {
99            var tabId = event.target.id;
100            var tabIndex = 0;
101            var tabsLength = this.tabs.length;
102
103            var tabIndex = this.getTabPosition(tabId);
104
105            if ( tabIndex + 1 < tabsLength ) {
106                this.openTab(this.tabs[tabIndex + 1]);
107            } else {
108                this.openFirstTab();
109            }
110        }
111
112        if( event.keyCode == 37 ) {
113            var tabId = event.target.id;
114            var tabIndex = 0;
115            var tabsLength = this.tabs.length;
116
117            var tabIndex = this.getTabPosition(tabId);
118
119            if ( tabIndex != 0 ) {
120                this.openTab(this.tabs[tabIndex - 1]);
121            } else {
122                this.openLastTab();
123            }
124        }
125
126    };
127
128    // Returns the array position of a given tab.
129    // See if there is any default function for this.
130    Tabs.prototype.getTabPosition = function(tabId) {
131        for( var i = 0; i < this.tabs.length; i++ ) {
132            var tab = this.tabs[i];
133            if( tabId == tab.getAttribute('id') ) {
134                return i;
135            }
136        }
137    };
138
139    // Opens the first tab.
140    Tabs.prototype.openFirstTab = function() {
141        this.openTab(this.tabs[0]);
142    };
143
144    // Opens the last tab.
145    Tabs.prototype.openLastTab = function() {
146        this.openTab(this.tabs[this.tabs.length - 1]);
147    };
148
149    // Tab opening function goes here.
150    Tabs.prototype.openTab = function(tab, setFocus) {
151
152        var listitem = tab.parentElement;
153        var tabId = tab.getAttribute('id');
154        var panelId = listitem.getAttribute("aria-controls");
155        
156        for( var i = 0; i < this.tabs.length; i++ ) {
157            var currentTab = this.tabs[i];
158
159            if( currentTab.getAttribute('id') == tabId ) {
160                this.activateTab(currentTab, setFocus);
161            } else {
162                this.deActivateTab(currentTab);
163            }
164        }
165
166        for( var i = 0; i < this.panels.length; i++ ) {
167            var panel = this.panels[i];
168
169            if( panel.getAttribute('id') == panelId ) {
170                this.activatePanel(panel);
171            } else {
172                this.deActivatePanel(panel);
173            }
174        }
175
176    };
177
178    // Activates the tab.
179    Tabs.prototype.activateTab = function(tab, setFocus) {
180        var needFocus = ( setFocus !== undefined ) ? setFocus : true;
181        var listitem = tab.parentElement;
182
183        listitem.setAttribute('aria-selected', 'true');
184        listitem.setAttribute('aria-expanded', 'true');
185        listitem.setAttribute('tabindex', '0');
186        listitem.classList.add('th-ui-state-active');
187        tab.setAttribute('tabindex', '-1');
188
189        if ( needFocus ) {
190            tab.focus();
191        }
192    }
193
194    // Deactivates the tab.
195    Tabs.prototype.deActivateTab = function(tab) {
196        var listitem = tab.parentElement;
197
198        listitem.setAttribute('aria-selected', 'false');
199        listitem.setAttribute('aria-expanded', 'false');
200        listitem.setAttribute('tabindex', '-1');
201        listitem.classList.remove('th-ui-state-active');
202        tab.setAttribute('tabindex', '-1');
203    }
204
205    // Activate the panel.
206    Tabs.prototype.activatePanel = function(panel) {
207        panel.style.display = 'block';
208        panel.setAttribute('aria-hidden', 'false');
209    }
210
211    // Deactivate the panel.
212    Tabs.prototype.deActivatePanel = function(panel) {
213        panel.style.display = 'none';
214        panel.setAttribute('aria-hidden', 'true');
215    }
216
217    // Traverse through the DOM and create Tabs instances for each tab widget.
218    function init(elements) {
219        var nodes = document.querySelectorAll(elements);
220        if ( nodes == null ) {
221            return;
222        }
223        for( var i = 0; i < nodes.length; i++ ) {
224            var node = nodes[i];
225            var tabs = new Tabs(node);
226        }
227    }
228
229    init(".hm-featured-tabs");
230    
231})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.