WIP Migrate mobile search
This commit is contained in:
@@ -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()
|
||||
{
|
||||
$this->processSearchParamsArgument();
|
||||
|
||||
@@ -148,6 +148,10 @@ tx_epproducts_ajax_json {
|
||||
1 = pricetable
|
||||
2 = searchresult
|
||||
}
|
||||
AjaxFilterPanel {
|
||||
1 = options
|
||||
2 = search
|
||||
}
|
||||
AjaxDate {
|
||||
1 = dates
|
||||
}
|
||||
|
||||
@@ -295,6 +295,7 @@ $iconRegistry->registerIcon(
|
||||
'ajax',
|
||||
[
|
||||
'AjaxSearch' => 'searchresult',
|
||||
'AjaxFilterPanel' => 'options,search',
|
||||
'AjaxDate' => 'dates',
|
||||
'AjaxContingent' => 'list,rooms',
|
||||
'AjaxTable' => 'datestable,pricetable,pricetableHtml,eventPricetable,daytripRooms',
|
||||
@@ -304,6 +305,7 @@ $iconRegistry->registerIcon(
|
||||
],
|
||||
[
|
||||
'AjaxSearch' => 'searchresult',
|
||||
'AjaxFilterPanel' => 'options,search',
|
||||
'AjaxDate' => 'dates',
|
||||
'AjaxContingent' => 'list,rooms',
|
||||
'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
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
import { Controller } from 'stimulus'
|
||||
|
||||
export default class extends Controller {
|
||||
|
||||
static targets = [ 'form', 'container' ]
|
||||
|
||||
static values = { loading: Boolean }
|
||||
|
||||
submit(e) {
|
||||
|
||||
}
|
||||
}
|
||||
+89
@@ -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)
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -49,7 +49,7 @@ export default class extends Controller {
|
||||
this.busIconTargets.forEach(icon => {
|
||||
let busPrice = parseInt(icon.dataset.busPrice)
|
||||
let busIncluded = !!icon.dataset.busIncluded
|
||||
icon.classList.toggle('hidden', this.hideBusIcon(busPrice, busIncluded))
|
||||
icon.classList.toggle('hidden', this.isHideBusIcon(busPrice, busIncluded))
|
||||
})
|
||||
if (this.hasSurchargeToggleLabelTarget) {
|
||||
let labelDefault = this.surchargeToggleLabelTarget.dataset.labelDefault
|
||||
@@ -86,7 +86,7 @@ export default class extends Controller {
|
||||
return minPrice
|
||||
}
|
||||
|
||||
hideBusIcon(busPrice, busIncluded) {
|
||||
isHideBusIcon(busPrice, busIncluded) {
|
||||
return (
|
||||
busPrice && this.modeValue !== 'surcharge' ||
|
||||
busIncluded && this.modeValue === 'discount'
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<f:render partial="ContactBar" arguments="{_all}"/>
|
||||
<f:render partial="Topnav" 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="Icons" arguments="{_all}"/>
|
||||
</html>
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
<f:render partial="ContactBar" arguments="{_all}"/>
|
||||
<f:render partial="Topnav" 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="Icons" arguments="{_all}"/>
|
||||
</html>
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
<f:render partial="ContactBar" arguments="{_all}"/>
|
||||
<f:render partial="Topnav" 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="Icons" arguments="{_all}"/>
|
||||
</html>
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
<f:render partial="ContactBar" arguments="{_all}"/>
|
||||
<f:render partial="Topnav" 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="Icons" arguments="{_all}"/>
|
||||
</html>
|
||||
|
||||
@@ -16,19 +16,15 @@
|
||||
<f:render section="FirstLevel" arguments="{_all}"/>
|
||||
</div>
|
||||
<div class="flex lg:hidden items-center space-x-4">
|
||||
<f:if condition="{data.tx_eptheme_hide_searchbar}">
|
||||
<f:else>
|
||||
<button type="button"
|
||||
class="focus:outline-none text-gray-800"
|
||||
data-controller="overlay-toggle"
|
||||
data-overlay-toggle-id-value="search"
|
||||
data-action="overlay-toggle#invokeToggle">
|
||||
<svg class="w-8 h-8 text-gray-800">
|
||||
<use href="#icon-search"></use>
|
||||
</svg>
|
||||
</button>
|
||||
</f:else>
|
||||
</f:if>
|
||||
<button type="button"
|
||||
class="focus:outline-none text-gray-800"
|
||||
data-controller="overlay-toggle"
|
||||
data-overlay-toggle-id-value="mobile-search"
|
||||
data-action="overlay-toggle#invokeToggle">
|
||||
<svg class="w-8 h-8 text-gray-800">
|
||||
<use href="#icon-search"></use>
|
||||
</svg>
|
||||
</button>
|
||||
<button type="button"
|
||||
class="focus:outline-none text-gray-800"
|
||||
data-controller="overlay-toggle"
|
||||
|
||||
+343
-350
@@ -3,118 +3,201 @@
|
||||
xmlns:ep="http://typo3.org/ns/EP/EpTheme/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"
|
||||
data-controller="collapse"
|
||||
data-collapse-collapsed-value="{f:if(condition: '{filterSettings.dateFrom} || {filterSettings.dateTo}', then: 'false', else: 'true')}">
|
||||
<button type="button"
|
||||
data-action="click->collapse#toggle"
|
||||
class="flex items-center justify-between w-full">
|
||||
<span class="uppercase font-bold">
|
||||
Reisezeitraum
|
||||
</span>
|
||||
<svg class="w-6 h-6 text-white transform"
|
||||
data-collapse-target="icon">
|
||||
<use href="#icon-arrow-right"></use>
|
||||
</svg>
|
||||
</button>
|
||||
<div data-collapse-target="container">
|
||||
<f:form.hidden property="dateFrom"
|
||||
data="{'search-target': 'dateFrom', 'mobile-search-target': 'dateFrom'}"/>
|
||||
<f:form.hidden property="dateTo"
|
||||
data="{'search-target': 'dateTo', 'mobile-search-target': 'dateTo'}"/>
|
||||
|
||||
<div class="mb-4 p-4 bg-ep-primary text-white"
|
||||
data-controller="collapse"
|
||||
data-collapse-collapsed-value="{f:if(condition: '{filterSettings.dateFrom} || {filterSettings.dateTo}', then: 'false', else: 'true')}">
|
||||
<button type="button"
|
||||
data-action="click->collapse#toggle"
|
||||
class="flex items-center justify-between w-full">
|
||||
<span class="uppercase font-bold">
|
||||
Reisezeitraum
|
||||
</span>
|
||||
<svg class="w-6 h-6 text-white transform"
|
||||
data-collapse-target="icon">
|
||||
<use href="#icon-arrow-right"></use>
|
||||
</svg>
|
||||
</button>
|
||||
<div data-collapse-target="container">
|
||||
<f:form.hidden property="dateFrom"
|
||||
data="{'search-target': 'dateFrom'}"/>
|
||||
<f:form.hidden property="dateTo"
|
||||
data="{'search-target': 'dateTo'}"/>
|
||||
|
||||
<div data-controller="collapse datepicker"
|
||||
data-datepicker-date-from-value="{filterSettings.dateFrom}"
|
||||
data-datepicker-date-to-value="{filterSettings.dateTo}"
|
||||
data-datepicker-min-date-value="{f:format.date(date: 'now', format: 'Y-m-d')}"
|
||||
data-action="collapse:click:outside->collapse#close searchbar:input@window->collapse#close"
|
||||
data-collapse-collapsed-value="true">
|
||||
<div class="relative">
|
||||
<input type="text"
|
||||
data-action="click->collapse#toggle"
|
||||
class="w-full px-0 bg-transparent border-0 ring-0 focus:ring-0 text-white uppercase cursor-pointer placeholder-white"
|
||||
placeholder="Zeitraum"
|
||||
value="{ep:dateRange(dateFrom: filterSettings.dateFrom, dateTo: filterSettings.dateTo, includeLabel: 0)}"
|
||||
data-searchbar-target="dateRangeLabel"/>
|
||||
<svg class="w-6 h-6 text-white absolute right-0 top-0 mt-2 cursor-pointer"
|
||||
data-action="click->collapse#toggle">
|
||||
<use href="#icon-calendar"></use>
|
||||
</svg>
|
||||
<div class="hidden absolute z-20 top-100 mt-2 left-0 min-w-full bg-white p-4 shadow-md rounded"
|
||||
data-collapse-target="container">
|
||||
<div class="flex justify-between divide-x divide-gray-200">
|
||||
<div class="pr-2">
|
||||
<input type="hidden"
|
||||
data-datepicker-target="field">
|
||||
</div>
|
||||
<div class="flex-1 flex flex-col justify-between pl-2">
|
||||
<f:if condition="{settings.datePickerPresets}">
|
||||
<div class="flex flex-col space-y-4">
|
||||
<f:for each="{settings.datePickerPresets}" as="preset">
|
||||
<button type="button"
|
||||
class="button button--small button--light w-full"
|
||||
data-preset='{preset -> f:format.json() -> f:format.raw()}'
|
||||
data-action="datepicker#selectPreset">
|
||||
<span>
|
||||
{preset.label}
|
||||
</span>
|
||||
</button>
|
||||
</f:for>
|
||||
</div>
|
||||
</f:if>
|
||||
<div data-controller="collapse datepicker"
|
||||
data-datepicker-date-from-value="{filterSettings.dateFrom}"
|
||||
data-datepicker-date-to-value="{filterSettings.dateTo}"
|
||||
data-datepicker-min-date-value="{f:format.date(date: 'now', format: 'Y-m-d')}"
|
||||
data-action="collapse:click:outside->collapse#close searchbar:input@window->collapse#close"
|
||||
data-collapse-collapsed-value="true">
|
||||
<div class="relative">
|
||||
<input type="text"
|
||||
data-action="click->collapse#toggle"
|
||||
class="w-full px-0 bg-transparent border-0 ring-0 focus:ring-0 text-white uppercase cursor-pointer placeholder-white"
|
||||
placeholder="Zeitraum"
|
||||
value="{ep:dateRange(dateFrom: filterSettings.dateFrom, dateTo: filterSettings.dateTo, includeLabel: 0)}"
|
||||
data-searchbar-target="dateRangeLabel"/>
|
||||
<svg class="w-6 h-6 text-white absolute right-0 top-0 mt-2 cursor-pointer"
|
||||
data-action="click->collapse#toggle">
|
||||
<use href="#icon-calendar"></use>
|
||||
</svg>
|
||||
<div class="hidden absolute z-20 top-100 mt-2 left-0 min-w-full bg-white p-4 shadow-md rounded"
|
||||
data-collapse-target="container">
|
||||
<div class="flex justify-between divide-x divide-gray-200">
|
||||
<div class="pr-2">
|
||||
<input type="hidden"
|
||||
data-datepicker-target="field">
|
||||
</div>
|
||||
<div class="flex-1 flex flex-col justify-between pl-2">
|
||||
<f:if condition="{settings.datePickerPresets}">
|
||||
<div class="flex flex-col space-y-4">
|
||||
<button type="button"
|
||||
class="button button--small button--light w-full"
|
||||
data-action="collapse#close">
|
||||
schließen
|
||||
</button>
|
||||
<button type="button"
|
||||
class="button button--small button--light w-full"
|
||||
data-action="datepicker#reset">
|
||||
zurücksetzen
|
||||
</button>
|
||||
<f:for each="{settings.datePickerPresets}" as="preset">
|
||||
<button type="button"
|
||||
class="button button--small button--light w-full"
|
||||
data-preset='{preset -> f:format.json() -> f:format.raw()}'
|
||||
data-action="datepicker#selectPreset">
|
||||
<span>
|
||||
{preset.label}
|
||||
</span>
|
||||
</button>
|
||||
</f:for>
|
||||
</div>
|
||||
</f:if>
|
||||
<div class="flex flex-col space-y-4">
|
||||
<button type="button"
|
||||
class="button button--small button--light w-full"
|
||||
data-action="collapse#close">
|
||||
schließen
|
||||
</button>
|
||||
<button type="button"
|
||||
class="button button--small button--light w-full"
|
||||
data-action="datepicker#reset">
|
||||
zurücksetzen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4 p-4 bg-ep-primary text-white"
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4 p-4 bg-ep-primary text-white"
|
||||
data-controller="collapse"
|
||||
data-collapse-collapsed-value="{f:if(condition: '{filterSettings.conceptUids}', then: 'false', else: 'true')}">
|
||||
<button type="button"
|
||||
data-action="click->collapse#toggle"
|
||||
class="flex items-center justify-between w-full">
|
||||
<span class="uppercase font-bold">
|
||||
Reisekonzepte
|
||||
</span>
|
||||
<svg class="w-6 h-6 text-white transform"
|
||||
data-collapse-target="icon">
|
||||
<use href="#icon-arrow-right"></use>
|
||||
</svg>
|
||||
</button>
|
||||
<div data-collapse-target="container"
|
||||
class="pt-2">
|
||||
<ul class="mb-0 p-0 space-y-2">
|
||||
<f:for each="{filterOptions.concepts}" as="concept">
|
||||
<li>
|
||||
<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"
|
||||
property="conceptUids"
|
||||
data="{action: 'search#filter mobile-search#filter'}"
|
||||
value="{concept.uid}"/>
|
||||
<span class="inline-block py-1 px-2 bg-concept-{concept.code} text-white">
|
||||
{concept.name}
|
||||
</span>
|
||||
</label>
|
||||
</li>
|
||||
</f:for>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="px-4 divide-y">
|
||||
|
||||
<div class="py-2"
|
||||
data-controller="collapse"
|
||||
data-collapse-collapsed-value="{f:if(condition: '{filterSettings.conceptUids}', then: 'false', else: 'true')}">
|
||||
data-collapse-collapsed-value="{f:if(condition: '{filterSettings.countryUids} || {filterSettings.regionUids}', then: 'false', else: 'true')}">
|
||||
<button type="button"
|
||||
data-action="click->collapse#toggle"
|
||||
class="flex items-center justify-between w-full">
|
||||
<span class="uppercase font-bold">
|
||||
Reisekonzepte
|
||||
Reiseziel
|
||||
</span>
|
||||
<svg class="w-6 h-6 text-white transform"
|
||||
<svg class="w-6 h-6 transform"
|
||||
data-collapse-target="icon">
|
||||
<use href="#icon-arrow-right"></use>
|
||||
</svg>
|
||||
</button>
|
||||
<div data-collapse-target="container"
|
||||
class="pt-2">
|
||||
<ul class="mb-0 p-0 space-y-2">
|
||||
<f:for each="{filterOptions.concepts}" as="concept">
|
||||
<div data-collapse-target="container">
|
||||
<ul class="mb-0 p-0 pt-2">
|
||||
<f:for each="{filterOptions.destinations}" as="destination">
|
||||
<li class="relative border-b last:border-0 mb-2">
|
||||
<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"
|
||||
property="countryUids"
|
||||
data="{action: 'search#filter mobile-search#filter'}"
|
||||
value="{destination.country.uid}"/>
|
||||
<span class="pl-2 leading-none">
|
||||
<strong>{destination.country.label}</strong>
|
||||
</span>
|
||||
<svg class="absolute top-0 right-0 w-8 h-6">
|
||||
<use href="#icon-flag-{destination.country.code -> f:format.case(mode: 'lower')}"/>
|
||||
</svg>
|
||||
</label>
|
||||
<f:if condition="{destination.regions}">
|
||||
<ul class="py-2 space-y-1">
|
||||
<f:for each="{destination.regions}" as="region">
|
||||
<li>
|
||||
<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"
|
||||
property="regionUids"
|
||||
data="{action: 'search#filter mobile-search#filter'}"
|
||||
value="{region.uid}"/>
|
||||
<span class="leading-none pl-2">
|
||||
{region.label}
|
||||
</span>
|
||||
</label>
|
||||
</li>
|
||||
</f:for>
|
||||
</ul>
|
||||
</f:if>
|
||||
</li>
|
||||
</f:for>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="py-2"
|
||||
data-controller="collapse"
|
||||
data-collapse-collapsed-value="{f:if(condition: '{filterSettings.priceRanges}', then: 'false', else: 'true')}">
|
||||
<button type="button"
|
||||
data-action="click->collapse#toggle"
|
||||
class="flex items-center justify-between w-full">
|
||||
<span class="uppercase font-bold">
|
||||
Preis
|
||||
</span>
|
||||
<svg class="w-6 h-6 transform"
|
||||
data-collapse-target="icon">
|
||||
<use href="#icon-arrow-right"></use>
|
||||
</svg>
|
||||
</button>
|
||||
<div data-collapse-target="container">
|
||||
<ul class="mb-0 p-0 pt-2 space-y-1">
|
||||
<f:for each="{filterOptions.priceRanges}" as="range">
|
||||
<li>
|
||||
<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"
|
||||
property="conceptUids"
|
||||
data="{action: 'search#filter'}"
|
||||
value="{concept.uid}"/>
|
||||
<span class="inline-block py-1 px-2 bg-concept-{concept.code} text-white">
|
||||
{concept.name}
|
||||
<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"
|
||||
property="priceRanges"
|
||||
data="{action: 'search#filter mobile-search#filter'}"
|
||||
value="{range.uid}"/>
|
||||
<span class="leading-none pl-2">
|
||||
{ep:priceRange(min: range.min, max: range.max)}
|
||||
</span>
|
||||
</label>
|
||||
</li>
|
||||
@@ -123,267 +206,177 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="px-4 divide-y">
|
||||
|
||||
<div class="py-2"
|
||||
data-controller="collapse"
|
||||
data-collapse-collapsed-value="{f:if(condition: '{filterSettings.countryUids} || {filterSettings.regionUids}', then: 'false', else: 'true')}">
|
||||
<button type="button"
|
||||
data-action="click->collapse#toggle"
|
||||
class="flex items-center justify-between w-full">
|
||||
<span class="uppercase font-bold">
|
||||
Reiseziel
|
||||
</span>
|
||||
<svg class="w-6 h-6 transform"
|
||||
data-collapse-target="icon">
|
||||
<use href="#icon-arrow-right"></use>
|
||||
</svg>
|
||||
</button>
|
||||
<div data-collapse-target="container">
|
||||
<ul class="mb-0 p-0 pt-2">
|
||||
<f:for each="{filterOptions.destinations}" as="destination">
|
||||
<li class="relative border-b last:border-0 mb-2">
|
||||
<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"
|
||||
property="countryUids"
|
||||
data="{action: 'search#filter'}"
|
||||
value="{destination.country.uid}"/>
|
||||
<span class="pl-2 leading-none">
|
||||
<strong>{destination.country.label}</strong>
|
||||
</span>
|
||||
<svg class="absolute top-0 right-0 w-8 h-6">
|
||||
<use href="#icon-flag-{destination.country.code -> f:format.case(mode: 'lower')}"/>
|
||||
</svg>
|
||||
</label>
|
||||
<f:if condition="{destination.regions}">
|
||||
<ul class="py-2 space-y-1">
|
||||
<f:for each="{destination.regions}" as="region">
|
||||
<li>
|
||||
<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"
|
||||
property="regionUids"
|
||||
data="{action: 'search#filter'}"
|
||||
value="{region.uid}"/>
|
||||
<span class="leading-none pl-2">
|
||||
{region.label}
|
||||
</span>
|
||||
</label>
|
||||
</li>
|
||||
</f:for>
|
||||
</ul>
|
||||
</f:if>
|
||||
</li>
|
||||
</f:for>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="py-2"
|
||||
data-controller="collapse"
|
||||
data-collapse-collapsed-value="{f:if(condition: '{filterSettings.pax} > 1', then: 'false', else: 'true')}">
|
||||
<button type="button"
|
||||
data-action="click->collapse#toggle"
|
||||
class="flex items-center justify-between w-full">
|
||||
<span class="uppercase font-bold">
|
||||
Personen
|
||||
</span>
|
||||
<svg class="w-6 h-6 transform"
|
||||
data-collapse-target="icon">
|
||||
<use href="#icon-arrow-right"></use>
|
||||
</svg>
|
||||
</button>
|
||||
<div data-collapse-target="container">
|
||||
<f:form.select class="w-full border-0 focus:ring-0 bg-right mt-2 p-0"
|
||||
property="pax"
|
||||
options="{filterOptions.pax}"
|
||||
data="{action: 'search#filter mobile-search#filter'}"/>
|
||||
</div>
|
||||
|
||||
<div class="py-2"
|
||||
data-controller="collapse"
|
||||
data-collapse-collapsed-value="{f:if(condition: '{filterSettings.priceRanges}', then: 'false', else: 'true')}">
|
||||
<button type="button"
|
||||
data-action="click->collapse#toggle"
|
||||
class="flex items-center justify-between w-full">
|
||||
<span class="uppercase font-bold">
|
||||
Preis
|
||||
</span>
|
||||
<svg class="w-6 h-6 transform"
|
||||
data-collapse-target="icon">
|
||||
<use href="#icon-arrow-right"></use>
|
||||
</svg>
|
||||
</button>
|
||||
<div data-collapse-target="container">
|
||||
<ul class="mb-0 p-0 pt-2 space-y-1">
|
||||
<f:for each="{filterOptions.priceRanges}" as="range">
|
||||
<li>
|
||||
<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"
|
||||
property="priceRanges"
|
||||
data="{action: 'search#filter'}"
|
||||
value="{range.uid}"/>
|
||||
<span class="leading-none pl-2">
|
||||
{ep:priceRange(min: range.min, max: range.max)}
|
||||
</span>
|
||||
</label>
|
||||
</li>
|
||||
</f:for>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="py-2"
|
||||
data-controller="collapse"
|
||||
data-collapse-collapsed-value="{f:if(condition: '{filterSettings.pax} > 1', then: 'false', else: 'true')}">
|
||||
<button type="button"
|
||||
data-action="click->collapse#toggle"
|
||||
class="flex items-center justify-between w-full">
|
||||
<span class="uppercase font-bold">
|
||||
Personen
|
||||
</span>
|
||||
<svg class="w-6 h-6 transform"
|
||||
data-collapse-target="icon">
|
||||
<use href="#icon-arrow-right"></use>
|
||||
</svg>
|
||||
</button>
|
||||
<div data-collapse-target="container">
|
||||
<f:form.select class="w-full border-0 focus:ring-0 bg-right mt-2 p-0"
|
||||
property="pax"
|
||||
options="{filterOptions.pax}"
|
||||
data="{action: 'search#filter'}"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<f:variable name="hotelTypes" value="{
|
||||
1: 'Ferienwohnung',
|
||||
2: 'Sportclub',
|
||||
3: 'Appartment',
|
||||
4: 'Gästehaus',
|
||||
5: 'Pension'
|
||||
}"/>
|
||||
<div class="py-2"
|
||||
data-controller="collapse"
|
||||
data-collapse-collapsed-value="{f:if(condition: '{filterSettings.hotelTypes}', then: 'false', else: 'true')}">
|
||||
<button type="button"
|
||||
data-action="click->collapse#toggle"
|
||||
class="flex items-center justify-between w-full">
|
||||
<span class="uppercase font-bold">
|
||||
Unterkunft
|
||||
</span>
|
||||
<svg class="w-6 h-6 transform"
|
||||
data-collapse-target="icon">
|
||||
<use href="#icon-arrow-right"></use>
|
||||
</svg>
|
||||
</button>
|
||||
<div data-collapse-target="container">
|
||||
<ul class="mb-0 p-0 pt-2 space-y-1">
|
||||
<f:for each="{filterOptions.hotelTypes}" as="type">
|
||||
<li>
|
||||
<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"
|
||||
property="hotelTypes"
|
||||
data="{action: 'search#filter'}"
|
||||
value="{type}"/>
|
||||
<span class="leading-none pl-2">
|
||||
{hotelTypes.{type}}
|
||||
</span>
|
||||
</label>
|
||||
</li>
|
||||
</f:for>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="py-2"
|
||||
data-controller="collapse"
|
||||
data-collapse-collapsed-value="{f:if(condition: '{filterSettings.boardTypes}', then: 'false', else: 'true')}">
|
||||
<button type="button"
|
||||
data-action="click->collapse#toggle"
|
||||
class="flex items-center justify-between w-full">
|
||||
<span class="uppercase font-bold">
|
||||
Verpflegung
|
||||
</span>
|
||||
<svg class="w-6 h-6 transform"
|
||||
data-collapse-target="icon">
|
||||
<use href="#icon-arrow-right"></use>
|
||||
</svg>
|
||||
</button>
|
||||
<div data-collapse-target="container">
|
||||
<ul class="mb-0 p-0 pt-2 space-y-1">
|
||||
<f:for each="{filterOptions.boardTypes}" as="type">
|
||||
<f:if condition="{type.label}">
|
||||
<li>
|
||||
<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"
|
||||
property="boardTypes"
|
||||
data="{action: 'search#filter'}"
|
||||
value="{type.uid}"/>
|
||||
<span class="pl-2 leading-none">
|
||||
{type.label}
|
||||
</span>
|
||||
</label>
|
||||
</li>
|
||||
</f:if>
|
||||
</f:for>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<f:variable name="roomTypes" value="{
|
||||
1: 'EZ',
|
||||
2: 'DZ / 2er',
|
||||
3: '3er',
|
||||
4: '4er',
|
||||
5: 'ab 5 Pers.',
|
||||
6: 'mit anderen'
|
||||
}"/>
|
||||
<div class="py-2"
|
||||
data-controller="collapse"
|
||||
data-collapse-collapsed-value="{f:if(condition: '{filterSettings.roomTypes}', then: 'false', else: 'true')}">
|
||||
<button type="button"
|
||||
data-action="click->collapse#toggle"
|
||||
class="flex items-center justify-between w-full">
|
||||
<span class="uppercase font-bold">
|
||||
Zimmerarten/Apart.
|
||||
</span>
|
||||
<svg class="w-6 h-6 transform"
|
||||
data-collapse-target="icon">
|
||||
<use href="#icon-arrow-right"></use>
|
||||
</svg>
|
||||
</button>
|
||||
<div data-collapse-target="container">
|
||||
<ul class="mb-0 p-0 p-0 pt-2 space-y-1">
|
||||
<f:for each="{filterOptions.roomTypes}" as="type">
|
||||
<li>
|
||||
<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"
|
||||
property="roomTypes"
|
||||
data="{action: 'search#filter'}"
|
||||
value="{type}"/>
|
||||
<span class="leading-none pl-2">
|
||||
{roomTypes.{type}}
|
||||
</span>
|
||||
</label>
|
||||
</li>
|
||||
</f:for>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<f:if condition="{filterOptions.busAvailable}">
|
||||
<div class="py-2"
|
||||
data-controller="collapse"
|
||||
data-collapse-collapsed-value="{f:if(condition: filterSettings.bus, then: 'false', else: 'true')}">
|
||||
<button type="button"
|
||||
data-action="click->collapse#toggle"
|
||||
class="flex items-center justify-between w-full">
|
||||
<span class="uppercase font-bold">
|
||||
Anreise
|
||||
</span>
|
||||
<svg class="w-6 h-6 transform"
|
||||
data-collapse-target="icon">
|
||||
<use href="#icon-arrow-right"></use>
|
||||
</svg>
|
||||
</button>
|
||||
<div data-collapse-target="container">
|
||||
<ul class="mb-0 p-0 pt-2 space-y-1">
|
||||
<li>
|
||||
<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"
|
||||
property="bus"
|
||||
data="{action: 'search#filter'}"
|
||||
value="1"/>
|
||||
<span class="leading-none pl-2">
|
||||
Busanreise
|
||||
</span>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</f:if>
|
||||
|
||||
</div>
|
||||
|
||||
</f:form>
|
||||
<f:variable name="hotelTypes" value="{
|
||||
1: 'Ferienwohnung',
|
||||
2: 'Sportclub',
|
||||
3: 'Appartment',
|
||||
4: 'Gästehaus',
|
||||
5: 'Pension'
|
||||
}"/>
|
||||
<div class="py-2"
|
||||
data-controller="collapse"
|
||||
data-collapse-collapsed-value="{f:if(condition: '{filterSettings.hotelTypes}', then: 'false', else: 'true')}">
|
||||
<button type="button"
|
||||
data-action="click->collapse#toggle"
|
||||
class="flex items-center justify-between w-full">
|
||||
<span class="uppercase font-bold">
|
||||
Unterkunft
|
||||
</span>
|
||||
<svg class="w-6 h-6 transform"
|
||||
data-collapse-target="icon">
|
||||
<use href="#icon-arrow-right"></use>
|
||||
</svg>
|
||||
</button>
|
||||
<div data-collapse-target="container">
|
||||
<ul class="mb-0 p-0 pt-2 space-y-1">
|
||||
<f:for each="{filterOptions.hotelTypes}" as="type">
|
||||
<li>
|
||||
<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"
|
||||
property="hotelTypes"
|
||||
data="{action: 'search#filter mobile-search#filter'}"
|
||||
value="{type}"/>
|
||||
<span class="leading-none pl-2">
|
||||
{hotelTypes.{type}}
|
||||
</span>
|
||||
</label>
|
||||
</li>
|
||||
</f:for>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="py-2"
|
||||
data-controller="collapse"
|
||||
data-collapse-collapsed-value="{f:if(condition: '{filterSettings.boardTypes}', then: 'false', else: 'true')}">
|
||||
<button type="button"
|
||||
data-action="click->collapse#toggle"
|
||||
class="flex items-center justify-between w-full">
|
||||
<span class="uppercase font-bold">
|
||||
Verpflegung
|
||||
</span>
|
||||
<svg class="w-6 h-6 transform"
|
||||
data-collapse-target="icon">
|
||||
<use href="#icon-arrow-right"></use>
|
||||
</svg>
|
||||
</button>
|
||||
<div data-collapse-target="container">
|
||||
<ul class="mb-0 p-0 pt-2 space-y-1">
|
||||
<f:for each="{filterOptions.boardTypes}" as="type">
|
||||
<f:if condition="{type.label}">
|
||||
<li>
|
||||
<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"
|
||||
property="boardTypes"
|
||||
data="{action: 'search#filter mobile-search#filter'}"
|
||||
value="{type.uid}"/>
|
||||
<span class="pl-2 leading-none">
|
||||
{type.label}
|
||||
</span>
|
||||
</label>
|
||||
</li>
|
||||
</f:if>
|
||||
</f:for>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<f:variable name="roomTypes" value="{
|
||||
1: 'EZ',
|
||||
2: 'DZ / 2er',
|
||||
3: '3er',
|
||||
4: '4er',
|
||||
5: 'ab 5 Pers.',
|
||||
6: 'mit anderen'
|
||||
}"/>
|
||||
<div class="py-2"
|
||||
data-controller="collapse"
|
||||
data-collapse-collapsed-value="{f:if(condition: '{filterSettings.roomTypes}', then: 'false', else: 'true')}">
|
||||
<button type="button"
|
||||
data-action="click->collapse#toggle"
|
||||
class="flex items-center justify-between w-full">
|
||||
<span class="uppercase font-bold">
|
||||
Zimmerarten/Apart.
|
||||
</span>
|
||||
<svg class="w-6 h-6 transform"
|
||||
data-collapse-target="icon">
|
||||
<use href="#icon-arrow-right"></use>
|
||||
</svg>
|
||||
</button>
|
||||
<div data-collapse-target="container">
|
||||
<ul class="mb-0 p-0 p-0 pt-2 space-y-1">
|
||||
<f:for each="{filterOptions.roomTypes}" as="type">
|
||||
<li>
|
||||
<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"
|
||||
property="roomTypes"
|
||||
data="{action: 'search#filter mobile-search#filter'}"
|
||||
value="{type}"/>
|
||||
<span class="leading-none pl-2">
|
||||
{roomTypes.{type}}
|
||||
</span>
|
||||
</label>
|
||||
</li>
|
||||
</f:for>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<f:if condition="{filterOptions.busAvailable}">
|
||||
<div class="py-2"
|
||||
data-controller="collapse"
|
||||
data-collapse-collapsed-value="{f:if(condition: filterSettings.bus, then: 'false', else: 'true')}">
|
||||
<button type="button"
|
||||
data-action="click->collapse#toggle"
|
||||
class="flex items-center justify-between w-full">
|
||||
<span class="uppercase font-bold">
|
||||
Anreise
|
||||
</span>
|
||||
<svg class="w-6 h-6 transform"
|
||||
data-collapse-target="icon">
|
||||
<use href="#icon-arrow-right"></use>
|
||||
</svg>
|
||||
</button>
|
||||
<div data-collapse-target="container">
|
||||
<ul class="mb-0 p-0 pt-2 space-y-1">
|
||||
<li>
|
||||
<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"
|
||||
property="bus"
|
||||
data="{action: 'search#filter mobile-search#filter'}"
|
||||
value="1"/>
|
||||
<span class="leading-none pl-2">
|
||||
Busanreise
|
||||
</span>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</f:if>
|
||||
|
||||
</div>
|
||||
|
||||
</html>
|
||||
|
||||
@@ -3,15 +3,17 @@
|
||||
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
||||
|
||||
<div class="grid grid-cols-3 gap-8">
|
||||
<div class="col-span-3 lg:col-span-1 relative"
|
||||
data-controller="collapse"
|
||||
data-collapse-until-value="1024">
|
||||
<div class="lg:block bg-white p-4"
|
||||
data-collapse-target="container">
|
||||
<div class="col-span-3 lg:col-span-1 relative">
|
||||
<div class="hidden lg:block bg-white p-4">
|
||||
<h3 class="headline headline--underlined mb-4">
|
||||
Filter
|
||||
</h3>
|
||||
<f:render partial="Search/FilterPanel" arguments="{_all}"/>
|
||||
<f:form object="{filterSettings}"
|
||||
name="filterSettings"
|
||||
pluginName="Ajax"
|
||||
data="{'search-target': 'form'}">
|
||||
<f:render partial="Search/FilterPanel" arguments="{_all}"/>
|
||||
</f:form>
|
||||
<div class="mt-4">
|
||||
<button type="button"
|
||||
class="button button--secondary w-full"
|
||||
@@ -20,6 +22,38 @@
|
||||
</button>
|
||||
</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 class="col-span-3 lg:col-span-2 relative">
|
||||
<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>
|
||||
+23
-1
@@ -5,6 +5,28 @@
|
||||
|
||||
<f:layout name="Default"/>
|
||||
|
||||
<f:render partial="Search/FilterPanel" arguments="{_all}"/>
|
||||
<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: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>
|
||||
|
||||
@@ -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: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"
|
||||
data-controller="search"
|
||||
data-search-uri-value="{ep:uri.ajax(controller: 'AjaxSearch', action: 'searchresult', pageUid: settings.defaultAjaxUid, format: 'html')}"
|
||||
|
||||
Reference in New Issue
Block a user