Skip to content

Commit

Permalink
made autocomplete part as "suggest"
Browse files Browse the repository at this point in the history
  • Loading branch information
tyrant88 committed Jul 28, 2024
1 parent f196974 commit 24b01b9
Show file tree
Hide file tree
Showing 17 changed files with 978 additions and 8 deletions.
File renamed without changes.
211 changes: 211 additions & 0 deletions assets/suggest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
document.addEventListener('DOMContentLoaded', function () {
function suggest(input, options) {
var cache = [],
cacheSize = 0,
results = document.createElement('ul'),
timeout = null,
prevLength = 0;

results.className = options.resultsClass;
document.body.appendChild(results);

function getPosition(el) {
var rect = el.getBoundingClientRect();
return {
top: rect.top + window.scrollY,
left: rect.left + window.scrollX
};
}

function updatePosition() {
var pos = getPosition(input);
results.style.top = pos.top + input.offsetHeight + 'px';
results.style.left = pos.left + 'px';
}

function handleKeyup(e) {
if (/27$|38$|40$/.test(e.keyCode) && results.style.display !== 'none' || /^13$|^9$/.test(e.keyCode) && getCurrentResult()) {
e.preventDefault();
e.stopPropagation();
switch (e.keyCode) {
case 38:
selectPrevious();
break;
case 40:
selectNext();
break;
case 9:
case 13:
chooseResult();
break;
case 27:
results.style.display = 'none';
break;
}
} else {
if (input.value.length !== prevLength) {
clearTimeout(timeout);
timeout = setTimeout(fetchSuggestions, options.delay);
prevLength = input.value.length;
}
}
}

function fetchSuggestions() {
var query = input.value.trim();
if (query.length >= options.minchars) {
var cached = getCached(query);
if (cached) {
displayResults(cached.items);
} else {
fetch(options.source + '&q=' + encodeURIComponent(query))
.then(response => response.text())
.then(data => {
var items = parseResults(data, query);
displayResults(items);
addToCache(query, items, data.length);
});
}
} else {
results.style.display = 'none';
}
}

function getCached(query) {
for (var i = 0; i < cache.length; i++) {
if (cache[i].q === query) {
cache.unshift(cache.splice(i, 1)[0]);
return cache[0];
}
}
return false;
}

function addToCache(query, items, size) {
while (cache.length && cacheSize + size > options.maxCacheSize) {
var cached = cache.pop();
cacheSize -= cached.size;
}
cache.push({q: query, size: size, items: items});
cacheSize += size;
}

function displayResults(items) {
if (items.length) {
results.innerHTML = '';
for (var i = 0; i < items.length; i++) {
var li = document.createElement('li');
li.innerHTML = items[i];
li.addEventListener('mouseover', function () {
var children = results.children;
for (var j = 0; j < children.length; j++) {
children[j].classList.remove(options.selectClass);
}
this.classList.add(options.selectClass);
});
li.addEventListener('click', function (e) {
e.preventDefault();
e.stopPropagation();
chooseResult();
});
results.appendChild(li);
}
results.style.display = 'block';
} else {
results.style.display = 'none';
}
}

function parseResults(data, query) {
var items = data.split(options.delimiter).map(item => item.trim()).filter(item => item);
var regex = new RegExp(query, 'ig');
return items.map(item => item.replace(regex, function (match) {
return '<span class="' + options.matchClass + '">' + match + '</span>';
}));
}

function getCurrentResult() {
var selected = results.querySelector('.' + options.selectClass);
return selected || false;
}

function chooseResult() {
var currentResult = getCurrentResult();
if (currentResult) {
input.value = currentResult.textContent;
results.style.display = 'none';
if (options.onSelect) {
options.onSelect.apply(input, [currentResult.textContent]);
}
}
}

function selectNext() {
var currentResult = getCurrentResult();
if (currentResult) {
var next = currentResult.nextElementSibling;
currentResult.classList.remove(options.selectClass);
if (next) {
next.classList.add(options.selectClass);
} else {
results.firstElementChild.classList.add(options.selectClass);
}
} else {
results.firstElementChild.classList.add(options.selectClass);
}
}

function selectPrevious() {
var currentResult = getCurrentResult();
if (currentResult) {
var prev = currentResult.previousElementSibling;
currentResult.classList.remove(options.selectClass);
if (prev) {
prev.classList.add(options.selectClass);
} else {
results.lastElementChild.classList.add(options.selectClass);
}
} else {
results.lastElementChild.classList.add(options.selectClass);
}
}

input.addEventListener('keyup', handleKeyup);
input.addEventListener('blur', function () {
setTimeout(function () {
results.style.display = 'none';
}, 200);
});
window.addEventListener('resize', updatePosition);
window.addEventListener('load', updatePosition);

updatePosition();
}

function initSuggest() {
var searchInput = document.querySelector(".search_it-form input[name=search]");

if (searchInput) {
suggest(searchInput, {
source: 'index.php?rex-api-call=search_it_autocomplete&rnd=' + Math.random(),
delay: 100,
resultsClass: 'ac_results',
selectClass: 'ac_over',
matchClass: 'ac_match',
minchars: 2,
delimiter: '\n',
onSelect: function (value) {
var searchForm = searchInput.closest('.search_it-form');
if (searchForm.classList.contains('search_it-form-autocomplete')) {
searchForm.submit();
return false;
}

},
maxCacheSize: 65536
});
}
}

initSuggest();
});
27 changes: 27 additions & 0 deletions boot.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,33 @@
}
}

// autocomplete
if ($this->getConfig('autoComplete') == 1) {
if (rex::isBackend()) {

rex_view::addCssFile($this->getAssetsUrl('suggest.css'));
rex_view::addJsFile($this->getAssetsUrl('suggest.js'));

if (!$this->hasConfig()) {
$this->setConfig(array(
'modus' => 'keywords',
'maxSuggestion' => 10,
'similarwordsmode' => '0',
'autoSubmitForm' => 1
));
}
} else {
if ($this->getConfig('autoSubmitForm') == 1) {
rex_extension::register('OUTPUT_FILTER', function (rex_extension_point $ep) {
$subject = $ep->getSubject();
return str_replace(['search_it-form', '###AUTOSUBMIT###'],
['search_it-form search_it-form-autocomplete', ''],
$subject);
});
}
}
}

if (rex::isBackend() && rex::getUser()) {
// automatic indexing
if (rex_addon::get('search_it')->getConfig('automaticindex') == true) {
Expand Down
41 changes: 41 additions & 0 deletions docs/30_autocomplete.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Installation Autocomplete

Es stellt ein "Suggest"-PlugIn für die Autovervollständigung bei
der Suche im Frontend zur Verfügung und generiert einen Code welcher im Template
eingebunden werden muss.

## Requirements

* Funktionierendes Suchformular, das die HTML-Klasse "search_it-form",
sowie ein HTML-Eingabefeld für die Suche mit dem Namen "search" beinhaltet.

## Installation

1. Autocomplete und aktivieren
2. Konfiguration im Plugin vornehmen und speichern
3. Den generierten Code für das Template herauskopieren und in das Template,
welches für das Suchfeld verwendet wird, vor dem schließenden `</body>` Tag
hinzufügen
4. Sollte das Suchfeld überall verwendet werden, beispielsweise im Kopf der
Seite, muss der generierte Code in das entsprechende Template hinzugefügt
werden
5. Optional: CSS und JS Datei in den eigenen Frontend_prozess einbauen ( z.B.
per Minify oder im Bimmelbam )

## Lizenz

"Autocomplete" von Manétage steht unter MIT Lizenz.

## Rechtliches

Verwendung auf eigene Gefahr.

## Autor

**Manetage** - Ronny Kemmereit / Pascal Schuchmann
Norbert Micheel

**Friends Of REDAXO**

* http://www.redaxo.org
* https://github.com/FriendsOfREDAXO
23 changes: 23 additions & 0 deletions lang/de_de.lang
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,26 @@ search_it_docs_module-pagination = Paginierung
search_it_docs_module-simsearch = Ähnlichkeitssuche
search_it_docs_module-url = URL-Addon
search_it_docs_faq = FAQ


search_it_autocomplete_title = Autocomplete
search_it_autocomplete_info = Autocomplete für Search it

search_it_autocomplete_config = Konfiguration
search_it_autocomplete_config_saved = Einstellungen gespeichert.
search_it_autocomplete_config_save = Einstellungen speichern

search_it_autocomplete_config_autoComplete = Autovervollständigung aktivieren
search_it_autocomplete_config_modus = Modus der Ausgabe
search_it_autocomplete_config_maxSuggestion = Maximale Trefferanzahl
search_it_autocomplete_config_similarwords_label = Ähnlichkeitssuche
search_it_autocomplete_config_similarwords_none = Deaktivieren
search_it_autocomplete_config_similarwords_soundex = Soundex (Allgemein)
search_it_autocomplete_config_similarwords_metaphone = Metaphone (EN)
search_it_autocomplete_config_similarwords_cologne = Kölner Phonetik (DE)
search_it_autocomplete_config_similarwords_all = Alle

search_it_autocomplete_config_autoSubmitForm = Auto Submit Form

search_it_autocomplete_config_install = Installation
search_it_autocomplete_config_codesnippet = Generierter Code zum Einbinden in Template
22 changes: 22 additions & 0 deletions lang/en_gb.lang
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,25 @@ search_it_docs_module-pagination = Paging
search_it_docs_module-simsearch = similarity search
search_it_docs_module-url = URL-AddOn
search_it_docs_faq = FAQ

search_it_autocomplete_title = Autocomplete
search_it_autocomplete_info = Autocomplete for Search it

search_it_autocomplete_config = Configuration
search_it_autocomplete_config_saved = Settings saved.
search_it_autocomplete_config_save = Save settings

search_it_autocomplete_config_autoComplete = Activate autocomplete
search_it_autocomplete_config_modus = Output mode
search_it_autocomplete_config_maxSuggestion = Maximum number of hits
search_it_autocomplete_config_similarwords_label = Similarity search
search_it_autocomplete_config_similarwords_none = Deactivate
search_it_autocomplete_config_similarwords_soundex = Soundex (General)
search_it_autocomplete_config_similarwords_metaphone = Metaphone (EN)
search_it_autocomplete_config_similarwords_cologne = Cologne Phonetics (DE)
search_it_autocomplete_config_similarwords_all = All

search_it_autocomplete_config_autoSubmitForm = Auto Submit Form

search_it_autocomplete_config_install = Installation
search_it_autocomplete_config_codesnippet = Generated code for insert in template
23 changes: 23 additions & 0 deletions lang/es_es.lang
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,26 @@ search_it_docs_module-pagination = Paging
search_it_docs_module-simsearch = similarity search
search_it_docs_module-url = URL-AddOn
search_it_docs_faq = FAQ


search_it_autocomplete_title = Autocomplete
search_it_autocomplete_info = Autocomplete für Search it

search_it_autocomplete_config = Konfiguration
search_it_autocomplete_config_saved = Einstellungen gespeichert.
search_it_autocomplete_config_save = Einstellungen speichern

search_it_autocomplete_config_autoComplete = Autovervollständigung aktivieren
search_it_autocomplete_config_modus = Modus der Ausgabe
search_it_autocomplete_config_maxSuggestion = Maximale Trefferanzahl
search_it_autocomplete_config_similarwords_label = Ähnlichkeitssuche
search_it_autocomplete_config_similarwords_none = Deaktivieren
search_it_autocomplete_config_similarwords_soundex = Soundex (Allgemein)
search_it_autocomplete_config_similarwords_metaphone = Metaphone (EN)
search_it_autocomplete_config_similarwords_cologne = Kölner Phonetik (DE)
search_it_autocomplete_config_similarwords_all = Alle

search_it_autocomplete_config_autoSubmitForm = Auto Submit Form

search_it_autocomplete_config_install = Installation
search_it_autocomplete_config_codesnippet = Código generado para su inclusión en la plantilla
23 changes: 23 additions & 0 deletions lang/pt_br.lang
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,26 @@ search_it_docs_module-pagination = Paging
search_it_docs_module-simsearch = similarity search
search_it_docs_module-url = URL-AddOn
search_it_docs_faq = FAQ


search_it_autocomplete_title = Autocomplete
search_it_autocomplete_info = Autocomplete para Search it

search_it_autocomplete_config = Configurações
search_it_autocomplete_config_saved = Configurações salvas.
search_it_autocomplete_config_save = Salvar configurações

search_it_autocomplete_config_autoComplete = Autovervollständigung aktivieren
search_it_autocomplete_config_modus = Modo de emissão
search_it_autocomplete_config_maxSuggestion = Número máximo de visitas
search_it_autocomplete_config_similarwords_label = Número máximo de visitas
search_it_autocomplete_config_similarwords_none = Desativar
search_it_autocomplete_config_similarwords_soundex = Soundex (Geral)
search_it_autocomplete_config_similarwords_metaphone = Metaphone (EN)
search_it_autocomplete_config_similarwords_cologne = Fonética de Colônia (DE)
search_it_autocomplete_config_similarwords_all = Tudo

search_it_autocomplete_config_autoSubmitForm = Auto Submit Form

search_it_autocomplete_config_install = Instalação
search_it_autocomplete_config_codesnippet = Código gerado para Template
Loading

0 comments on commit 24b01b9

Please sign in to comment.