Commit 4193005a authored by Jonas Götze's avatar Jonas Götze
Browse files

[WIP][FEATURE] suggest for locations

parent 30fb64bd
<?php
namespace T3o\T3orgLayout\Middleware;
/*
* This file is part of a TYPO3 extension.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Psr\Http\Server\MiddlewareInterface;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Http\JsonResponse;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class Events implements MiddlewareInterface
{
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$response = $handler->handle($request);
if (!isset($request->getQueryParams()['eventLocationSearch'])) {
return $response;
}
$searchPhrase = $request->getQueryParams()['eventLocationSearch'];
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('tx_sfeventmgt_domain_model_location')
->createQueryBuilder();
$locations = $queryBuilder->select(
'uid',
'title',
'address',
'zip',
'city',
'country'
)
->from('tx_sfeventmgt_domain_model_location')
->where(
$queryBuilder->expr()->like(
'title',
$queryBuilder->createNamedParameter('%' . $searchPhrase . '%')
),
)
->setMaxResults(10)
->execute()
->fetchAll();
return new JsonResponse($locations);
}
}
......@@ -7,6 +7,15 @@ return [
'before' => [
'typo3/cms-frontend/timetracker'
]
],
'T3o/T3orgLayout/ajaxsearch' => [
'target' => \T3o\T3orgLayout\Middleware\Events::class,
'before' => [
'typo3/cms-frontend/shortcut-and-mountpoint-redirect'
],
'after' => [
'typo3/cms-frontend/prepare-tsfe-rendering'
]
]
]
];
page {
includeCSS {
eventSubmission = EXT:t3org_layout/Resources/Public/Css/event-submission.css
}
includeJSFooter {
eventSubmission = EXT:t3org_layout/Resources/Public/JavaScript/EventSubmission.js
}
}
......@@ -50,6 +50,8 @@ finishers:
mapOnDatabaseColumn: 'teaser'
description:
mapOnDatabaseColumn: 'description'
location:
mapOnDatabaseColumn: 'location'
link:
mapOnDatabaseColumn: 'link'
program:
......@@ -218,6 +220,23 @@ renderables:
label: Description
properties:
elementDescription: 'full description of the event'
-
defaultValue: ''
type: Hidden
identifier: location
label: Location
properties:
elementDescription: ''
-
defaultValue: ''
type: Text
identifier: locationSearch
label: Location
properties:
elementDescription: ''
elementClassAttribute: 'js__eventsubmissionform__location-search_input'
fluidAdditionalAttributes:
data-location-search-target: 'location'
-
defaultValue: ''
type: Url
......
.js__eventsubmissionform__location-search_container {
position: relative;
}
.js__eventsubmissionform__location-search_resultlist {
position: absolute;
width: 100%;
background-color: white;
list-style-type: none;
margin: 0;
padding: 0;
}
.js__eventsubmissionform__location-search_resultlist li {
width: 100%;
padding: 10px 15px;
border-right: 1px solid #ff8700;
border-bottom: 1px solid #ff8700;
border-left: 1px solid #ff8700;
cursor: pointer;
}
document.querySelectorAll('input.js__eventsubmissionform__location-search_input').forEach(function(searchInput) {
let targetElementName = searchInput.getAttribute('data-location-search-target');
let targetElementId = searchInput.id.replace('-locationSearch', '-' + targetElementName);
let targetElement = document.getElementById(targetElementId);
if(typeof targetElement !== 'undefined') {
const _eventSubmissionFormLocationSearch = new XMLHttpRequest();
let resultList = document.createElement('ul');
resultList.setAttribute('id',searchInput.id + '-list');
resultList.setAttribute('class','js__eventsubmissionform__location-search_resultlist');
searchInput.parentNode.classList.add('js__eventsubmissionform__location-search_container');
searchInput.parentNode.insertBefore(resultList, searchInput.nextSibling);
_eventSubmissionFormLocationSearch.onreadystatechange = function (response) {
if (_eventSubmissionFormLocationSearch.readyState === 4) {
if (_eventSubmissionFormLocationSearch.status === 200) {
const jsonOptions = JSON.parse(_eventSubmissionFormLocationSearch.responseText);
jsonOptions.forEach(function (item) {
let option = document.createElement('li');
option.setAttribute('data-id',item.uid);
let content = [
'<strong>' + item.title + '</strong>'
];
if (item.address) {
content.push(item.address);
}
if (item.zip || item.city) {
content.push((item.zip + ' ' + item.city).trim());
}
if (item.country) {
content.push(item.country);
}
option.innerHTML = content.join('<br />');
resultList.appendChild(option);
});
searchInput.placeholder = "enter location";
} else {
searchInput.placeholder = "An error occured while loading locations";
}
}
};
let delay = function(callback, ms) {
let timer = 0;
return function() {
let context = this, args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
callback.apply(context, args);
}, ms || 0);
}
}
searchInput.addEventListener('keyup', delay(function () {
targetElement.value = '';
resultList.innerHTML = '';
let searchPhrase = searchInput.value;
if(searchPhrase.length > 2) {
_eventSubmissionFormLocationSearch.abort();
_eventSubmissionFormLocationSearch.open(
'GET',
'/index.php?eventLocationSearch=' + encodeURIComponent(searchPhrase),
true
);
_eventSubmissionFormLocationSearch.send();
}
}));
}
});
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment