From 41ffd5a1cced029dda82c4ac0b1f3b92f686fa94 Mon Sep 17 00:00:00 2001 From: Florian Schlittenbauer Date: Sat, 19 Oct 2019 17:02:42 +0200 Subject: [PATCH] implement open state and group mode --- README.md | 49 ++++++++++++++++++++++++++++++++- shortcodes/DetailsShortcode.php | 10 ++++++- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e1b9573..3f6d67f 100644 --- a/README.md +++ b/README.md @@ -396,13 +396,14 @@ Genie dahin einem ein gib geben allen. #### Details/Summary The `
` element provides a simple show/hide behaviour without JavaScript, and can optionally contain a `` element that is always shown. Clicking on the summary text toggles the visibility of the content, and when a summary is not provided, it defaults to "Details". The element can be used to provide extra details, or can be combined into an accordion-like structure. +Use `open="true"` to open the item by default. ``` [details] Lorem ipsum dolor sit amet... [/details] -[details="Summary text"] +[details="Summary text" open="true"] Lorem ipsum dolor sit amet... [/details] @@ -411,6 +412,52 @@ Lorem ipsum dolor sit amet... [/details] ``` +You can use the group attribute to group items together. This makes it easy to implement accordion behaviour, where only one item of a group can be open at a time. + +``` +[details="Summary text" open="true" group="group01"] +Lorem ipsum dolor sit amet... +[/details] + +[details="Summary text" group="group01"] +Lorem ipsum dolor sit amet... +[/details] + +[details="Summary text" group="group01"] +Lorem ipsum dolor sit amet... +[/details] +``` + +Combined with a little JS like this gets you the desired behaviour: + +```js +const items = document.querySelectorAll('details'); + +[...items].forEach(item => { + // check if item is in group mode + if (item.dataset.group) { + // override click event handling for group mode items + item.querySelector('summary').addEventListener('click', e => { + e.preventDefault(); + + // check if item is open or closed + if (item.hasAttribute('open')) { + // close item if it was open + item.removeAttribute('open'); + } else { + // close all open items in group + [...document.querySelectorAll(`details[data-group="${item.dataset.group}"][open]`)].forEach(details => { + details.removeAttribute('open'); + }); + // open the item + item.setAttribute('open', ''); + } + }); + } +}); + +``` + **Note:** The show/hide behaviour is not supported in IE 11 or Edge 18, and the element will be permanently open. You can check the current status of browser compatibility at [Can I Use](https://caniuse.com/#search=details). #### Lorem Ipsum diff --git a/shortcodes/DetailsShortcode.php b/shortcodes/DetailsShortcode.php index 69c4732..10f4900 100644 --- a/shortcodes/DetailsShortcode.php +++ b/shortcodes/DetailsShortcode.php @@ -16,11 +16,19 @@ public function init() $class = $sc->getParameter('class', $this->getBbCode($sc)); $classHTML = (isset($class) and $class !== $summary) ? 'class="'.$class.'"' : ''; + // Get group for details + $group = $sc->getParameter('group', $this->getBbCode($sc)); + $groupHTML = (isset($group) and $group !== $summary) ? 'data-group="'.$group.'"' : ''; + + // Get open status for details + $open = $sc->getParameter('open', $this->getBbCode($sc)); + $openHTML = (isset($open) and $open !== $summary) ? 'open' : ''; + // Get content $content = $sc->getContent(); // Return the details/summary block - return '
'.$summaryHTML.$content.'
'; + return '
'.$summaryHTML.$content.'
'; }); } }