Migrate mobile search
This commit is contained in:
@@ -75,6 +75,7 @@ class AjaxFilterPanelController extends ActionController
|
||||
$this->view->assignMultiple([
|
||||
'filterSettings' => $filterSettings,
|
||||
'filterOptions' => $filterOptions,
|
||||
'stimulusController' => 'mobile-search',
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -99,12 +99,7 @@ class AjaxSearchController extends ActionController
|
||||
$organic = false;
|
||||
}
|
||||
|
||||
$filterOptions = $this->filterService->getFilterOptions(
|
||||
$filterSettings,
|
||||
$excludedConceptUids,
|
||||
$excludedRegionUids,
|
||||
$forcedConceptUids
|
||||
);
|
||||
$filterOptions = $this->filterService->collectFilterOptionsFromResult($searchResult);
|
||||
|
||||
$referringPageUri = $this
|
||||
->uriBuilder
|
||||
@@ -124,6 +119,7 @@ class AjaxSearchController extends ActionController
|
||||
'filterOptions' => $filterOptions,
|
||||
'searchResult' => $searchResult->getData(),
|
||||
'referringPageUri' => $referringPageUri,
|
||||
'stimulusController' => 'search',
|
||||
'meta' => [
|
||||
'organic' => $organic,
|
||||
'total' => $searchResult->getTotal(),
|
||||
|
||||
@@ -140,12 +140,7 @@ class SearchController extends ActionController
|
||||
$organic = false;
|
||||
}
|
||||
|
||||
$filterOptions = $this->filterService->getFilterOptions(
|
||||
$filterSettings,
|
||||
$excludedConceptUids,
|
||||
$excludedRegionUids,
|
||||
$forcedConceptUids
|
||||
);
|
||||
$filterOptions = $this->filterService->collectFilterOptionsFromResult($searchResult);
|
||||
|
||||
$referringPageUri = $this
|
||||
->uriBuilder
|
||||
@@ -165,6 +160,7 @@ class SearchController extends ActionController
|
||||
'filterOptions' => $filterOptions,
|
||||
'searchResult' => $searchResult->getData(),
|
||||
'referringPageUri' => $referringPageUri,
|
||||
'stimulusController' => 'search',
|
||||
'meta' => [
|
||||
'organic' => $organic,
|
||||
'total' => $searchResult->getTotal(),
|
||||
|
||||
@@ -96,9 +96,17 @@ class FilterOptions implements \JsonSerializable
|
||||
*/
|
||||
protected $busAvailable;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $resultCount;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->pax = range(1, 20);
|
||||
$this->pax = [
|
||||
0 => 'beliebig',
|
||||
...array_combine(range(1, 20), range(1, 20))
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -277,6 +285,22 @@ class FilterOptions implements \JsonSerializable
|
||||
$this->busAvailable = $busAvailable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getResultCount(): ?int
|
||||
{
|
||||
return $this->resultCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $resultCount
|
||||
*/
|
||||
public function setResultCount(int $resultCount)
|
||||
{
|
||||
$this->resultCount = $resultCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
@@ -294,6 +318,7 @@ class FilterOptions implements \JsonSerializable
|
||||
'dateFrom' => ($this->getDateFrom() !== null) ? $this->getDateFrom()->format('Y-m-d') : null,
|
||||
'dateTo' => ($this->getDateTo() !== null) ? $this->getDateTo()->format('Y-m-d') : null,
|
||||
'busAvailable' => $this->getBusAvailable(),
|
||||
'resultCount' => $this->getResultCount(),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -89,17 +89,22 @@ class ProductRepository extends AbstractRepository
|
||||
$query = $qb
|
||||
->select(
|
||||
'date.concept as conceptUid', 'date.concept_name as conceptName', 'date.concept_code as conceptCode',
|
||||
'date.concept_sorting as conceptSorting',
|
||||
'date.product as productUid', 'date.product_name as productName',
|
||||
'date.product_detail_page as productDetailPage', 'date.product_feature as productFeature',
|
||||
'date.daytrip as daytrip', 'date.country as countryUid','date.country_name as countryName',
|
||||
'date.country_code as countryCode', 'date.region as regionUid', 'date.region_name as regionName',
|
||||
'date.region_feature as regionFeature', 'date.date_start as dateStart', 'date.date_end as dateEnd',
|
||||
'date.hotel as hotelUid', 'date.hotel_name as hotelName', 'date.hotel_category as hotelCategory',
|
||||
'date.hotel_type as hotelType',
|
||||
'date.earlybird as earlybird', 'date.new as new', 'date.low_contingent as lowContingent',
|
||||
'date.board as board', 'date.product_fact as productFact', 'date.hotel_fact as hotelFact',
|
||||
'date.region_fact as regionFact', 'date.services_included as servicesIncluded',
|
||||
'date.board as board', 'date.board_bus_pro_id as boardUid',
|
||||
'date.product_fact as productFact', 'date.hotel_fact as hotelFact', 'date.region_fact as regionFact',
|
||||
'date.services_included as servicesIncluded',
|
||||
'date.bus_available as busAvailable',
|
||||
'date.min_price as minPrice', 'date.nights as nights', 'date.available as available',
|
||||
'date.pseudo_price as pseudoPrice', 'date.hide_booking_button as hideBookingButton'
|
||||
'date.pseudo_price as pseudoPrice', 'date.hide_booking_button as hideBookingButton',
|
||||
'room.type as roomType'
|
||||
)
|
||||
->from('tx_epproducts_domain_model_date', 'date')
|
||||
->leftJoin('date', 'tx_epproducts_domain_model_room', 'room', 'room.date = date.uid')
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace EP\EpProducts\Service;
|
||||
***************************************************************/
|
||||
|
||||
use EP\EpProducts\Domain\Model\FilterOptions;
|
||||
use EP\EpProducts\Domain\Model\SearchResult;
|
||||
use EP\EpProducts\Domain\Repository\DateRepository;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use TYPO3\CMS\Core\SingletonInterface;
|
||||
@@ -116,10 +117,10 @@ class FilterService implements SingletonInterface
|
||||
$filterSettings['priceRanges'] = [ $searchParams['priceRange'] ];
|
||||
}
|
||||
if ($searchParams['pax']) {
|
||||
$filterSettings['pax'] = $searchParams['pax'];
|
||||
$filterSettings['pax'] = (int)$searchParams['pax'];
|
||||
}
|
||||
if ($searchParams['nights']) {
|
||||
$filterSettings['nights'] = $searchParams['nights'];
|
||||
$filterSettings['nights'] = (int)$searchParams['nights'];
|
||||
}
|
||||
|
||||
return $filterSettings;
|
||||
@@ -157,7 +158,7 @@ class FilterService implements SingletonInterface
|
||||
$filterSettings['dateTo'] = $staticSearchParams['date_to'];
|
||||
}
|
||||
if (!empty($staticSearchParams['pax']) && (int)$staticSearchParams['pax'] > 0) {
|
||||
$filterSettings['pax'] = $staticSearchParams['pax'];
|
||||
$filterSettings['pax'] = (int)$staticSearchParams['pax'];
|
||||
}
|
||||
|
||||
return $filterSettings;
|
||||
@@ -183,6 +184,124 @@ class FilterService implements SingletonInterface
|
||||
return $this->preprocessFilterOptions($filterOptionsData);
|
||||
}
|
||||
|
||||
public function collectFilterOptionsFromResult(SearchResult $searchResult): FilterOptions
|
||||
{
|
||||
$priceRanges = [];
|
||||
$busAvailable = false;
|
||||
$nights = [];
|
||||
$concepts = [];
|
||||
$destinations = [];
|
||||
$hotelTypes = [];
|
||||
$roomTypes = [];
|
||||
$boardTypes = [];
|
||||
$dateMin = $dateMax = null;
|
||||
|
||||
foreach ($searchResult->getData() as $row) {
|
||||
$concept = $row['concept'];
|
||||
if (!array_key_exists($concept['uid'], $concepts)) {
|
||||
$concepts[$concept['sorting']] = [
|
||||
'uid' => $concept['uid'],
|
||||
'name' => $concept['name'],
|
||||
'code' => $concept['code'],
|
||||
];
|
||||
}
|
||||
foreach ($row['items'] as $item) {
|
||||
if (null === $dateMin || $item['minDateStart'] < $dateMin) {
|
||||
$dateMin = $item['minDateStart'];
|
||||
}
|
||||
if (null === $dateMax || $item['maxDateEnd'] > $dateMax) {
|
||||
$dateMax = $row['itemMaxDateEnd'];
|
||||
}
|
||||
if ((bool) $row['busAvailable'] === true) {
|
||||
$busAvailable = true;
|
||||
}
|
||||
foreach ($item['nights'] as $nightsOption) {
|
||||
$duration = (int) $nightsOption <= 4 ? self::DURATION_SHORT : self::DURATION_LONG;
|
||||
if (!\in_array($duration, $nights, false)) {
|
||||
$nights[] = $duration;
|
||||
}
|
||||
}
|
||||
if (!array_key_exists($item['country']['uid'], $destinations)) {
|
||||
$destinations[$item['country']['uid']] = [
|
||||
'country' => [
|
||||
'uid' => $item['country']['uid'],
|
||||
'label' => $item['country']['name'],
|
||||
'code' => $item['country']['code'],
|
||||
],
|
||||
'regions' => [],
|
||||
];
|
||||
}
|
||||
if (!array_key_exists($item['region']['uid'], $destinations[$item['country']['uid']]['regions'])) {
|
||||
$destinations[$item['country']['uid']]['regions'][$item['region']['uid']] = [
|
||||
'uid' => $item['region']['uid'],
|
||||
'label' => $item['region']['name'],
|
||||
];
|
||||
}
|
||||
if (!\in_array($item['hotel']['type'], $hotelTypes, false)) {
|
||||
$hotelTypes[] = $item['hotel']['type'];
|
||||
}
|
||||
foreach ($item['rooms'] as $roomType) {
|
||||
if (!\in_array($roomType, $roomTypes, false)) {
|
||||
$roomTypes[] = $roomType;
|
||||
}
|
||||
}
|
||||
$boardType = [
|
||||
'uid' => $item['boardUid'],
|
||||
'label' => $item['board'],
|
||||
];
|
||||
if (!\in_array($boardType, $boardTypes, false)) {
|
||||
$boardTypes[] = $boardType;
|
||||
}
|
||||
foreach (FilterOptions::$priceRangeOptions as $index => $priceRange) {
|
||||
if (array_key_exists($index, $priceRanges)) {
|
||||
continue;
|
||||
}
|
||||
[$min, $max] = $priceRange;
|
||||
if ($item['minPrice'] >= $min && $item['minPrice'] < $max) {
|
||||
$range = FilterOptions::$priceRangeOptions[$index];
|
||||
$priceRanges[$index] = [
|
||||
'uid' => $index,
|
||||
'min' => $range[0],
|
||||
'max' => $range[1],
|
||||
'formatted' => $this->formatPriceRange($range[0], $range[1]),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($destinations as $key => $value) {
|
||||
usort($value['regions'], function ($a, $b) {
|
||||
return strcmp($a['label'], $b['label']);
|
||||
});
|
||||
$destinations[$key] = $value;
|
||||
}
|
||||
sort($destinations);
|
||||
sort($nights);
|
||||
sort($roomTypes);
|
||||
ksort($priceRanges);
|
||||
|
||||
usort($boardTypes, function ($a, $b) {
|
||||
return strcmp($a['label'], $b['label']);
|
||||
});
|
||||
|
||||
$filterOptions = new FilterOptions();
|
||||
$filterOptions->setPriceRanges($priceRanges);
|
||||
$filterOptions->setDateFrom($dateMin);
|
||||
$filterOptions->setDateTo($dateMax);
|
||||
$filterOptions->setConcepts($concepts);
|
||||
$filterOptions->setDestinations($destinations);
|
||||
$filterOptions->setHotelTypes($hotelTypes);
|
||||
$filterOptions->setRoomTypes($roomTypes);
|
||||
$filterOptions->setBoardTypes($boardTypes);
|
||||
$filterOptions->setBusAvailable($busAvailable);
|
||||
$filterOptions->setNights($nights);
|
||||
|
||||
$filterOptions->setResultCount($searchResult->getTotal());
|
||||
|
||||
return $filterOptions;
|
||||
}
|
||||
|
||||
public function preprocessFilterOptions(array $filterOptionsData): FilterOptions
|
||||
{
|
||||
$priceRanges = [];
|
||||
@@ -256,15 +375,14 @@ class FilterService implements SingletonInterface
|
||||
// Board types
|
||||
$boardType = [
|
||||
'uid' => $row['boardUid'],
|
||||
'label' => $row['boardType'],
|
||||
'label' => $row['board'],
|
||||
];
|
||||
if (!\in_array($boardType, $boardTypes, false)) {
|
||||
$boardTypes[] = $boardType;
|
||||
}
|
||||
|
||||
// Price range
|
||||
foreach (FilterOptions::$priceRangeOptions as $index => $priceRange)
|
||||
{
|
||||
foreach (FilterOptions::$priceRangeOptions as $index => $priceRange) {
|
||||
if (array_key_exists($index, $priceRanges)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -108,6 +108,7 @@ class SearchResultService implements SingletonInterface
|
||||
'uid' => $row['conceptUid'],
|
||||
'name' => $row['conceptName'],
|
||||
'code' => $row['conceptCode'],
|
||||
'sorting' => $row['conceptSorting'],
|
||||
],
|
||||
'items' => [],
|
||||
];
|
||||
@@ -130,6 +131,7 @@ class SearchResultService implements SingletonInterface
|
||||
'earlybird' => $row['earlybird'],
|
||||
'daytrip' => $row['daytrip'],
|
||||
'hideBookingButton' => $row['hideBookingButton'],
|
||||
'busAvailable' => $row['busAvailable'],
|
||||
'lowContingent' => $row['lowContingent'],
|
||||
'servicesIncluded' => unserialize($row['servicesIncluded'], ['allowed_classes' => false]),
|
||||
'hotel' => [
|
||||
@@ -139,13 +141,16 @@ class SearchResultService implements SingletonInterface
|
||||
'images' => $this->hotelImageService->getImages($row['hotelUid']),
|
||||
'fact' => $row['hotelFact'],
|
||||
'category' => $hotelCategory,
|
||||
'type' => $row['hotelType'],
|
||||
],
|
||||
'country' => [
|
||||
'uid' => $row['countryUid'],
|
||||
'code' => $row['countryCode'],
|
||||
'name' => $row['countryName'],
|
||||
'flag' => $this->flagIconService->getImage($row['countryCode']),
|
||||
],
|
||||
'region' => [
|
||||
'uid' => $row['regionUid'],
|
||||
'name' => $row['regionName'],
|
||||
'fact' => $row['regionFact'],
|
||||
'feature' => $row['regionFeature'],
|
||||
@@ -159,14 +164,20 @@ class SearchResultService implements SingletonInterface
|
||||
'fact' => $row['productFact'],
|
||||
],
|
||||
'board' => $row['board'],
|
||||
'boardUid' => $row['boardUid'],
|
||||
'dates' => [],
|
||||
'nights' => [],
|
||||
'rooms' => [],
|
||||
];
|
||||
$total++;
|
||||
}
|
||||
|
||||
$item =& $items[$key];
|
||||
|
||||
if (!\in_array($row['roomType'], $item['rooms'], false)) {
|
||||
$item['rooms'][] = $row['roomType'];
|
||||
}
|
||||
|
||||
if (!\in_array($row['nights'], $item['nights'], false)) {
|
||||
$item['nights'][] = $row['nights'];
|
||||
}
|
||||
|
||||
+9
-3
@@ -13,8 +13,10 @@ export default class extends Controller {
|
||||
|
||||
static values = {
|
||||
optionsUri: String,
|
||||
initialOptionsUri: String,
|
||||
searchUri: String,
|
||||
loading: Boolean,
|
||||
loaded: Boolean,
|
||||
show: Boolean,
|
||||
}
|
||||
|
||||
@@ -25,13 +27,14 @@ export default class extends Controller {
|
||||
open(e) {
|
||||
if (e.detail === 'mobile-search') {
|
||||
this.showValue = true
|
||||
this.load()
|
||||
if (false === this.loadedValue) {
|
||||
this.load()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close() {
|
||||
this.showValue = false
|
||||
this.containerTarget.innerHTML = ''
|
||||
}
|
||||
|
||||
filter() {
|
||||
@@ -46,12 +49,14 @@ export default class extends Controller {
|
||||
}
|
||||
|
||||
load(options) {
|
||||
let uri = this.loadedValue ? this.optionsUriValue : this.initialOptionsUriValue
|
||||
this.loadingValue = true
|
||||
fetch(this.optionsUriValue, options)
|
||||
fetch(uri, options)
|
||||
.then(this.checkStatus)
|
||||
.then(this.parseHTML)
|
||||
.then(html => {
|
||||
this.containerTarget.innerHTML = html
|
||||
this.loadedValue = true
|
||||
})
|
||||
.finally(() => {
|
||||
this.loadingValue = false
|
||||
@@ -73,6 +78,7 @@ export default class extends Controller {
|
||||
}
|
||||
|
||||
selectDateRange(e) {
|
||||
e.stopPropagation()
|
||||
this.dateFromTarget.value = e.detail.from
|
||||
this.dateToTarget.value = e.detail.to
|
||||
this.filter()
|
||||
|
||||
@@ -34,8 +34,7 @@
|
||||
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"/>
|
||||
value="{ep:dateRange(dateFrom: filterSettings.dateFrom, dateTo: filterSettings.dateTo, includeLabel: 0)}"/>
|
||||
<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>
|
||||
@@ -106,7 +105,7 @@
|
||||
<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'}"
|
||||
data="{action: '{stimulusController}#filter'}"
|
||||
value="{concept.uid}"/>
|
||||
<span class="inline-block py-1 px-2 bg-concept-{concept.code} text-white">
|
||||
{concept.name}
|
||||
@@ -141,7 +140,7 @@
|
||||
<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'}"
|
||||
data="{action: '{stimulusController}#filter'}"
|
||||
value="{destination.country.uid}"/>
|
||||
<span class="pl-2 leading-none">
|
||||
<strong>{destination.country.label}</strong>
|
||||
@@ -157,7 +156,7 @@
|
||||
<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'}"
|
||||
data="{action: '{stimulusController}#filter'}"
|
||||
value="{region.uid}"/>
|
||||
<span class="leading-none pl-2">
|
||||
{region.label}
|
||||
@@ -194,7 +193,7 @@
|
||||
<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'}"
|
||||
data="{action: '{stimulusController}#filter'}"
|
||||
value="{range.uid}"/>
|
||||
<span class="leading-none pl-2">
|
||||
{ep:priceRange(min: range.min, max: range.max)}
|
||||
@@ -224,7 +223,7 @@
|
||||
<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'}"/>
|
||||
data="{action: '{stimulusController}#filter'}"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -256,7 +255,7 @@
|
||||
<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'}"
|
||||
data="{action: '{stimulusController}#filter'}"
|
||||
value="{type}"/>
|
||||
<span class="leading-none pl-2">
|
||||
{hotelTypes.{type}}
|
||||
@@ -290,7 +289,7 @@
|
||||
<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'}"
|
||||
data="{action: '{stimulusController}#filter'}"
|
||||
value="{type.uid}"/>
|
||||
<span class="pl-2 leading-none">
|
||||
{type.label}
|
||||
@@ -332,7 +331,7 @@
|
||||
<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'}"
|
||||
data="{action: '{stimulusController}#filter'}"
|
||||
value="{type}"/>
|
||||
<span class="leading-none pl-2">
|
||||
{roomTypes.{type}}
|
||||
@@ -365,7 +364,7 @@
|
||||
<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'}"
|
||||
data="{action: '{stimulusController}#filter'}"
|
||||
value="1"/>
|
||||
<span class="leading-none pl-2">
|
||||
Busanreise
|
||||
|
||||
@@ -22,42 +22,11 @@
|
||||
</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}"/>
|
||||
</div>
|
||||
<f:render partial="Search/MobileSearch" arguments="{_all}"/>
|
||||
</div>
|
||||
|
||||
</html>
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en"
|
||||
<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">
|
||||
|
||||
<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-initial-options-uri-value="{ep:uri.ajax(controller: 'AjaxFilterPanel', action: 'options', pageUid: settings.defaultAjaxUid, arguments: '{filterSettings: filterSettings}', 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">
|
||||
data-action="overlay-toggle:toggle@window->mobile-search#open datepicker:range-select->mobile-search#selectDateRange">
|
||||
<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"
|
||||
|
||||
Reference in New Issue
Block a user