Skip to content

Instantly share code, notes, and snippets.

@jamiepittock
Forked from wsydney76/CollapseSidebarAsset.php
Created February 21, 2024 08:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jamiepittock/c9c41d5c21481c7b6971dbd201d18e80 to your computer and use it in GitHub Desktop.
Save jamiepittock/c9c41d5c21481c7b6971dbd201d18e80 to your computer and use it in GitHub Desktop.
Make sections of Craft 5 element indexes collapsible
/* toggle sidebar visibility */
#sidebar li.heading > span {
font-size: 14px;
letter-spacing: 1px;
display: block;
}
#sidebar ul:not(.st-sidebar) li.heading > span {
cursor: pointer;
}
#sidebar ul:not(.st-sidebar) li.heading > span:hover::after {
content: ' [-]';
font-weight: normal;
font-size: 10px;
}
/* TODO: Check how to avoid vertical shift on hover without this hack: */
#sidebar ul:not(.st-sidebar) li.heading > span::after {
content: ' ';
font-weight: normal;
font-size: 10px;
}
#sidebar ul:not(.st-sidebar) li.heading.collapsed > span::after {
content: ' [+]';
font-weight: normal;
font-size: 10px;
}
#sidebar li.heading.collapsed ul {
display: none;
}
/*
DOM Structure:
#sidebar
nav
ul
li.heading <-- toggle class 'collapsed' here
span <-- The heading text, add click eventListener here
ul <-- the sources, toggle visiblity via css .collapsed -> ul
Known issues:
Visibility does not get refreshed when changing sites via the sitemenu.
Depends on heading names, so will be reset if headings are changed.
*/
['entries','assets','categories','users'].forEach(elementType => {
if (isElementIndex(elementType)) {
initSidebarVisibility(elementType)
}
})
function isElementIndex(elementType) {
urlSegments = window.location.pathname.split("/");
return urlSegments.length >= 3 && urlSegments[2] === elementType
}
function initSidebarVisibility(elementType) {
// get headings
headingNodes = document.querySelectorAll('#sidebar li.heading > span')
// set visibility as stored in localStorage
setSidebarVisibility(elementType, headingNodes);
// Toggle sources visiblity on click
headingNodes.forEach(item => {
item.addEventListener('click', event => {
event.target.parentElement.classList.toggle('collapsed')
storeSidebarVisibility(elementType, headingNodes)
})
})
}
// store settings in local storage
function storeSidebarVisibility(elementType, headingNodes) {
var v = {};
headingNodes.forEach(function(element) {
v[element.innerText] = element.parentElement.classList.contains('collapsed') ? 'hidden' : 'visible'
});
localStorage[getStorageName(elementType)] = JSON.stringify(v);
}
function setSidebarVisibility(elementType, headingNodes) {
var v = localStorage[getStorageName(elementType)];
// No stored settings?
if (v === undefined) {
return;
}
v = JSON.parse(v);
headingNodes.forEach( (element, index) => {
if (element.innerText in v && v[element.innerText] === 'hidden') {
element.parentElement.classList.add('collapsed');
}
})
}
function getStorageName(elementType) {
urlParams = new URLSearchParams(window.location.search)
site = urlParams.get('site')
return 'sidebarVisiblity_' + site + '_' + elementType
}
<?php
namespace modules\main\web\assets\collapsesidebar;
use craft\web\AssetBundle;
/**
* Collapse Sidebar asset bundle
* Experimental!
*
* In your module's init() method, you can register this asset bundle like this:
* if (Craft::$app->request->isCpRequest) {
* Craft::$app->view->registerAssetBundle(CollapseSidebarAsset::class);
* }
*/
class CollapseSidebarAsset extends AssetBundle
{
public $sourcePath = __DIR__ . '/dist';
public $js = ['collapse-sidebar.js'];
public $css = ['collapse-sidebar.css'];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment