Further improve mobile search

This commit is contained in:
Björn Fromme
2021-10-26 11:26:09 +02:00
parent 2b2dbae409
commit 4923944175
10 changed files with 214 additions and 46 deletions
@@ -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));
}
}
@@ -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)}"
@@ -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>