Add collapsible groups functionality with localStorage support for state management
This commit is contained in:
93
js/collapsible-groups.js
Normal file
93
js/collapsible-groups.js
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
/**
|
||||||
|
* collapsible-groups.js - Collapsible service groups
|
||||||
|
*/
|
||||||
|
|
||||||
|
const STORAGE_KEY_COLLAPSED = 'collapsed-groups';
|
||||||
|
|
||||||
|
// Load collapsed state from localStorage
|
||||||
|
function loadCollapsedState() {
|
||||||
|
try {
|
||||||
|
const saved = localStorage.getItem(STORAGE_KEY_COLLAPSED);
|
||||||
|
return saved ? JSON.parse(saved) : {};
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Error loading collapsed state:', e);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save collapsed state to localStorage
|
||||||
|
function saveCollapsedState(collapsedMap) {
|
||||||
|
try {
|
||||||
|
localStorage.setItem(STORAGE_KEY_COLLAPSED, JSON.stringify(collapsedMap));
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Error saving collapsed state:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle group collapse
|
||||||
|
function toggleGroup(groupElement) {
|
||||||
|
const groupName = groupElement.querySelector('h2')?.textContent;
|
||||||
|
if (!groupName) return;
|
||||||
|
|
||||||
|
const content = groupElement.querySelector('.services-grid');
|
||||||
|
const toggle = groupElement.querySelector('.group-toggle');
|
||||||
|
|
||||||
|
if (!content) return;
|
||||||
|
|
||||||
|
const isCollapsed = content.classList.toggle('collapsed');
|
||||||
|
toggle?.classList.toggle('collapsed', isCollapsed);
|
||||||
|
|
||||||
|
// Save state
|
||||||
|
const collapsedMap = loadCollapsedState();
|
||||||
|
collapsedMap[groupName] = isCollapsed;
|
||||||
|
saveCollapsedState(collapsedMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply saved collapsed state
|
||||||
|
function applyCollapsedState() {
|
||||||
|
const collapsedMap = loadCollapsedState();
|
||||||
|
|
||||||
|
document.querySelectorAll('.service-group').forEach(group => {
|
||||||
|
const groupName = group.querySelector('h2')?.textContent;
|
||||||
|
if (!groupName) return;
|
||||||
|
|
||||||
|
const content = group.querySelector('.services-grid');
|
||||||
|
const toggle = group.querySelector('.group-toggle');
|
||||||
|
|
||||||
|
if (collapsedMap[groupName]) {
|
||||||
|
content?.classList.add('collapsed');
|
||||||
|
toggle?.classList.add('collapsed');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize collapsible groups
|
||||||
|
function initCollapsibleGroups() {
|
||||||
|
document.querySelectorAll('.service-group').forEach(group => {
|
||||||
|
const header = group.querySelector('h2');
|
||||||
|
if (!header) return;
|
||||||
|
|
||||||
|
// Add toggle icon
|
||||||
|
const toggle = document.createElement('span');
|
||||||
|
toggle.className = 'group-toggle';
|
||||||
|
toggle.innerHTML = '▼';
|
||||||
|
toggle.title = 'Collapse/Expand';
|
||||||
|
|
||||||
|
// Make header clickable
|
||||||
|
header.style.cursor = 'pointer';
|
||||||
|
header.style.userSelect = 'none';
|
||||||
|
header.insertBefore(toggle, header.firstChild);
|
||||||
|
|
||||||
|
// Add click handler
|
||||||
|
header.addEventListener('click', () => toggleGroup(group));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Apply saved state
|
||||||
|
applyCollapsedState();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export for use in other modules
|
||||||
|
window.collapsibleGroupsModule = {
|
||||||
|
init: initCollapsibleGroups,
|
||||||
|
applyCollapsedState: applyCollapsedState
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user