PageSourceSearch

https://sharethedignity.org.au/wp-content/themes/skelly/js/togglepanel.js

js sharethedignity.org.au collected 2026-10-02 03:05:44 UTC 3,727 bytes, 144 lines download raw bytes

1(function() {
2  'use strict';
3
4  const panelConfigs = [
5    {
6      container: '.header-search',
7      toggle: '.search-toggle',
8      dropdown: '.search-dropdown',
9      input: '.search-input' // Optional
10    },
11    {
12      container: '.login-panel',
13      toggle: '.login-toggle',
14      dropdown: '.login-dropdown'
15    },
16    {
17      container: '.mobile-login-panel',
18      toggle: '.mobile-cta-login',
19      dropdown: '.mobile-login-drop'
20    }
21  ];
22
23  // Store active instances to manage cross-closing
24  const activePanels = [];
25
26  function initPanels() {
27    panelConfigs.forEach(config => {
28      const container = document.querySelector(config.container);
29      if (!container) return;
30
31      const toggle = container.querySelector(config.toggle);
32      const dropdown = container.querySelector(config.dropdown);
33      const input = config.input ? container.querySelector(config.input) : null;
34
35      if (!toggle || !dropdown) return;
36
37      const panel = {
38        container,
39        toggle,
40        dropdown,
41        isOpen: false,
42        
43        open() {
44          // Close all other open panels first to prevent conflicts
45          activePanels.forEach(p => {
46            if (p !== this && p.isOpen) p.close();
47          });
48
49          container.classList.add('is-open');
50          toggle.setAttribute('aria-expanded', 'true');
51          if (input) input.focus();
52          this.isOpen = true;
53        },
54        
55        close() {
56          container.classList.remove('is-open');
57          toggle.setAttribute('aria-expanded', 'false');
58          this.isOpen = false;
59        },
60        
61        togglePanel() {
62          this.isOpen ? this.close() : this.open();
63        }
64      };
65
66      // Toggle on button click
67      toggle.addEventListener('click', (e) => {
68        // Prevent default in case it's an <a> tag
69        e.preventDefault(); 
70        panel.togglePanel();
71      });
72
73      // Close on Escape key
74      container.addEventListener('keydown', (e) => {
75        if (e.key === 'Escape' && panel.isOpen) {
76          e.preventDefault();
77          panel.close();
78          toggle.focus(); // Return focus for accessibility
79        }
80      });
81
82      activePanels.push(panel);
83    });
84
85    // click listener for all panels
86    document.addEventListener('click', (e) => {
87      activePanels.forEach(panel => {
88        // If the panel is open AND the click happened outside of this specific container
89        if (panel.isOpen && !panel.container.contains(e.target)) {
90          panel.close();
91        }
92      });
93    });
94  }
95
96  /**
97   *  Gravity Forms File Upload Enhancement
98   */
99  function initFileUploadUI() {
100    function bindFileInputs() {
101      const inputs = document.querySelectorAll('.ginput_container_fileupload input[type="file"]');
102
103      inputs.forEach(input => {
104        if (input.dataset.bound) return;
105
106        input.dataset.bound = "true";
107
108        input.addEventListener('change', function () {
109          console.log('file changed');
110
111          const container = input.closest('.ginput_container_fileupload');
112          if (!container) return;
113
114          if (input.files.length > 0) {
115            container.classList.add('has-file');
116            container.setAttribute('data-file', input.files[0].name);
117          }
118        });
119      });
120    }
121
122    // Run once
123    bindFileInputs();
124
125    // GF hook (jQuery-based)
126    if (window.jQuery) {
127      jQuery(document).on('gform_post_render', function () {
128        bindFileInputs();
129      });
130    }
131  }
132
133  function initAll() {
134    initPanels();
135    initFileUploadUI();
136  }
137
138  // Initialize when DOM is ready
139  if (document.readyState === 'loading') {
140    document.addEventListener('DOMContentLoaded', initAll);
141  } else {
142    initAll();
143  }
144})();

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.