feat: content element for faq overview grouped by categories

addresses #869b064ah
This commit is contained in:
Björn Fromme
2026-06-23 18:42:01 +02:00
parent e0b43a7a38
commit 561883f74a
6 changed files with 139 additions and 7 deletions
@@ -5,7 +5,7 @@ export default class extends Controller {
static debounces = [ 'filter' ]
static targets = [ 'entry' ]
static targets = [ 'entry', 'category' ]
initialize() {
useDebounce(this)
@@ -14,17 +14,20 @@ export default class extends Controller {
filter(e) {
let value = e.target.value
if (value.length < 3) {
this.entryTargets.forEach(entry => {
entry.classList.remove('hidden')
})
this.entryTargets.forEach(entry => entry.classList.remove('hidden'))
this.categoryTargets.forEach(category => category.classList.remove('hidden'))
return
}
const pattern = new RegExp(value, 'i')
this.entryTargets.forEach(entry => {
const question = entry.querySelector('button span').textContent
const answer = entry.querySelector('[data-rte-content]').textContent
const matches = question.match(pattern) || answer.match(pattern)
entry.classList.toggle('hidden', !matches)
entry.classList.toggle('hidden', !question.match(pattern) && !answer.match(pattern))
})
this.categoryTargets.forEach(category => {
const hasVisible = Array.from(category.querySelectorAll('[data-faq-target="entry"]'))
.some(entry => !entry.classList.contains('hidden'))
category.classList.toggle('hidden', !hasVisible)
})
}
}
@@ -0,0 +1,36 @@
<html data-namespace-typo3-fluid="true" lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers"
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers">
<f:if condition="{faqs}">
<div class="mt-6"
data-faq-target="category">
<f:if condition="{category}">
<span class="headline--4 text-white uppercase mb-3 block">{category}</span>
</f:if>
<f:for each="{faqs}" as="faq">
<div class="p-4 rounded mb-2"
data-controller="collapse"
data-collapse-collapsed-value="true"
data-faq-target="entry">
<button type="button"
aria-label="Antwort anzeigen/ausblenden"
class="text-lg md:text-xl text-white flex items-center space-x-4"
data-action="collapse#toggle">
{ep:icon(icon: 'chevron-right', class: 'w-4 h-4 text-white transition-transform duration-200 ease-in-out', data: '{collapse-target: \'icon\'}')}
<span class="text-left">
{faq.data.question}
</span>
</button>
<div class="text-white pt-2 transition-transform ease-out overflow-hidden origin-top transform hidden"
data-collapse-target="container"
data-rte-content>
{faq.data.answer -> f:format.html()}
</div>
</div>
</f:for>
</div>
</f:if>
</html>
@@ -0,0 +1,42 @@
<html data-namespace-typo3-fluid="true" lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers"
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers">
<f:layout name="Default"/>
<f:section name="Main">
<f:if condition="{faqs}">
<div class="bg-winter my-4">
<div class="bg-ep-primary/90 sbw:bg-sbw-primary/90 uch:bg-uch-primary/90 ser:bg-ser-primary/90 py-8">
<div class="container"
data-controller="faq">
<span class="headline--3 text-white uppercase mb-4">
Häufig gestellte Fragen
</span>
<div class="mb-4 pr-2 w-80 border-b border-r border-white flex items-center justify-between">
<input type="text"
aria-label="Suchbegriff"
data-action="faq#filter"
class="bg-transparent border-0 uppercase ring-0 focus:ring-0 placeholder-white text-white"
placeholder="Suchbegriff">
{ep:icon(icon: 'search', class: 'w-6 h-6 text-white')}
</div>
<f:groupedFor each="{faqs}" as="groupFaqs" groupBy="data.category" groupKey="categoryName">
<f:render partial="FaqGroup" arguments="{faqs: groupFaqs, category: categoryName}"/>
</f:groupedFor>
<f:if condition="{settings.infoPageUid}">
<div class="flex items-center justify-end space-x-2 text-sm text-white">
{ep:icon(icon: 'info-circle', class: 'w-4 h-4')}
<a href="{f:uri.typolink(parameter: settings.infoPageUid)}" class="underline">
Weitere Reiseinfos findet ihr hier
</a>
</div>
</f:if>
</div>
</div>
</div>
</f:if>
</f:section>
</html>