feat: content element for faq overview grouped by categories
addresses #869b064ah
This commit is contained in:
+28
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
defined('TYPO3_MODE') or die();
|
||||||
|
|
||||||
|
call_user_func(function() {
|
||||||
|
$frontendLanguageFilePrefix = 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:';
|
||||||
|
|
||||||
|
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTcaSelectItem(
|
||||||
|
'tt_content',
|
||||||
|
'CType',
|
||||||
|
[
|
||||||
|
'FAQ Alle Kategorien',
|
||||||
|
'faq_overview',
|
||||||
|
'content-ep_theme-ce',
|
||||||
|
],
|
||||||
|
'nlform',
|
||||||
|
'after'
|
||||||
|
);
|
||||||
|
|
||||||
|
$GLOBALS['TCA']['tt_content']['types']['faq_overview'] = [
|
||||||
|
'showitem' => '
|
||||||
|
--palette--;' . $frontendLanguageFilePrefix . 'palette.general;general,
|
||||||
|
--div--;' . $frontendLanguageFilePrefix . 'tabs.access,
|
||||||
|
hidden;' . $frontendLanguageFilePrefix . 'field.default.hidden,
|
||||||
|
--div--;' . $frontendLanguageFilePrefix . 'tabs.extended
|
||||||
|
',
|
||||||
|
];
|
||||||
|
});
|
||||||
+7
-1
@@ -85,6 +85,12 @@ mod {
|
|||||||
}
|
}
|
||||||
special {
|
special {
|
||||||
elements {
|
elements {
|
||||||
|
faq_overview {
|
||||||
|
iconIdentifier = content-ep_theme-ce
|
||||||
|
title = FAQ Alle Kategorien
|
||||||
|
description = Alle FAQ-Einträge nach Kategorie gruppiert
|
||||||
|
tt_content_defValues.CType = faq_overview
|
||||||
|
}
|
||||||
lineup {
|
lineup {
|
||||||
iconIdentifier = content-ep_theme-ce
|
iconIdentifier = content-ep_theme-ce
|
||||||
title = Lineup
|
title = Lineup
|
||||||
@@ -104,7 +110,7 @@ mod {
|
|||||||
tt_content_defValues.CType = nlform
|
tt_content_defValues.CType = nlform
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
show := addToList(lineup, event_pricetable, nlform)
|
show := addToList(faq_overview, lineup, event_pricetable, nlform)
|
||||||
}
|
}
|
||||||
common {
|
common {
|
||||||
elements {
|
elements {
|
||||||
|
|||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
tt_content.faq_overview =< lib.contentElement
|
||||||
|
tt_content.faq_overview {
|
||||||
|
templateName = FaqOverview
|
||||||
|
settings {
|
||||||
|
infoPageUid = {$plugin.tx_eptheme.settings.infoPageUid}
|
||||||
|
}
|
||||||
|
dataProcessing {
|
||||||
|
10 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor
|
||||||
|
10 {
|
||||||
|
table = tx_epproducts_domain_model_faq
|
||||||
|
where = category != ''
|
||||||
|
orderBy = category ASC, uid ASC
|
||||||
|
pidInList = {$plugin.tx_epproducts.settings.faqsStoragePid}
|
||||||
|
as = faqs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+9
-6
@@ -5,7 +5,7 @@ export default class extends Controller {
|
|||||||
|
|
||||||
static debounces = [ 'filter' ]
|
static debounces = [ 'filter' ]
|
||||||
|
|
||||||
static targets = [ 'entry' ]
|
static targets = [ 'entry', 'category' ]
|
||||||
|
|
||||||
initialize() {
|
initialize() {
|
||||||
useDebounce(this)
|
useDebounce(this)
|
||||||
@@ -14,17 +14,20 @@ export default class extends Controller {
|
|||||||
filter(e) {
|
filter(e) {
|
||||||
let value = e.target.value
|
let value = e.target.value
|
||||||
if (value.length < 3) {
|
if (value.length < 3) {
|
||||||
this.entryTargets.forEach(entry => {
|
this.entryTargets.forEach(entry => entry.classList.remove('hidden'))
|
||||||
entry.classList.remove('hidden')
|
this.categoryTargets.forEach(category => category.classList.remove('hidden'))
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const pattern = new RegExp(value, 'i')
|
const pattern = new RegExp(value, 'i')
|
||||||
this.entryTargets.forEach(entry => {
|
this.entryTargets.forEach(entry => {
|
||||||
const question = entry.querySelector('button span').textContent
|
const question = entry.querySelector('button span').textContent
|
||||||
const answer = entry.querySelector('[data-rte-content]').textContent
|
const answer = entry.querySelector('[data-rte-content]').textContent
|
||||||
const matches = question.match(pattern) || answer.match(pattern)
|
entry.classList.toggle('hidden', !question.match(pattern) && !answer.match(pattern))
|
||||||
entry.classList.toggle('hidden', !matches)
|
})
|
||||||
|
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>
|
||||||
+42
@@ -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>
|
||||||
Reference in New Issue
Block a user