Further improve mobile search
This commit is contained in:
@@ -28,6 +28,7 @@ namespace EP\EpProducts\Controller;
|
|||||||
***************************************************************/
|
***************************************************************/
|
||||||
|
|
||||||
use EP\EpProducts\Service\FilterService;
|
use EP\EpProducts\Service\FilterService;
|
||||||
|
use EP\EpProducts\Service\SearchResultService;
|
||||||
use EP\EpProducts\Traits\RequestArgumentTypeConversionTrait;
|
use EP\EpProducts\Traits\RequestArgumentTypeConversionTrait;
|
||||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
|
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
|
||||||
@@ -42,12 +43,18 @@ class AjaxFilterPanelController extends ActionController
|
|||||||
*/
|
*/
|
||||||
protected $filterService;
|
protected $filterService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var SearchResultService
|
||||||
|
*/
|
||||||
|
private $searchResultService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param FilterService $filterService
|
* @param FilterService $filterService
|
||||||
*/
|
*/
|
||||||
public function __construct(FilterService $filterService)
|
public function __construct(FilterService $filterService, SearchResultService $searchResultService)
|
||||||
{
|
{
|
||||||
$this->filterService = $filterService;
|
$this->filterService = $filterService;
|
||||||
|
$this->searchResultService = $searchResultService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function initializeAction()
|
public function initializeAction()
|
||||||
@@ -59,20 +66,15 @@ class AjaxFilterPanelController extends ActionController
|
|||||||
/**
|
/**
|
||||||
* @param array $filterSettings
|
* @param array $filterSettings
|
||||||
*/
|
*/
|
||||||
public function optionsAction(array $filterSettings)
|
public function indexAction(array $filterSettings)
|
||||||
{
|
{
|
||||||
$forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true);
|
|
||||||
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids']);
|
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids']);
|
||||||
$excludedRegionUids = GeneralUtility::trimExplode(',', $this->settings['excludedRegionUids']);
|
|
||||||
|
|
||||||
$filterOptions = $this
|
$searchResult = $this
|
||||||
->filterService
|
->searchResultService
|
||||||
->getFilterOptions(
|
->getResult($filterSettings, $excludedConceptUids);
|
||||||
$filterSettings,
|
|
||||||
$excludedConceptUids,
|
$filterOptions = $this->filterService->collectFilterOptionsFromResult($searchResult);
|
||||||
$excludedRegionUids,
|
|
||||||
$forcedConceptUids
|
|
||||||
);
|
|
||||||
|
|
||||||
$resultsUri = $this->uriBuilder
|
$resultsUri = $this->uriBuilder
|
||||||
->reset()
|
->reset()
|
||||||
|
|||||||
@@ -74,7 +74,6 @@ class AjaxSearchController extends ActionController
|
|||||||
$organic = true;
|
$organic = true;
|
||||||
$forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true);
|
$forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true);
|
||||||
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids']);
|
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids']);
|
||||||
$excludedRegionUids = GeneralUtility::trimExplode(',', $this->settings['excludedRegionUids']);
|
|
||||||
|
|
||||||
if (isset($filterSettings['dateFrom']) || isset($filterSettings['dateTo'])) {
|
if (isset($filterSettings['dateFrom']) || isset($filterSettings['dateTo'])) {
|
||||||
$dateSelected = true;
|
$dateSelected = true;
|
||||||
|
|||||||
@@ -59,21 +59,6 @@ class SearchController extends ActionController
|
|||||||
$this->searchResultService = $searchResultService;
|
$this->searchResultService = $searchResultService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function searchbarAction()
|
|
||||||
{
|
|
||||||
$fixed = (bool)$this->settings['fixed'];
|
|
||||||
$searchParams = $this->searchResultService->getNormalizedSearchParams();
|
|
||||||
$filterSettings = $this->filterService->getNormalizedFilterSettings();
|
|
||||||
$filterOptions = $this->filterService->getFilterOptions($filterSettings);
|
|
||||||
|
|
||||||
$this->view->assignMultiple([
|
|
||||||
'filterSettings' => $filterSettings,
|
|
||||||
'filterOptions' => $filterOptions,
|
|
||||||
'searchParams' => $searchParams,
|
|
||||||
'fixed' => $fixed,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function initializeProcessSearchAction()
|
public function initializeProcessSearchAction()
|
||||||
{
|
{
|
||||||
$this->processSearchParamsArgument();
|
$this->processSearchParamsArgument();
|
||||||
|
|||||||
@@ -149,8 +149,7 @@ tx_epproducts_ajax_json {
|
|||||||
2 = searchresult
|
2 = searchresult
|
||||||
}
|
}
|
||||||
AjaxFilterPanel {
|
AjaxFilterPanel {
|
||||||
1 = options
|
1 = index
|
||||||
2 = search
|
|
||||||
}
|
}
|
||||||
AjaxDate {
|
AjaxDate {
|
||||||
1 = dates
|
1 = dates
|
||||||
|
|||||||
@@ -51,14 +51,6 @@ $iconRegistry->registerIcon(
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
|
|
||||||
'EP.ep_products',
|
|
||||||
'searchbox',
|
|
||||||
[
|
|
||||||
'Search' => 'searchbox',
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
|
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
|
||||||
'EP.ep_products',
|
'EP.ep_products',
|
||||||
'searchresult',
|
'searchresult',
|
||||||
@@ -295,7 +287,7 @@ $iconRegistry->registerIcon(
|
|||||||
'ajax',
|
'ajax',
|
||||||
[
|
[
|
||||||
'AjaxSearch' => 'searchresult',
|
'AjaxSearch' => 'searchresult',
|
||||||
'AjaxFilterPanel' => 'options,search',
|
'AjaxFilterPanel' => 'index',
|
||||||
'AjaxDate' => 'dates',
|
'AjaxDate' => 'dates',
|
||||||
'AjaxContingent' => 'list,rooms',
|
'AjaxContingent' => 'list,rooms',
|
||||||
'AjaxTable' => 'datestable,pricetable,pricetableHtml,eventPricetable,daytripRooms',
|
'AjaxTable' => 'datestable,pricetable,pricetableHtml,eventPricetable,daytripRooms',
|
||||||
@@ -305,7 +297,7 @@ $iconRegistry->registerIcon(
|
|||||||
],
|
],
|
||||||
[
|
[
|
||||||
'AjaxSearch' => 'searchresult',
|
'AjaxSearch' => 'searchresult',
|
||||||
'AjaxFilterPanel' => 'options,search',
|
'AjaxFilterPanel' => 'index',
|
||||||
'AjaxDate' => 'dates',
|
'AjaxDate' => 'dates',
|
||||||
'AjaxContingent' => 'list,rooms',
|
'AjaxContingent' => 'list,rooms',
|
||||||
'AjaxTable' => 'datestable,pricetable,pricetableHtml,eventPricetable,daytripRooms',
|
'AjaxTable' => 'datestable,pricetable,pricetableHtml,eventPricetable,daytripRooms',
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace EP\EpTheme\ViewHelpers;
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* Copyright notice
|
||||||
|
*
|
||||||
|
* (c) 2018 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 TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||||
|
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||||
|
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||||
|
|
||||||
|
class StimulusActionViewHelper extends AbstractViewHelper
|
||||||
|
{
|
||||||
|
use CompileWithRenderStatic;
|
||||||
|
|
||||||
|
protected $escapeOutput = false;
|
||||||
|
|
||||||
|
public function initializeArguments()
|
||||||
|
{
|
||||||
|
parent::initializeArguments();
|
||||||
|
|
||||||
|
$this->registerArgument('controller', 'string', 'Controller name', true);
|
||||||
|
$this->registerArgument('action', 'string', 'Action name', true);
|
||||||
|
$this->registerArgument('event', 'string', 'Event name', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $arguments
|
||||||
|
* @param \Closure $renderChildrenClosure
|
||||||
|
* @param RenderingContextInterface $renderingContext
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function renderStatic(
|
||||||
|
array $arguments,
|
||||||
|
\Closure $renderChildrenClosure,
|
||||||
|
RenderingContextInterface $renderingContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
$controllerName = static::normalizeControllerName($arguments['controller']);
|
||||||
|
$action = $arguments['action'];
|
||||||
|
$event = $arguments['event'];
|
||||||
|
|
||||||
|
if (!$event) {
|
||||||
|
return sprintf('data-action="%s#%s"', $controllerName, $action);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprintf('data-action="%s->%s#%s"', $event, $controllerName, $action);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method taken from symfony/webpack-encore-bundle
|
||||||
|
*
|
||||||
|
* @param string $str
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private static function normalizeControllerName(string $str): string
|
||||||
|
{
|
||||||
|
return preg_replace('/^@/', '', str_replace('_', '-', str_replace('/', '--', $str)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace EP\EpTheme\ViewHelpers;
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* Copyright notice
|
||||||
|
*
|
||||||
|
* (c) 2018 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 TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||||
|
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||||
|
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||||
|
|
||||||
|
class StimulusControllerViewHelper extends AbstractViewHelper
|
||||||
|
{
|
||||||
|
use CompileWithRenderStatic;
|
||||||
|
|
||||||
|
protected $escapeOutput = false;
|
||||||
|
|
||||||
|
public function initializeArguments()
|
||||||
|
{
|
||||||
|
parent::initializeArguments();
|
||||||
|
|
||||||
|
$this->registerArgument('controller', 'string', 'Controller name', true);
|
||||||
|
$this->registerArgument('values', 'array', 'Controller values', false, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $arguments
|
||||||
|
* @param \Closure $renderChildrenClosure
|
||||||
|
* @param RenderingContextInterface $renderingContext
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function renderStatic(
|
||||||
|
array $arguments,
|
||||||
|
\Closure $renderChildrenClosure,
|
||||||
|
RenderingContextInterface $renderingContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
$controllerName = static::normalizeControllerName($arguments['controller']);
|
||||||
|
$attributes = [
|
||||||
|
sprintf('data-controller="%s"', $controllerName),
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($arguments['values'] as $key => $value) {
|
||||||
|
if (!is_scalar($value)) {
|
||||||
|
$value = htmlspecialchars(json_encode($value), ENT_QUOTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (\is_bool($value)) {
|
||||||
|
$value = $value ? 'true' : 'false';
|
||||||
|
}
|
||||||
|
|
||||||
|
$key = static::normalizeKeyName($key);
|
||||||
|
|
||||||
|
$attributes[] = sprintf('data-%s-%s-value="%s"', $controllerName, $key, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode(' ', $attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method taken from symfony/webpack-encore-bundle
|
||||||
|
*
|
||||||
|
* @param string $str
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private static function normalizeControllerName(string $str): string
|
||||||
|
{
|
||||||
|
return preg_replace('/^@/', '', str_replace('_', '-', str_replace('/', '--', $str)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method taken from symfony/webpack-encore-bundle
|
||||||
|
*
|
||||||
|
* @param string $str
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private static function normalizeKeyName(string $str): string
|
||||||
|
{
|
||||||
|
// Adapted from ByteString::camel
|
||||||
|
$str = ucfirst(str_replace(' ', '', ucwords(preg_replace('/[^a-zA-Z0-9\x7f-\xff]++/', ' ', $str))));
|
||||||
|
|
||||||
|
// Adapted from ByteString::snake
|
||||||
|
return strtolower(preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'], '\1-\2', $str));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+3
-3
@@ -12,8 +12,8 @@ export default class extends Controller {
|
|||||||
]
|
]
|
||||||
|
|
||||||
static values = {
|
static values = {
|
||||||
optionsUri: String,
|
uri: String,
|
||||||
initialOptionsUri: String,
|
initUri: String,
|
||||||
loading: Boolean,
|
loading: Boolean,
|
||||||
loaded: Boolean,
|
loaded: Boolean,
|
||||||
show: Boolean,
|
show: Boolean,
|
||||||
@@ -48,7 +48,7 @@ export default class extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
load(options) {
|
load(options) {
|
||||||
let uri = this.loadedValue ? this.optionsUriValue : this.initialOptionsUriValue
|
let uri = this.loadedValue ? this.uriValue : this.initUriValue
|
||||||
this.loadingValue = true
|
this.loadingValue = true
|
||||||
fetch(uri, options)
|
fetch(uri, options)
|
||||||
.then(this.checkStatus)
|
.then(this.checkStatus)
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
<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"
|
<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-controller="mobile-search"
|
||||||
data-mobile-search-options-uri-value="{ep:uri.ajax(controller: 'AjaxFilterPanel', action: 'options', pageUid: settings.defaultAjaxUid, format: 'html')}"
|
data-mobile-search-uri-value="{ep:uri.ajax(controller: 'AjaxFilterPanel', action: 'index', 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-init-uri-value="{ep:uri.ajax(controller: 'AjaxFilterPanel', action: 'index', pageUid: settings.defaultAjaxUid, arguments: '{filterSettings: filterSettings}', format: 'html')}"
|
||||||
data-action="overlay-toggle:toggle@window->mobile-search#open datepicker:range-select->mobile-search#selectDateRange">
|
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">
|
<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)}"
|
<a href="{f:uri.typolink(parameter: settings.defaultHomeUid)}"
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@
|
|||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<a href="{filterOptions.resultsUri}"
|
<a href="{filterOptions.resultsUri}"
|
||||||
class="button button--primary w-full">
|
class="button button--primary w-full">
|
||||||
Ergebnis anzeigen
|
{filterOptions.resultCount} Treffer anzeigen
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</f:if>
|
</f:if>
|
||||||
Reference in New Issue
Block a user