From af6a21438e640bbfe22247c07ecc9e1771f75a17 Mon Sep 17 00:00:00 2001 From: Felix Hamann Date: Wed, 3 Apr 2019 23:21:12 +0200 Subject: [PATCH 01/61] add new JS utility registry and proof-of-concept utility --- src/Foundation.hs | 27 ++++---- static/js/utils/poc.js | 33 +++++++++ static/js/utils/registry.js | 109 ++++++++++++++++++++++++++++++ static/js/utils/setup.js | 114 -------------------------------- templates/default-layout.hamlet | 2 +- 5 files changed, 157 insertions(+), 128 deletions(-) create mode 100644 static/js/utils/poc.js create mode 100644 static/js/utils/registry.js delete mode 100644 static/js/utils/setup.js diff --git a/src/Foundation.hs b/src/Foundation.hs index 0d8e5d909..a15dd5a9b 100644 --- a/src/Foundation.hs +++ b/src/Foundation.hs @@ -1065,19 +1065,20 @@ siteLayout' headingOverride widget = do addScript $ StaticR js_polyfills_fetchPolyfill_js addScript $ StaticR js_polyfills_urlPolyfill_js -- JavaScript utils - addScript $ StaticR js_utils_alerts_js - addScript $ StaticR js_utils_asidenav_js - addScript $ StaticR js_utils_asyncForm_js - addScript $ StaticR js_utils_asyncTable_js - addScript $ StaticR js_utils_asyncTableFilter_js - addScript $ StaticR js_utils_checkAll_js - addScript $ StaticR js_utils_httpClient_js - addScript $ StaticR js_utils_form_js - addScript $ StaticR js_utils_inputs_js - addScript $ StaticR js_utils_modal_js - addScript $ StaticR js_utils_setup_js - addScript $ StaticR js_utils_showHide_js - addScript $ StaticR js_utils_tabber_js + -- addScript $ StaticR js_utils_alerts_js + -- addScript $ StaticR js_utils_asidenav_js + -- addScript $ StaticR js_utils_asyncForm_js + -- addScript $ StaticR js_utils_asyncTable_js + -- addScript $ StaticR js_utils_asyncTableFilter_js + -- addScript $ StaticR js_utils_checkAll_js + -- addScript $ StaticR js_utils_httpClient_js + -- addScript $ StaticR js_utils_form_js + -- addScript $ StaticR js_utils_inputs_js + -- addScript $ StaticR js_utils_modal_js + addScript $ StaticR js_utils_registry_js + addScript $ StaticR js_utils_poc_js + -- addScript $ StaticR js_utils_showHide_js + -- addScript $ StaticR js_utils_tabber_js addStylesheet $ StaticR css_utils_alerts_scss addStylesheet $ StaticR css_utils_asidenav_scss addStylesheet $ StaticR css_utils_asyncForm_scss diff --git a/static/js/utils/poc.js b/static/js/utils/poc.js new file mode 100644 index 000000000..5d87a0f82 --- /dev/null +++ b/static/js/utils/poc.js @@ -0,0 +1,33 @@ +(function() { + + var UTIL_NAME = 'poc'; + var UTIL_SELECTOR = '[uw-poc]'; + + var util = function(element) { + + function _init() { + var color = 'red'; + if (element.dataset.color) { + color = element.dataset.color; + } + element.style.outline = '1px solid ' + color; + } + + _init(); + + return { + name: UTIL_NAME, + element: element, + destroy: function() {}, + }; + }; + + if (UtilRegistry) { + UtilRegistry.register({ + name: UTIL_NAME, + selector: UTIL_SELECTOR, + setup: util, + }); + } + +})(); diff --git a/static/js/utils/registry.js b/static/js/utils/registry.js new file mode 100644 index 000000000..775b58fe4 --- /dev/null +++ b/static/js/utils/registry.js @@ -0,0 +1,109 @@ +(function() { + 'use strict'; + + var registeredUtils = []; + var activeUtilInstances = []; + + // Registry + // (revealing module pattern) + window.UtilRegistry = (function() { + + /** + * function registerUtil + * + * utils need to have at least these properties: + * name: string | utils name, e.g. 'example' + * selector: string | utils selector, e.g. '[uw-example]' + * setup: Function | utils setup function, see below + * + * setup function must return instance object with at least these properties: + * name: string | utils name + * element: HTMLElement | element the util is applied to + * destroy: Function | function to destroy the util and remove any listeners + * + * @param util Object Utility that should be added to the registry + */ + function registerUtil(util) { + console.log('registering util', util); + registeredUtils.push(util); + } + + function deregisterUtil(name, destroy) { + var utilIndex = _findUtilIndex(name); + + if (utilIndex >= 0) { + if (destroy === true) { + _destroyUtilInstances(name); + } + + registeredUtils.splice(utilIndex, 1); + } + } + + function setupAllUtils() { + console.log('setting up all registered utils'); + registeredUtils.forEach(function(util) { + setupUtil(util); + }); + } + + function setupUtil(util, scope) { + console.log('setting up util', { util }); + scope = scope || document; + + if (util && typeof util.setup === 'function') { + const elements = _findUtilElements(util, scope); + + elements.forEach(function(element) { + var utilInstance = util.setup(element); + if (utilInstance) { + activeUtilInstances.push(utilInstance); + } + }); + } + } + + function findUtil(name) { + return registeredUtils.find(function(util) { + return util.name === name; + }); + } + + function _findUtilElements(util, scope) { + return Array.from(scope.querySelectorAll(util.selector)); + } + + function _findUtilIndex(name) { + return registeredUtils.findIndex(function(util) { + return util.name === name; + }); + } + + function _destroyUtilInstances(name) { + console.log('TODO: destroy util instances', { name }); + // call destroy on each activeUtilInstance that matches the name + } + + // public API + return { + register: registerUtil, + deregister: deregisterUtil, + setupAll: setupAllUtils, + setup: setupUtil, + find: findUtil, + } + })(); + + document.addEventListener('DOMContentLoaded', function() { + window.UtilRegistry.setupAll(); + }); + + + // REMOVE ME. JUST HERE TO AVOID JS ERRORS + window.utils = { + setup: function(name) { + console.log('not really setting up', name); + }, + }; + +})(); diff --git a/static/js/utils/setup.js b/static/js/utils/setup.js deleted file mode 100644 index bb3bb0e3d..000000000 --- a/static/js/utils/setup.js +++ /dev/null @@ -1,114 +0,0 @@ -(function() { - 'use strict'; - - window.utils = window.utils || {}; - - var registeredSetupListeners = {}; - var activeInstances = {}; - -/** - * setup function to initiate a util (utilName) on a scope (sope) with options (options). - * - * Utils need to be defined as property of `window.utils` and need to accept a scope and (optionally) options. - * Example: `window.utils.autoSubmit = function(scope, options) { ... };` - */ - - window.utils.setup = function(utilName, scope, options) { - if (!utilName || !scope) { - return; - } - - options = options || {}; - - var utilInstance; - - // i18n - if (window.I18N) { - options.i18n = window.I18N; - } - - if (activeInstances[utilName]) { - var instanceWithSameScope = activeInstances[utilName] - .filter(function(instance) { return !!instance; }) - .find(function(instance) { - return instance.scope === scope; - }); - var isAlreadySetup = !!instanceWithSameScope; - - if (isAlreadySetup) { - console.warn('Trying to setup a JS utility that\'s already been set up', { utility: utilName, scope, options }); - if (!options.force) { - return false; - } - } - } - - function setup() { - var listener = function(event) { - if (event.detail.targetUtil !== utilName) { - return false; - } - - if (options.setupFunction) { - utilInstance = options.setupFunction(scope, options); - } else { - var util = window.utils[utilName]; - if (!util) { - throw new Error('"' + utilName + '" is not a known js util'); - } - - utilInstance = util(scope, options); - } - - if (utilInstance) { - if (activeInstances[utilName] && Array.isArray(activeInstances[utilName])) { - activeInstances[utilName].push(utilInstance); - } else { - activeInstances[utilName] = [ utilInstance ]; - } - } - }; - - if (registeredSetupListeners[utilName] && Array.isArray(registeredSetupListeners[utilName])) { - window.utils.teardown(utilName); - } - - if (!registeredSetupListeners[utilName] || Array.isArray(registeredSetupListeners[utilName])) { - registeredSetupListeners[utilName] = []; - } - registeredSetupListeners[utilName].push(listener); - - document.addEventListener('setup', listener); - - document.dispatchEvent(new CustomEvent('setup', { - detail: { targetUtil: utilName, module: 'none' }, - bubbles: true, - cancelable: true, - })); - } - - setup(); - - return utilInstance; - }; - - window.utils.teardown = function(utilName, destroy) { - if (registeredSetupListeners[utilName]) { - registeredSetupListeners[utilName] - .filter(function(listener) { return !!listener }) - .forEach(function(listener) { - document.removeEventListener('setup', listener); - }); - delete registeredSetupListeners[utilName]; - } - - if (destroy === true && activeInstances[utilName]) { - activeInstances[utilName] - .filter(function(instance) { return !!instance }) - .forEach(function(instance) { - instance.destroy(); - }); - delete activeInstances[utilName]; - } - } -})(); diff --git a/templates/default-layout.hamlet b/templates/default-layout.hamlet index f43282fb0..7a679af27 100644 --- a/templates/default-layout.hamlet +++ b/templates/default-layout.hamlet @@ -6,7 +6,7 @@ $if not isModal
-
+
$if not isModal From 6d824d33928a39c66054cc814648787213ce2984 Mon Sep 17 00:00:00 2001 From: Felix Hamann Date: Wed, 3 Apr 2019 23:23:53 +0200 Subject: [PATCH 02/61] WIP: refactor show hide JS utility to work with new registry --- src/Foundation.hs | 2 +- static/js/utils/showHide.js | 106 ++++++++++++++++++++++-------------- 2 files changed, 65 insertions(+), 43 deletions(-) diff --git a/src/Foundation.hs b/src/Foundation.hs index a15dd5a9b..a0d739bc7 100644 --- a/src/Foundation.hs +++ b/src/Foundation.hs @@ -1077,7 +1077,7 @@ siteLayout' headingOverride widget = do -- addScript $ StaticR js_utils_modal_js addScript $ StaticR js_utils_registry_js addScript $ StaticR js_utils_poc_js - -- addScript $ StaticR js_utils_showHide_js + addScript $ StaticR js_utils_showHide_js -- addScript $ StaticR js_utils_tabber_js addStylesheet $ StaticR css_utils_alerts_scss addStylesheet $ StaticR css_utils_asidenav_scss diff --git a/static/js/utils/showHide.js b/static/js/utils/showHide.js index 0441cde4b..6689b83bd 100644 --- a/static/js/utils/showHide.js +++ b/static/js/utils/showHide.js @@ -1,77 +1,99 @@ (function() { 'use strict'; - window.utils = window.utils || {}; + var UTIL_NAME = 'showHide'; + var UTIL_SELECTOR = '[uw-show-hide]'; var JS_INITIALIZED_CLASS = 'js-show-hide-initialized'; var LOCAL_STORAGE_SHOW_HIDE = 'SHOW_HIDE'; - var SHOW_HIDE_TOGGLE_CLASS = 'js-show-hide__toggle'; var SHOW_HIDE_COLLAPSED_CLASS = 'js-show-hide--collapsed'; var SHOW_HIDE_TARGET_CLASS = 'js-show-hide__target'; /** - * div - * div.js-show-hide__toggle - * toggle here - * div - * content here + *
+ *
+ * [toggle here] + *
+ * [content here] */ - window.utils.showHide = function(wrapper, options) { + var util = function(element) { - options = options || {}; + function _init() { + if (!element) { + throw new Error('ShowHide utility cannot be setup without an element!'); + } - function addEventHandler(el) { - el.addEventListener('click', function elClickListener() { - var newState = el.parentElement.classList.toggle(SHOW_HIDE_COLLAPSED_CLASS); - updateLSState(el.dataset.shIndex || null, newState); + if (element.classList.contains(JS_INITIALIZED_CLASS)) { + return false; + } + + _addEventHandler(); + } + + function _addEventHandler() { + element.addEventListener('click', function clickListener() { + console.log('showhide clicked'); + var newState = element.parentElement.classList.toggle(SHOW_HIDE_COLLAPSED_CLASS); + _updateLSState(element.dataset.shIndex || null, newState); }); } - function updateLSState(index, state) { + function _updateLSState(index, state) { if (!index) { return false; } - var lsData = getLocalStorageData(); + var lsData = _getLocalStorageData(); lsData[index] = state; window.localStorage.setItem(LOCAL_STORAGE_SHOW_HIDE, JSON.stringify(lsData)); } - function collapsedStateInLocalStorage(index) { - var lsState = getLocalStorageData(); - return lsState[index]; - } + // function _getCollapsedLSState(index) { + // var lsState = _getLocalStorageData(); + // return lsState[index]; + // } - function getLocalStorageData() { + function _getLocalStorageData() { return JSON.parse(window.localStorage.getItem(LOCAL_STORAGE_SHOW_HIDE)) || {}; } - Array - .from(wrapper.querySelectorAll('.' + SHOW_HIDE_TOGGLE_CLASS)) - .forEach(function(el) { - if (el.classList.contains(JS_INITIALIZED_CLASS)) { - return false; - } + // var showHides = Array.from(scope.querySelectorAll(UTIL_SELECTOR)); + // showHides.forEach(function(el) { + // if (el.classList.contains(JS_INITIALIZED_CLASS)) { + // return false; + // } - var index = el.dataset.shIndex || null; - var isCollapsed = el.dataset.collapsed === 'true'; - var lsCollapsedState = collapsedStateInLocalStorage(index); - if (typeof lsCollapsedState !== 'undefined') { - isCollapsed = lsCollapsedState; - } - el.parentElement.classList.toggle(SHOW_HIDE_COLLAPSED_CLASS, isCollapsed); + // var index = el.dataset.shIndex || null; + // var isCollapsed = el.dataset.collapsed === 'true'; + // var lsCollapsedState = _getCollapsedLSState(index); + // if (typeof lsCollapsedState !== 'undefined') { + // isCollapsed = lsCollapsedState; + // } + // el.parentElement.classList.toggle(SHOW_HIDE_COLLAPSED_CLASS, isCollapsed); - Array.from(el.parentElement.children).forEach(function(el) { - if (!el.classList.contains('' + SHOW_HIDE_TOGGLE_CLASS)) { - el.classList.add(SHOW_HIDE_TARGET_CLASS); - } - }); - el.classList.add(JS_INITIALIZED_CLASS); - addEventHandler(el); - }); + // Array.from(el.parentElement.children).forEach(function(el) { + // if (!el.matches(UTIL_SELECTOR)) { + // el.classList.add(SHOW_HIDE_TARGET_CLASS); + // } + // }); + // el.classList.add(JS_INITIALIZED_CLASS); + // _addEventHandler(el); + // }); + + _init(); return { - scope: wrapper, + name: UTIL_NAME, + element: element, destroy: function() {}, }; }; + + if (UtilRegistry) { + UtilRegistry.register({ + name: UTIL_NAME, + selector: UTIL_SELECTOR, + setup: util + }); + } + })(); From ff59d0a41269e105865cf589fac364de34935bf7 Mon Sep 17 00:00:00 2001 From: Felix Hamann Date: Wed, 3 Apr 2019 23:31:22 +0200 Subject: [PATCH 03/61] move JS UtilRegistry to top of imports to ensure its present in scope --- src/Foundation.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Foundation.hs b/src/Foundation.hs index a0d739bc7..365a64ccf 100644 --- a/src/Foundation.hs +++ b/src/Foundation.hs @@ -1065,6 +1065,7 @@ siteLayout' headingOverride widget = do addScript $ StaticR js_polyfills_fetchPolyfill_js addScript $ StaticR js_polyfills_urlPolyfill_js -- JavaScript utils + addScript $ StaticR js_utils_registry_js -- addScript $ StaticR js_utils_alerts_js -- addScript $ StaticR js_utils_asidenav_js -- addScript $ StaticR js_utils_asyncForm_js @@ -1075,7 +1076,6 @@ siteLayout' headingOverride widget = do -- addScript $ StaticR js_utils_form_js -- addScript $ StaticR js_utils_inputs_js -- addScript $ StaticR js_utils_modal_js - addScript $ StaticR js_utils_registry_js addScript $ StaticR js_utils_poc_js addScript $ StaticR js_utils_showHide_js -- addScript $ StaticR js_utils_tabber_js From 5e71e8c9e6fa8deb00efcc4781f9df7c1687ee7d Mon Sep 17 00:00:00 2001 From: Felix Hamann Date: Thu, 4 Apr 2019 22:57:53 +0200 Subject: [PATCH 04/61] rework show-hide js utility --- static/css/utils/asidenav.scss | 19 +-- static/css/utils/showHide.scss | 24 +-- static/js/utils/modal.js | 16 +- static/js/utils/registry.js | 9 +- static/js/utils/showHide.js | 145 ++++++++++--------- templates/adminTest.hamlet | 2 +- templates/table/layout-filter-default.hamlet | 2 +- templates/table/layout-filter-default.lucius | 4 + templates/widgets/asidenav/asidenav.hamlet | 6 +- 9 files changed, 125 insertions(+), 102 deletions(-) diff --git a/static/css/utils/asidenav.scss b/static/css/utils/asidenav.scss index 1ac580d58..101bf5506 100644 --- a/static/css/utils/asidenav.scss +++ b/static/css/utils/asidenav.scss @@ -55,10 +55,6 @@ .asidenav__box-title { font-size: 18px; padding-left: 10px; - - &.js-show-hide__toggle::before { - z-index: 1; - } } } } @@ -94,18 +90,9 @@ margin-top: 30px; background-color: transparent; transition: all .2s ease; - padding: 30px 13px 10px; + padding: 10px 13px; margin: 0; border-bottom: 1px solid var(--color-grey); - - &.js-show-hide__toggle { - - &::before { - left: auto; - right: 20px; - color: var(--color-font); - } - } } /* LOGO */ @@ -361,9 +348,5 @@ background-color: var(--color-lightwhite); } } - - .js-show-hide__toggle::before { - content: none; - } } } diff --git a/static/css/utils/showHide.scss b/static/css/utils/showHide.scss index ab82286b8..1f85fbf36 100644 --- a/static/css/utils/showHide.scss +++ b/static/css/utils/showHide.scss @@ -1,10 +1,9 @@ $show-hide-toggle-size: 6px; -.js-show-hide__toggle { +.show-hide__toggle { position: relative; cursor: pointer; - padding: 3px 7px; &:hover { background-color: var(--color-grey-lighter); @@ -12,32 +11,33 @@ $show-hide-toggle-size: 6px; } } -.js-show-hide__toggle::before { +.show-hide__toggle::before { content: ''; position: absolute; width: $show-hide-toggle-size; height: $show-hide-toggle-size; left: -15px; - top: 12px - $show-hide-toggle-size / 2; + top: 50%; color: var(--color-primary); border-right: 2px solid currentColor; border-top: 2px solid currentColor; transition: transform .2s ease; - transform-origin: ($show-hide-toggle-size / 2); - transform: translateY($show-hide-toggle-size) rotate(-45deg); + transform: translateY(-50%) rotate(-45deg); } -.js-show-hide__target { - transition: all .2s ease; +.show-hide__toggle--right::before { + left: auto; + right: 20px; + color: var(--color-font); } -.js-show-hide--collapsed { +.show-hide--collapsed { - .js-show-hide__toggle::before { - transform: translateY($show-hide-toggle-size / 3) rotate(135deg); + .show-hide__toggle::before { + transform: translateY(-50%) rotate(135deg); } - .js-show-hide__target { + :not(.show-hide__toggle) { display: block; height: 0; margin: 0; diff --git a/static/js/utils/modal.js b/static/js/utils/modal.js index a5971edf7..50307f3db 100644 --- a/static/js/utils/modal.js +++ b/static/js/utils/modal.js @@ -2,6 +2,20 @@ 'use strict'; window.utils = window.utils || {}; + // ######################## + // TODO: make use of selector + // or think of a different way to dynamically initialize widgets + // with selectors with specific ids like #modal-hident69 + // + // Idee: + // Alles wegschmeißen zu dynamischen IDs. Util init rein über Selector '[uw-...]' + // bedarf Änderung in Templates. + // Ausserdem müssen sich Utils bei Event 'util-setup-ready' registrieren als Util + // utils.setup wird dann überflüssig, bzw. wird zu einer Registry / Controller + // der die utils bei DomCOntentLoaded intialisiert. + // + // ######################## + var SELECTOR = '[uw-modal]'; var JS_INITIALIZED_CLASS = 'js-modal-initialized'; var MODAL_OPEN_CLASS = 'modal--open'; @@ -17,7 +31,7 @@ var OVERLAY_OPEN_CLASS = 'modal__overlay--open'; var CLOSER_CLASS = 'modal__closer'; - window.utils.modal = function(modalElement, options) { + window.utils.modal = function(scope, options) { if (!modalElement || modalElement.classList.contains(JS_INITIALIZED_CLASS)) { return; diff --git a/static/js/utils/registry.js b/static/js/utils/registry.js index 775b58fe4..9acff588d 100644 --- a/static/js/utils/registry.js +++ b/static/js/utils/registry.js @@ -55,7 +55,14 @@ const elements = _findUtilElements(util, scope); elements.forEach(function(element) { - var utilInstance = util.setup(element); + var utilInstance = null; + + try { + utilInstance = util.setup(element); + } catch(err) { + console.warn('Error while trying to initialize a utility!', { util , element, err }); + } + if (utilInstance) { activeUtilInstances.push(utilInstance); } diff --git a/static/js/utils/showHide.js b/static/js/utils/showHide.js index 6689b83bd..cd3a6e4ac 100644 --- a/static/js/utils/showHide.js +++ b/static/js/utils/showHide.js @@ -1,98 +1,113 @@ (function() { 'use strict'; - var UTIL_NAME = 'showHide'; - var UTIL_SELECTOR = '[uw-show-hide]'; + var SHOW_HIDE_UTIL_NAME = 'showHide'; + var SHOW_HIDE_UTIL_SELECTOR = '[uw-show-hide]'; - var JS_INITIALIZED_CLASS = 'js-show-hide-initialized'; - var LOCAL_STORAGE_SHOW_HIDE = 'SHOW_HIDE'; - var SHOW_HIDE_COLLAPSED_CLASS = 'js-show-hide--collapsed'; - var SHOW_HIDE_TARGET_CLASS = 'js-show-hide__target'; + var SHOW_HIDE_LOCAL_STORAGE_KEY = 'SHOW_HIDE'; + var SHOW_HIDE_INITIALIZED_CLASS = 'show-hide--initialized'; + var SHOW_HIDE_COLLAPSED_CLASS = 'show-hide--collapsed'; + var SHOW_HIDE_TOGGLE_CLASS = 'show-hide__toggle'; + var SHOW_HIDE_TOGGLE_RIGHT_CLASS = 'show-hide__toggle--right'; /** + * + * ShowHide Utility + * + * Attribute: uw-show-hide + * + * Params: (all optional) + * data-show-hide-id: string + * If this param is given the state of the utility will be persisted in the clients local storage. + * data-show-hide-collapsed: boolean property + * If this param is present the ShowHide utility will be collapsed. This value will be overruled by any value stored in the LocalStorage. + * data-show-hide-align: 'right' + * Where to put the arrow that marks the element as a ShowHide toggle. Left of toggle by default. + * + * Example usage: *
- *
- * [toggle here] - *
- * [content here] + *
Click me + *
This will be toggled + *
This will be toggled as well */ - var util = function(element) { + var showHideUtil = function(element) { - function _init() { + var showHideId; + + function init() { if (!element) { throw new Error('ShowHide utility cannot be setup without an element!'); } - if (element.classList.contains(JS_INITIALIZED_CLASS)) { - return false; + if (element.classList.contains(SHOW_HIDE_INITIALIZED_CLASS)) { + throw new Error('ShowHide utility already initialized!'); } - _addEventHandler(); + // register click listener + addClickListener(); + + // param showHideId + if (element.dataset.showHideId) { + showHideId = element.dataset.showHideId; + } + + // param showHideCollapsed + var collapsed = false; + if (element.dataset.showHideCollapsed !== undefined) { + collapsed = true; + } + if (showHideId) { + var localStorageCollapsed = getLocalStorage()[showHideId]; + if (typeof localStorageCollapsed !== 'undefined') { + collapsed = localStorageCollapsed; + } + } + element.parentElement.classList.toggle(SHOW_HIDE_COLLAPSED_CLASS, collapsed); + + // param showHideAlign + var alignment = element.dataset.showHideAlign; + if (alignment === 'right') { + element.classList.add(SHOW_HIDE_TOGGLE_RIGHT_CLASS); + } + + // mark as initialized + element.classList.add(SHOW_HIDE_INITIALIZED_CLASS, SHOW_HIDE_TOGGLE_CLASS); + + return { + name: SHOW_HIDE_UTIL_NAME, + element: element, + destroy: function() {}, + }; } - function _addEventHandler() { + function addClickListener() { element.addEventListener('click', function clickListener() { - console.log('showhide clicked'); var newState = element.parentElement.classList.toggle(SHOW_HIDE_COLLAPSED_CLASS); - _updateLSState(element.dataset.shIndex || null, newState); + + if (showHideId) { + setLocalStorage(showHideId, newState); + } }); } - function _updateLSState(index, state) { - if (!index) { - return false; - } - var lsData = _getLocalStorageData(); - lsData[index] = state; - window.localStorage.setItem(LOCAL_STORAGE_SHOW_HIDE, JSON.stringify(lsData)); + function setLocalStorage(id, state) { + var lsData = getLocalStorage(); + lsData[id] = state; + window.localStorage.setItem(SHOW_HIDE_LOCAL_STORAGE_KEY, JSON.stringify(lsData)); } - // function _getCollapsedLSState(index) { - // var lsState = _getLocalStorageData(); - // return lsState[index]; - // } - - function _getLocalStorageData() { - return JSON.parse(window.localStorage.getItem(LOCAL_STORAGE_SHOW_HIDE)) || {}; + function getLocalStorage() { + return JSON.parse(window.localStorage.getItem(SHOW_HIDE_LOCAL_STORAGE_KEY)) || {}; } - // var showHides = Array.from(scope.querySelectorAll(UTIL_SELECTOR)); - // showHides.forEach(function(el) { - // if (el.classList.contains(JS_INITIALIZED_CLASS)) { - // return false; - // } - - // var index = el.dataset.shIndex || null; - // var isCollapsed = el.dataset.collapsed === 'true'; - // var lsCollapsedState = _getCollapsedLSState(index); - // if (typeof lsCollapsedState !== 'undefined') { - // isCollapsed = lsCollapsedState; - // } - // el.parentElement.classList.toggle(SHOW_HIDE_COLLAPSED_CLASS, isCollapsed); - - // Array.from(el.parentElement.children).forEach(function(el) { - // if (!el.matches(UTIL_SELECTOR)) { - // el.classList.add(SHOW_HIDE_TARGET_CLASS); - // } - // }); - // el.classList.add(JS_INITIALIZED_CLASS); - // _addEventHandler(el); - // }); - - _init(); - - return { - name: UTIL_NAME, - element: element, - destroy: function() {}, - }; + return init(); }; if (UtilRegistry) { UtilRegistry.register({ - name: UTIL_NAME, - selector: UTIL_SELECTOR, - setup: util + name: SHOW_HIDE_UTIL_NAME, + selector: SHOW_HIDE_UTIL_SELECTOR, + setup: showHideUtil }); } diff --git a/templates/adminTest.hamlet b/templates/adminTest.hamlet index 7e59d9599..b595fe813 100644 --- a/templates/adminTest.hamlet +++ b/templates/adminTest.hamlet @@ -6,7 +6,7 @@ Der Handler sollte jeweils aktuelle Beispiele für alle möglichen Funktionalitäten enthalten, so dass man immer weiß, wo man nachschlagen kann.
-

Teilweise funktionierende Abschnitte +

Teilweise funktionierende Abschnitte