WIP Migrate mobile search

This commit is contained in:
Björn Fromme
2021-10-22 18:35:02 +02:00
parent c75c86c3ca
commit a5b88ebf47
20 changed files with 654 additions and 506 deletions
@@ -0,0 +1,100 @@
<?php
namespace EP\EpProducts\Controller;
/***************************************************************
*
* Copyright notice
*
* (c) 2021 Björn Fromme <[email protected]>, dreipunktnull
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use EP\EpProducts\Service\FilterService;
use EP\EpProducts\Traits\RequestArgumentTypeConversionTrait;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
class AjaxFilterPanelController extends ActionController
{
use RequestArgumentTypeConversionTrait;
/**
* @var \EP\EpProducts\Service\FilterService
*/
protected $filterService;
/**
* @param FilterService $filterService
*/
public function __construct(FilterService $filterService)
{
$this->filterService = $filterService;
}
public function initializeAction()
{
$forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true);
$this->processFilterSettingsArgument($forcedConceptUids);
}
/**
* @param array $filterSettings
*/
public function optionsAction(array $filterSettings)
{
$forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true);
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids']);
$excludedRegionUids = GeneralUtility::trimExplode(',', $this->settings['excludedRegionUids']);
$filterOptions = $this->filterService->getFilterOptions(
$filterSettings,
$excludedConceptUids,
$excludedRegionUids,
$forcedConceptUids
);
$this->view->assignMultiple([
'filterSettings' => $filterSettings,
'filterOptions' => $filterOptions,
]);
}
/**
* @param array $filterSettings
*/
public function searchAction(array $filterSettings)
{
$uri = $this->uriBuilder
->reset()
->setCreateAbsoluteUri(true)
->setTargetPageUid($this->settings['defaultSearchPageUid'])
->uriFor(
'searchresult',
['filterSettings' => $filterSettings],
'Search',
'epproducts',
'searchresult'
);
return json_encode($uri, JSON_THROW_ON_ERROR);
}
}
@@ -74,19 +74,6 @@ class SearchController extends ActionController
]); ]);
} }
public function searchboxAction()
{
$searchParams = $this->searchResultService->getNormalizedSearchParams();
$filterSettings = $this->filterService->getNormalizedFilterSettings();
$filterOptions = $this->filterService->getFilterOptions($filterSettings);
$this->view->assignMultiple([
'filterSettings' => $filterSettings,
'filterOptions' => $filterOptions,
'searchParams' => $searchParams,
]);
}
public function initializeProcessSearchAction() public function initializeProcessSearchAction()
{ {
$this->processSearchParamsArgument(); $this->processSearchParamsArgument();
@@ -148,6 +148,10 @@ tx_epproducts_ajax_json {
1 = pricetable 1 = pricetable
2 = searchresult 2 = searchresult
} }
AjaxFilterPanel {
1 = options
2 = search
}
AjaxDate { AjaxDate {
1 = dates 1 = dates
} }
@@ -295,6 +295,7 @@ $iconRegistry->registerIcon(
'ajax', 'ajax',
[ [
'AjaxSearch' => 'searchresult', 'AjaxSearch' => 'searchresult',
'AjaxFilterPanel' => 'options,search',
'AjaxDate' => 'dates', 'AjaxDate' => 'dates',
'AjaxContingent' => 'list,rooms', 'AjaxContingent' => 'list,rooms',
'AjaxTable' => 'datestable,pricetable,pricetableHtml,eventPricetable,daytripRooms', 'AjaxTable' => 'datestable,pricetable,pricetableHtml,eventPricetable,daytripRooms',
@@ -304,6 +305,7 @@ $iconRegistry->registerIcon(
], ],
[ [
'AjaxSearch' => 'searchresult', 'AjaxSearch' => 'searchresult',
'AjaxFilterPanel' => 'options,search',
'AjaxDate' => 'dates', 'AjaxDate' => 'dates',
'AjaxContingent' => 'list,rooms', 'AjaxContingent' => 'list,rooms',
'AjaxTable' => 'datestable,pricetable,pricetableHtml,eventPricetable,daytripRooms', 'AjaxTable' => 'datestable,pricetable,pricetableHtml,eventPricetable,daytripRooms',
@@ -1,18 +0,0 @@
lib.searchBox = USER
lib.searchBox {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
extensionName = EpProducts
pluginName = searchbox
vendorName = EP
controller = Search
action = searchbox
switchableControllerActions {
Search {
1 = searchbox
}
}
settings =< plugin.tx_epproducts.settings
settings.searchPageUid < plugin.tx_epproducts.settings.defaultSearchPageUid
persistence =< plugin.tx_epproducts.persistence
view =< plugin.tx_epproducts.view
}
@@ -1,12 +0,0 @@
import { Controller } from 'stimulus'
export default class extends Controller {
static targets = [ 'form', 'container' ]
static values = { loading: Boolean }
submit(e) {
}
}
@@ -0,0 +1,89 @@
import { Controller } from 'stimulus'
import { useFetch} from '../mixins/use_fetch'
export default class extends Controller {
static targets = [
'form',
'container',
'loadingIndicator',
'dateFrom',
'dateTo',
]
static values = {
optionsUri: String,
searchUri: String,
loading: Boolean,
show: Boolean,
}
initialize() {
useFetch(this)
}
open(e) {
if (e.detail === 'mobile-search') {
this.showValue = true
this.load()
}
}
close() {
this.showValue = false
this.containerTarget.innerHTML = ''
}
filter() {
this.load({
method: 'POST',
body: new FormData(this.formTarget)
})
}
reset() {
this.load({ method: 'POST' })
}
load(options) {
this.loadingValue = true
fetch(this.optionsUriValue, options)
.then(this.checkStatus)
.then(this.parseHTML)
.then(html => {
this.containerTarget.innerHTML = html
})
.finally(() => {
this.loadingValue = false
})
}
search() {
const options = {
method: 'POST',
body: new FormData(this.formTarget)
}
this.loadingValue = true
fetch(this.searchUriValue, options)
.then(this.checkStatus)
.then(this.parseJSON)
.then(uri => {
window.location = uri
})
}
selectDateRange(e) {
this.dateFromTarget.value = e.detail.from
this.dateToTarget.value = e.detail.to
this.filter()
}
showValueChanged() {
this.element.classList.toggle('hidden', false === this.showValue)
}
loadingValueChanged() {
this.containerTarget.classList.toggle('opacity-25', this.loadingValue === true)
this.loadingIndicatorTarget.classList.toggle('hidden', this.loadingValue === false)
}
}
@@ -49,7 +49,7 @@ export default class extends Controller {
this.busIconTargets.forEach(icon => { this.busIconTargets.forEach(icon => {
let busPrice = parseInt(icon.dataset.busPrice) let busPrice = parseInt(icon.dataset.busPrice)
let busIncluded = !!icon.dataset.busIncluded let busIncluded = !!icon.dataset.busIncluded
icon.classList.toggle('hidden', this.hideBusIcon(busPrice, busIncluded)) icon.classList.toggle('hidden', this.isHideBusIcon(busPrice, busIncluded))
}) })
if (this.hasSurchargeToggleLabelTarget) { if (this.hasSurchargeToggleLabelTarget) {
let labelDefault = this.surchargeToggleLabelTarget.dataset.labelDefault let labelDefault = this.surchargeToggleLabelTarget.dataset.labelDefault
@@ -86,7 +86,7 @@ export default class extends Controller {
return minPrice return minPrice
} }
hideBusIcon(busPrice, busIncluded) { isHideBusIcon(busPrice, busIncluded) {
return ( return (
busPrice && this.modeValue !== 'surcharge' || busPrice && this.modeValue !== 'surcharge' ||
busIncluded && this.modeValue === 'discount' busIncluded && this.modeValue === 'discount'
@@ -16,7 +16,7 @@
<f:render partial="ContactBar" arguments="{_all}"/> <f:render partial="ContactBar" arguments="{_all}"/>
<f:render partial="Topnav" arguments="{_all}"/> <f:render partial="Topnav" arguments="{_all}"/>
<f:render partial="Mobilenav" section="Main" arguments="{_all}"/> <f:render partial="Mobilenav" section="Main" arguments="{_all}"/>
<f:cObject typoscriptObjectPath="lib.searchBox"/> <f:render partial="Search/MobileSearch" arguments="{_all}"/>
<f:render partial="Config" arguments="{_all}" /> <f:render partial="Config" arguments="{_all}" />
<f:render partial="Icons" arguments="{_all}"/> <f:render partial="Icons" arguments="{_all}"/>
</html> </html>
@@ -18,6 +18,7 @@
<f:render partial="ContactBar" arguments="{_all}"/> <f:render partial="ContactBar" arguments="{_all}"/>
<f:render partial="Topnav" arguments="{_all}"/> <f:render partial="Topnav" arguments="{_all}"/>
<f:render partial="Mobilenav" section="Main" arguments="{_all}"/> <f:render partial="Mobilenav" section="Main" arguments="{_all}"/>
<f:render partial="Search/MobileSearch" arguments="{_all}"/>
<f:render partial="Config" arguments="{_all}" /> <f:render partial="Config" arguments="{_all}" />
<f:render partial="Icons" arguments="{_all}"/> <f:render partial="Icons" arguments="{_all}"/>
</html> </html>
@@ -26,6 +26,7 @@
<f:render partial="ContactBar" arguments="{_all}"/> <f:render partial="ContactBar" arguments="{_all}"/>
<f:render partial="Topnav" arguments="{_all}"/> <f:render partial="Topnav" arguments="{_all}"/>
<f:render partial="Mobilenav" section="Main" arguments="{_all}"/> <f:render partial="Mobilenav" section="Main" arguments="{_all}"/>
<f:render partial="Search/MobileSearch" arguments="{_all}"/>
<f:render partial="Config" arguments="{_all}" /> <f:render partial="Config" arguments="{_all}" />
<f:render partial="Icons" arguments="{_all}"/> <f:render partial="Icons" arguments="{_all}"/>
</html> </html>
@@ -26,6 +26,7 @@
<f:render partial="ContactBar" arguments="{_all}"/> <f:render partial="ContactBar" arguments="{_all}"/>
<f:render partial="Topnav" arguments="{_all}"/> <f:render partial="Topnav" arguments="{_all}"/>
<f:render partial="Mobilenav" section="Main" arguments="{_all}"/> <f:render partial="Mobilenav" section="Main" arguments="{_all}"/>
<f:render partial="Search/MobileSearch" arguments="{_all}"/>
<f:render partial="Config" arguments="{_all}" /> <f:render partial="Config" arguments="{_all}" />
<f:render partial="Icons" arguments="{_all}"/> <f:render partial="Icons" arguments="{_all}"/>
</html> </html>
@@ -16,19 +16,15 @@
<f:render section="FirstLevel" arguments="{_all}"/> <f:render section="FirstLevel" arguments="{_all}"/>
</div> </div>
<div class="flex lg:hidden items-center space-x-4"> <div class="flex lg:hidden items-center space-x-4">
<f:if condition="{data.tx_eptheme_hide_searchbar}">
<f:else>
<button type="button" <button type="button"
class="focus:outline-none text-gray-800" class="focus:outline-none text-gray-800"
data-controller="overlay-toggle" data-controller="overlay-toggle"
data-overlay-toggle-id-value="search" data-overlay-toggle-id-value="mobile-search"
data-action="overlay-toggle#invokeToggle"> data-action="overlay-toggle#invokeToggle">
<svg class="w-8 h-8 text-gray-800"> <svg class="w-8 h-8 text-gray-800">
<use href="#icon-search"></use> <use href="#icon-search"></use>
</svg> </svg>
</button> </button>
</f:else>
</f:if>
<button type="button" <button type="button"
class="focus:outline-none text-gray-800" class="focus:outline-none text-gray-800"
data-controller="overlay-toggle" data-controller="overlay-toggle"
@@ -3,11 +3,6 @@
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers" xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers"
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers"> xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
<f:form object="{filterSettings}"
name="filterSettings"
pluginName="Ajax"
data="{'search-target': 'form'}">
<div class="mb-4 p-4 bg-ep-primary text-white" <div class="mb-4 p-4 bg-ep-primary text-white"
data-controller="collapse" data-controller="collapse"
data-collapse-collapsed-value="{f:if(condition: '{filterSettings.dateFrom} || {filterSettings.dateTo}', then: 'false', else: 'true')}"> data-collapse-collapsed-value="{f:if(condition: '{filterSettings.dateFrom} || {filterSettings.dateTo}', then: 'false', else: 'true')}">
@@ -24,9 +19,9 @@
</button> </button>
<div data-collapse-target="container"> <div data-collapse-target="container">
<f:form.hidden property="dateFrom" <f:form.hidden property="dateFrom"
data="{'search-target': 'dateFrom'}"/> data="{'search-target': 'dateFrom', 'mobile-search-target': 'dateFrom'}"/>
<f:form.hidden property="dateTo" <f:form.hidden property="dateTo"
data="{'search-target': 'dateTo'}"/> data="{'search-target': 'dateTo', 'mobile-search-target': 'dateTo'}"/>
<div data-controller="collapse datepicker" <div data-controller="collapse datepicker"
data-datepicker-date-from-value="{filterSettings.dateFrom}" data-datepicker-date-from-value="{filterSettings.dateFrom}"
@@ -111,7 +106,7 @@
<label> <label>
<f:form.checkbox class="mr-2 rounded-full w-5 h-5 border-white ring-0 bg-transparent focus:ring-0 focus:border-none text-ep-primary" <f:form.checkbox class="mr-2 rounded-full w-5 h-5 border-white ring-0 bg-transparent focus:ring-0 focus:border-none text-ep-primary"
property="conceptUids" property="conceptUids"
data="{action: 'search#filter'}" data="{action: 'search#filter mobile-search#filter'}"
value="{concept.uid}"/> value="{concept.uid}"/>
<span class="inline-block py-1 px-2 bg-concept-{concept.code} text-white"> <span class="inline-block py-1 px-2 bg-concept-{concept.code} text-white">
{concept.name} {concept.name}
@@ -146,7 +141,7 @@
<label class="flex items-start"> <label class="flex items-start">
<f:form.checkbox class="w-5 h-5 border-ep-primary ring-0 bg-transparent focus:ring-0 focus:border-none text-ep-primary" <f:form.checkbox class="w-5 h-5 border-ep-primary ring-0 bg-transparent focus:ring-0 focus:border-none text-ep-primary"
property="countryUids" property="countryUids"
data="{action: 'search#filter'}" data="{action: 'search#filter mobile-search#filter'}"
value="{destination.country.uid}"/> value="{destination.country.uid}"/>
<span class="pl-2 leading-none"> <span class="pl-2 leading-none">
<strong>{destination.country.label}</strong> <strong>{destination.country.label}</strong>
@@ -162,7 +157,7 @@
<label class="flex items-start"> <label class="flex items-start">
<f:form.checkbox class="w-5 h-5 border-ep-primary ring-0 bg-transparent focus:ring-0 focus:border-none text-ep-primary" <f:form.checkbox class="w-5 h-5 border-ep-primary ring-0 bg-transparent focus:ring-0 focus:border-none text-ep-primary"
property="regionUids" property="regionUids"
data="{action: 'search#filter'}" data="{action: 'search#filter mobile-search#filter'}"
value="{region.uid}"/> value="{region.uid}"/>
<span class="leading-none pl-2"> <span class="leading-none pl-2">
{region.label} {region.label}
@@ -199,7 +194,7 @@
<label class="flex items-start"> <label class="flex items-start">
<f:form.checkbox class="w-5 h-5 border-ep-primary ring-0 bg-transparent focus:ring-0 focus:border-none text-ep-primary" <f:form.checkbox class="w-5 h-5 border-ep-primary ring-0 bg-transparent focus:ring-0 focus:border-none text-ep-primary"
property="priceRanges" property="priceRanges"
data="{action: 'search#filter'}" data="{action: 'search#filter mobile-search#filter'}"
value="{range.uid}"/> value="{range.uid}"/>
<span class="leading-none pl-2"> <span class="leading-none pl-2">
{ep:priceRange(min: range.min, max: range.max)} {ep:priceRange(min: range.min, max: range.max)}
@@ -229,7 +224,7 @@
<f:form.select class="w-full border-0 focus:ring-0 bg-right mt-2 p-0" <f:form.select class="w-full border-0 focus:ring-0 bg-right mt-2 p-0"
property="pax" property="pax"
options="{filterOptions.pax}" options="{filterOptions.pax}"
data="{action: 'search#filter'}"/> data="{action: 'search#filter mobile-search#filter'}"/>
</div> </div>
</div> </div>
@@ -261,7 +256,7 @@
<label class="flex items-start"> <label class="flex items-start">
<f:form.checkbox class="w-5 h-5 border-ep-primary ring-0 bg-transparent focus:ring-0 focus:border-none text-ep-primary" <f:form.checkbox class="w-5 h-5 border-ep-primary ring-0 bg-transparent focus:ring-0 focus:border-none text-ep-primary"
property="hotelTypes" property="hotelTypes"
data="{action: 'search#filter'}" data="{action: 'search#filter mobile-search#filter'}"
value="{type}"/> value="{type}"/>
<span class="leading-none pl-2"> <span class="leading-none pl-2">
{hotelTypes.{type}} {hotelTypes.{type}}
@@ -295,7 +290,7 @@
<label class="flex items-start"> <label class="flex items-start">
<f:form.checkbox class="w-5 h-5 border-ep-primary ring-0 bg-transparent focus:ring-0 focus:border-none text-ep-primary" <f:form.checkbox class="w-5 h-5 border-ep-primary ring-0 bg-transparent focus:ring-0 focus:border-none text-ep-primary"
property="boardTypes" property="boardTypes"
data="{action: 'search#filter'}" data="{action: 'search#filter mobile-search#filter'}"
value="{type.uid}"/> value="{type.uid}"/>
<span class="pl-2 leading-none"> <span class="pl-2 leading-none">
{type.label} {type.label}
@@ -337,7 +332,7 @@
<label class="flex items-start"> <label class="flex items-start">
<f:form.checkbox class="w-5 h-5 border-ep-primary ring-0 bg-transparent focus:ring-0 focus:border-none text-ep-primary" <f:form.checkbox class="w-5 h-5 border-ep-primary ring-0 bg-transparent focus:ring-0 focus:border-none text-ep-primary"
property="roomTypes" property="roomTypes"
data="{action: 'search#filter'}" data="{action: 'search#filter mobile-search#filter'}"
value="{type}"/> value="{type}"/>
<span class="leading-none pl-2"> <span class="leading-none pl-2">
{roomTypes.{type}} {roomTypes.{type}}
@@ -370,7 +365,7 @@
<label class="flex items-start"> <label class="flex items-start">
<f:form.checkbox class="w-5 h-5 border-ep-primary ring-0 bg-transparent focus:ring-0 focus:border-none text-ep-primary" <f:form.checkbox class="w-5 h-5 border-ep-primary ring-0 bg-transparent focus:ring-0 focus:border-none text-ep-primary"
property="bus" property="bus"
data="{action: 'search#filter'}" data="{action: 'search#filter mobile-search#filter'}"
value="1"/> value="1"/>
<span class="leading-none pl-2"> <span class="leading-none pl-2">
Busanreise Busanreise
@@ -384,6 +379,4 @@
</div> </div>
</f:form>
</html> </html>
@@ -3,15 +3,17 @@
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers"> xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
<div class="grid grid-cols-3 gap-8"> <div class="grid grid-cols-3 gap-8">
<div class="col-span-3 lg:col-span-1 relative" <div class="col-span-3 lg:col-span-1 relative">
data-controller="collapse" <div class="hidden lg:block bg-white p-4">
data-collapse-until-value="1024">
<div class="lg:block bg-white p-4"
data-collapse-target="container">
<h3 class="headline headline--underlined mb-4"> <h3 class="headline headline--underlined mb-4">
Filter Filter
</h3> </h3>
<f:form object="{filterSettings}"
name="filterSettings"
pluginName="Ajax"
data="{'search-target': 'form'}">
<f:render partial="Search/FilterPanel" arguments="{_all}"/> <f:render partial="Search/FilterPanel" arguments="{_all}"/>
</f:form>
<div class="mt-4"> <div class="mt-4">
<button type="button" <button type="button"
class="button button--secondary w-full" class="button button--secondary w-full"
@@ -20,6 +22,38 @@
</button> </button>
</div> </div>
</div> </div>
<div class="fixed lg:hidden top-0 left-0 inset-0 w-screen h-screen pt-14 pb-10 z-50 bg-gray-700 hidden"
data-controller="mobile-search"
data-mobile-search-options-uri-value="{ep:uri.ajax(controller: 'AjaxFilterPanel', action: 'options', pageUid: settings.defaultAjaxUid, arguments: '{filterSettings: filterSettings}', format: 'html')}"
data-action="overlay-toggle:toggle@window->mobile-search#open">
<div class="fixed top-0 left-0 z-100 inset-x-0 px-4 py-2 flex justify-between bg-white shadow-md">
<a href="{f:uri.typolink(parameter: settings.defaultHomeUid)}"
class="block lg:pb-4"
title="{settings.defaultTitle}">
<img class="block h-10 lg:h-12 w-auto" src="{f:uri.image(src: settings.logoImage)}" alt="{settings.defaultTitle}">
</a>
<button type="button"
class="focus:outline-none" data-action="mobile-search#close">
<svg class="w-8 h-8">
<use href="#icon-close"></use>
</svg>
</button>
</div>
<div data-mobile-search-target="container"
class="h-full w-full overflow-y-scroll p-4 bg-white">
</div>
<div class="fixed top-0 left-0 z-20 w-full h-full hidden"
data-mobile-search-target="loadingIndicator">
<div class="absolute top-1/2 left-1/2 transform -translate-xy-1/2 flex items-center space-x-4 bg-ep-secondary text-white text-lg p-4 rounded">
<svg class="w-6 h-6">
<use href="#icon-spinner"></use>
</svg>
<span>Suche wird geladen...</span>
</div>
</div>
</div>
</div> </div>
<div class="col-span-3 lg:col-span-2 relative"> <div class="col-span-3 lg:col-span-2 relative">
<f:render partial="Search/Result" arguments="{_all}"/> <f:render partial="Search/Result" arguments="{_all}"/>
@@ -0,0 +1,37 @@
<html xmlns="http://www.w3.org/1999/xhtml" lang="en"
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers"
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers">
<div class="fixed lg:hidden top-0 left-0 inset-0 w-screen h-screen pt-14 pb-10 z-50 bg-gray-700 hidden"
data-controller="mobile-search"
data-mobile-search-options-uri-value="{ep:uri.ajax(controller: 'AjaxFilterPanel', action: 'options', pageUid: settings.defaultAjaxUid, format: 'html')}"
data-mobile-search-search-uri-value="{ep:uri.ajax(controller: 'AjaxFilterPanel', action: 'search', pageUid: settings.defaultAjaxUid, format: 'json')}"
data-action="overlay-toggle:toggle@window->mobile-search#open">
<div class="fixed top-0 left-0 z-100 inset-x-0 px-4 py-2 flex justify-between bg-white shadow-md">
<a href="{f:uri.typolink(parameter: settings.defaultHomeUid)}"
class="block lg:pb-4"
title="{settings.defaultTitle}">
<img class="block h-10 lg:h-12 w-auto" src="{f:uri.image(src: settings.logoImage)}" alt="{settings.defaultTitle}">
</a>
<button type="button"
class="focus:outline-none" data-action="mobile-search#close">
<svg class="w-8 h-8">
<use href="#icon-close"></use>
</svg>
</button>
</div>
<div data-mobile-search-target="container"
class="h-full w-full overflow-y-scroll p-4 bg-white">
</div>
<div class="fixed top-0 left-0 z-20 w-full h-full hidden"
data-mobile-search-target="loadingIndicator">
<div class="absolute top-1/2 left-1/2 transform -translate-xy-1/2 flex items-center space-x-4 bg-ep-secondary text-white text-lg p-4 rounded">
<svg class="w-6 h-6">
<use href="#icon-spinner"></use>
</svg>
<span>Suche wird geladen...</span>
</div>
</div>
</div>
</html>
@@ -5,6 +5,28 @@
<f:layout name="Default"/> <f:layout name="Default"/>
<f:section name="Main">
<f:form object="{filterSettings}"
name="filterSettings"
pluginName="Ajax"
action=""
data="{'mobile-search-target': 'form'}">
<f:render partial="Search/FilterPanel" arguments="{_all}"/> <f:render partial="Search/FilterPanel" arguments="{_all}"/>
</f:form>
<div class="mt-4">
<button type="button"
class="button button--primary w-full"
data-action="mobile-search#search">
Ergebnis anzeigen
</button>
</div>
<div class="mt-4">
<button type="button"
class="button button--secondary w-full"
data-action="mobile-search#reset">
Filter zurücksetzen
</button>
</div>
</f:section>
</html> </html>
@@ -1,20 +0,0 @@
<div xmlns="http://www.w3.org/1999/xhtml" lang="en"
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers"
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers">
<f:layout name="Form/Default"/>
<f:section name="Main">
<div class="relative form form--border"
data-controller="contactform">
<div data-contactform-target="container">
<f:render partial="ContactForm/Simple" arguments="{_all}"/>
</div>
<div class="hidden form__overlay"
data-contactform-target="loadingIndicator">
<img src="{f:uri.resource(path: 'images/ajax-loader-white.gif', extensionName: 'ep_theme')}" alt="Processing...">
</div>
</div>
</f:section>
</div>
@@ -1,69 +0,0 @@
<html xmlns="http://www.w3.org/1999/xhtml" lang="en"
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">
<div class="fixed lg:hidden top-0 left-0 inset-0 w-screen h-screen pt-14 pb-10 z-50 bg-gray-700 hidden"
data-controller="overlay-toggle"
data-overlay-toggle-id-value="search"
data-overlay-toggle-target="overlay"
data-action="overlay-toggle:toggle@window->overlay-toggle#toggle">
<div class="fixed top-0 left-0 z-100 inset-x-0 px-4 py-2 flex justify-between bg-white shadow-md">
<a href="{f:uri.typolink(parameter: settings.defaultHomeUid)}"
class="block lg:pb-4"
title="{settings.defaultTitle}">
<img class="block h-10 lg:h-12 w-auto" src="{f:uri.image(src: settings.logoImage)}" alt="{settings.defaultTitle}">
</a>
<button type="button"
class="focus:outline-none" data-action="overlay-toggle#invokeToggle">
<svg class="w-8 h-8">
<use href="#icon-close"></use>
</svg>
</button>
</div>
<div class="h-full w-full overflow-y-scroll p-4">
<f:form action="processSearch" controller="Search" method="post" name="searchParams"
object="{searchParams}" pluginName="searchresult" extensionName="epproducts"
pageUid="{settings.defaultSearchPageUid}">
<f:form.hidden property="dateFrom" data="{'searchbar-target': 'dateFrom'}"/>
<f:form.hidden property="dateTo" data="{'searchbar-target': 'dateTo'}"/>
<f:form.hidden property="pax" data="{'searchbar-target': 'pax'}"/>
<f:form.hidden property="destinationUid" data="{'searchbar-target': 'destinationUid'}"/>
<f:form.hidden property="destinationType" data="{'searchbar-target': 'destinationType'}"/>
<f:form.hidden property="priceRange" data="{'searchbar-target': 'priceRange'}"/>
<label>Früheste Anreise</label>
<input
type="date"
class="border-gray-400 focus:border-gray-800">
<label>Späteste Abreise</label>
<input
type="date"
class="border-gray-400 focus:border-gray-800">
<label>Personen</label>
<input
type="number"
min="1"
max="20"
class="border-gray-400 focus:border-gray-800">
<div class="grid grid-cols-2 gap-4">
<button type="submit"
class="button">
Suchen
</button>
<button type="submit"
class="button button--secondary">
Detailsuche
</button>
</div>
</f:form>
</div>
</div>
</f:section>
</html>
@@ -3,7 +3,7 @@
<f:layout name="Default"/> <f:layout name="Default"/>
<f:section name="Main"> <f:section name="Main">
<div class="py-8 bg-ep-primary-bg"> <div class="pb-8 md:py-8 bg-ep-primary-bg">
<div class="container" <div class="container"
data-controller="search" data-controller="search"
data-search-uri-value="{ep:uri.ajax(controller: 'AjaxSearch', action: 'searchresult', pageUid: settings.defaultAjaxUid, format: 'html')}" data-search-uri-value="{ep:uri.ajax(controller: 'AjaxSearch', action: 'searchresult', pageUid: settings.defaultAjaxUid, format: 'html')}"